一、基本思路
1.首实现斜角贴图,需要显示菱形图块,使用矩形图块贴图,但是要将它的周围进行透明处理,只显示菱形部分
2.计算图块索引值的公式:
列编号 = 索引值 / 每一列的图块个数;
行编号 = 索引值 % 每一列的图块个数;
3.计算每一图块的贴图坐标公式,设矩形(菱形)长w,宽h,(xstart,ystart)为起始坐标
左上点x坐标 = xstart + 行编号 * (w/2) - 列编号 * (w/2)
左上点y坐标 = ystart + 列编号 * (h/2) - 列编号 * (h/2)
4.每贴好一块斜角地图,接着判断该地图是否需要贴景物?是的话,贴哪种景物?这要由sceneIndex[10*10]来决定,原理同取 图块一样,根据取出的值判断在该斜角地图贴什么景物或者不进行贴图,至于贴图坐标,斜角地图左上角坐标为参考,向右下 方挪个差不多就行了;
二、代码实现
#include "stdafx.h"
#include <stdio.h>
HINSTANCE hInst;
HBITMAP fullmap;
HDC mdc;
const int rows = 10,cols = 10;
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void MyPaint(HDC hdc);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
MyRegisterClass(hInstance);
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "canvas";
wcex.hIconSm = NULL;
return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
HDC hdc,bufdc;
hInst = hInstance;
hWnd = CreateWindow("canvas", "绘图窗口" , WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
MoveWindow(hWnd,10,10,640,400,true);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
int mapIndex[rows*cols] = { 2,2,2,2,2,0,1,0,1,0, //材1
3,3,2,2,0,0,0,1,1,0, //材2
3,0,0,0,0,0,0,0,1,2, //材3
2,2,0,0,0,0,0,2,2,2, //材4
2,2,0,0,0,0,2,2,2,2, //材5
2,2,0,0,0,2,2,0,0,2, //材6
2,0,0,2,2,2,0,0,1,0, //材7
0,0,2,0,0,0,1,1,1,1, //材8
0,2,0,3,3,3,3,3,3,1, //材9
2,0,3,3,3,3,3,3,3,3 };//材10
int sceneIndex[rows*cols] = { 0,2,2,0,2,0,1,0,1,1, //材1
0,0,0,0,0,0,0,1,1,0, //材2
0,0,0,0,0,0,1,0,1,0, //材3
0,0,1,0,1,0,0,0,2,0, //材4
2,2,0,0,1,0,0,0,0,2, //材5
0,0,0,0,0,0,0,0,0,0, //材6
0,0,1,0,0,0,0,0,1,0, //材7
0,0,0,0,0,0,1,1,1,1, //材8
1,0,0,0,0,0,0,0,0,1, //材9
2,0,0,0,0,0,0,0,0,0 };//材10
hdc = GetDC(hWnd);
mdc = CreateCompatibleDC(hdc);
bufdc = CreateCompatibleDC(hdc);
HBITMAP map[4],scene[2];//4种图块类型,2种景物类型
char filename[20] = "";
int rowNum,colNum;
int i,x,y;
int xstart,ystart;
xstart = 32 * (rows-1);
ystart = 0;
fullmap = (HBITMAP)LoadImage(NULL,"bg.bmp",IMAGE_BITMAP,640,480,LR_LOADFROMFILE);
SelectObject(mdc,fullmap);
for(i=0;i<4;i++)
{
sprintf(filename,"map%d.bmp",i);
map[i] = (HBITMAP)LoadImage(NULL,filename,IMAGE_BITMAP,128,32,LR_LOADFROMFILE);
}
for(i=0;i<2;i++)
{
sprintf(filename,"scene%d.bmp",i+1);//1和2两种景物
scene[i] = (HBITMAP)LoadImage(NULL,filename,IMAGE_BITMAP,100,60,LR_LOADFROMFILE);
}
for (i=0;i<rows*cols;i++)
{
SelectObject(bufdc,map[mapIndex[i]]);//根据map数组,取出相应的图块到bufdc
rowNum = i / cols;
colNum = i % cols;
x = xstart + colNum * 32 + rowNum * (-32);
y = ystart + rowNum * 16 + colNum * 16;
BitBlt(mdc,x,y,64,32,bufdc,64,0,SRCAND);
BitBlt(mdc,x,y,64,32,bufdc,0,0,SRCPAINT);
switch(sceneIndex[i]) //根据景物数组,取出相应的景物,1或2就进行贴图.0不做操作
{
case 1:
SelectObject(bufdc,scene[0]);
BitBlt(mdc,x+7,y-44,50,60,bufdc,50,0,SRCAND);//(x+7,y-44)是先画图,然后在计算坐标!
BitBlt(mdc,x+7,y-44,50,60,bufdc,0,0,SRCPAINT);
break;
case 2:
SelectObject(bufdc,scene[1]);
BitBlt(mdc,x+7,y-30,50,60,bufdc,50,0,SRCAND);
BitBlt(mdc,x+7,y-30,50,60,bufdc,0,0,SRCPAINT);
break;
}
}
MyPaint(hdc);
ReleaseDC(hWnd,hdc);
DeleteDC(bufdc);
return TRUE;
}
void MyPaint(HDC hdc)
{
SelectObject(mdc,fullmap);
BitBlt(hdc,0,0,640,480,mdc,0,0,SRCCOPY);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
MyPaint(hdc);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
DeleteDC(mdc);
DeleteObject(fullmap);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}