Visual C++游戏编程基础之景物贴图

一、基本思路

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;
}

  三、效果  

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值