這是我用一週打了更多或更少的這種相同的任務的功能。就我而言,我想返回一個可以與FillRect一起使用的HBRUSH。在這種情況下,我們仍然需要創建一個感興趣區域的位圖,然後再從中創建一個畫筆。
在你的情況下,只需要返回dstBmp
。 spriteSheet
是一個已加載256x256 spritesheet的全局。我已經將精靈的大小硬編碼爲16x16,您需要將其改爲81x117。
下面是一些代碼,用於抓取所需區域的副本,還有一些使用這些「郵票」繪製水平圖。這就是說 - 這種方法存在各種各樣的問題。速度是一個,過度的工作是另一個影響第一個的工作。最後,滾動一個這樣畫的窗口會產生人工製品。
// grabs a 16x16px section from the spriteSheet HBITMAP
HBRUSH getSpriteBrush(int col, int row)
{
HDC memDC, dstDC, curDC;
HBITMAP oldMemBmp, oldDstBmp, dstBmp;
curDC = GetDC(HWND_DESKTOP);
memDC = CreateCompatibleDC(NULL);
dstDC = CreateCompatibleDC(NULL);
dstBmp = CreateCompatibleBitmap(curDC, 16, 16);
int xOfs, yOfs;
xOfs = 16 * col;
yOfs = 16 * row;
oldMemBmp = (HBITMAP)SelectObject(memDC, spriteSheet);
oldDstBmp = (HBITMAP)SelectObject(dstDC, dstBmp);
BitBlt(dstDC,0,0,16,16, memDC, xOfs,yOfs, SRCCOPY);
SelectObject(memDC, oldMemBmp);
SelectObject(dstDC, oldDstBmp);
ReleaseDC(HWND_DESKTOP, curDC);
DeleteDC(memDC);
DeleteDC(dstDC);
HBRUSH result;
result = CreatePatternBrush(dstBmp);
DeleteObject(dstBmp);
return result;
}
void drawCompoundSprite(int x, int y, HDC paintDC, char *tileIndexes, int numCols, int numRows)
{
int mapCol, mapRow;
HBRUSH curSprite;
RECT curDstRect;
for (mapRow=0; mapRow<numRows; mapRow++)
{
for (mapCol=0; mapCol<numCols; mapCol++)
{
int curSpriteIndex = tileIndexes[mapRow*numCols + mapCol];
int spriteX, spriteY;
spriteX = curSpriteIndex % 16;
spriteY = curSpriteIndex/16;
curDstRect.left = x + 16*mapCol;
curDstRect.top = y + 16 * mapRow;
curDstRect.right = curDstRect.left + 16;
curDstRect.bottom = curDstRect.top + 16;
curSprite = getSpriteBrush(spriteX, spriteY);
FillRect(paintDC, &curDstRect, curSprite);
DeleteObject(curSprite);
}
}
}
後者的功能已經被替換爲以下內容:
void drawCompoundSpriteFast(int x, int y, HDC paintDC, unsigned char *tileIndexes, int numCols, int numRows, pMapInternalData mData)
{
int mapCol, mapRow;
HBRUSH curSprite;
RECT curDstRect;
HDC memDC;
HBITMAP oldBmp;
memDC = CreateCompatibleDC(NULL);
oldBmp = (HBITMAP)SelectObject(memDC, mData->spriteSheet);
for (mapRow=0; mapRow<numRows; mapRow++)
{
for (mapCol=0; mapCol<numCols; mapCol++)
{
int curSpriteIndex = tileIndexes[mapRow*numCols + mapCol];
int spriteX, spriteY;
spriteX = curSpriteIndex % mData->tileWidth;
spriteY = curSpriteIndex/mData->tileHeight
// Draw sprite as-is
// BitBlt(paintDC, x+16*mapCol, y+16*mapRow,
// mData->tileWidth, mData->tileHeight,
// memDC,
// spriteX * 16, spriteY*16,
// SRCCOPY);
// Draw sprite with magenta rgb(255,0,255) areas treated as transparent (empty)
TransparentBlt(
paintDC,
x+mData->tileWidth*mapCol, y+mData->tileHeight*mapRow,
mData->tileWidth, mData->tileHeight,
memDC,
spriteX * mData->tileWidth, spriteY*mData->tileHeight,
mData->tileWidth, mData->tileHeight,
RGB(255,0,255)
);
}
}
SelectObject(memDC, oldBmp);
DeleteObject(memDC);
}
是否使用gdiplus?如果是這樣,「Bitmap :: Clone」可能就是你想要的。 – 2014-10-31 23:30:32
不只是Win32 =(沒有額外的圖形庫 – 2014-10-31 23:40:38
用'CreateCompatibleBitmap'或'CreateDIBitmap'或類似的方法創建一個新的位圖,選擇它到一個DC中,並用'BitBlt'從源文件中選取適當的部分。 – 2014-11-01 01:53:26