VC++ 游戏编程背景动画设计.docx
《VC++ 游戏编程背景动画设计.docx》由会员分享,可在线阅读,更多相关《VC++ 游戏编程背景动画设计.docx(10页珍藏版)》请在冰豆网上搜索。
VC++游戏编程背景动画设计
前面的内容介绍了前景动画的设计,接下来是背景动画的设计,背景动画的设计同样是利用连续贴图的原理。
一、单一背景滚动
(一):
单一背景滚动就是利用一张相当大的背景图,当游戏进行的时候,随着动画中人物或鼠标的移动,背景显示区域跟着移动。
例如地图显示。
如上面这张图,由左上方到右下方,三个方框。
代表显示在窗口中的背景区域,程序只要按照从左上到右下的顺序就可以连续显示3个方框区域,达到背景滚动的效果。
其实这原理简单,这里就直接给出程序代码来看。
范例:
以键盘方向键(↑→↓←)控制背景滚动显示:
VS2008中新建Win32应用程序,命名后,选择默认的选项,点击完成。
定义全局变量:
1.HBITMAP map;
2.HDC hmdc, mdc;
3.HWND hWnd;
4.DWORD tPre, tNow;
5.int x = 0, y = 0;
HBITMAPmap;
HDChmdc,mdc;
HWNDhWnd;
DWORDtPre,tNow;
intx=0,y=0;
这里声明x,y来表示获取DC的屏幕原点:
BitBlt(hdc,0,0,640,480,mdc,x,y,SRCCOPY);
消息处理函数WndProc()函数中
1.case WM_KEYDOWN:
// 响应各个方向键的操作
2. switch(wParam)
3. {
4. case VK_UP:
5. y -= 20;
6. if (y < 0)
7. y = 0;
8. break;
9. case VK_DOWN:
10. y += 20;
11. if (y > 660)
12. y = 660;
13. break;
14. case VK_LEFT:
15. x -= 20;
16. if (x < 0)
17. x = 0;
18. break;
19. case VK_RIGHT:
20. x += 20;
21. if (x > 910)
22. x = 910;
23. break;
24. }
25. break;
caseWM_KEYDOWN:
//响应各个方向键的操作
switch(wParam)
{
caseVK_UP:
y-=20;
if(y<0)
y=0;
break;
caseVK_DOWN:
y+=20;
if(y>660)
y=660;
break;
caseVK_LEFT:
x-=20;
if(x<0)
x=0;
break;
caseVK_RIGHT:
x+=20;
if(x>910)
x=910;
break;
}
break;
运行后通过操作方向键可以控制查看地图的位置
(二)、循环背景动画
循环背景动画师不断的进行背景图的裁切与接合,然后显示在窗口上所产生的一种背景画面的循环滚动效果。
下面来介绍这种动画效果的制作。
如上图,在背景图向右移动时,屏幕会出现“缝隙”,所以我们就是要把移出屏幕的图贴到缝隙中来。
这样子循环后,就可以看到在空中飞行的效果了。
由上面的分析,我们的工作就是两次贴图。
第一步,裁取原始背景图右边部分进行贴图操作到另一个DC中,假设目前裁取的右边部分的宽度为x,如图:
第二步,采取原始背景图左边部分进行贴图操作到上一个DC中,完成了向右滚动接合后的新背景图。
第三步,将接合后的背景图显示在窗口中,之后递增x值,进行循环操作。
当x大于等于背景图后,就将x的值重设为0,继续重复循环。
这样子就形成了背景循环效果。
利用一张640*480的背景图,制作由左向右的循环滚动的动画
程序代码:
全局变量:
1.HBITMAP bg;
2.HDC hmdc, mdc, buffdc;
3.HWND hWnd;
4.DWORD tPre, tNow;
5.int x = 0, y=0;
HBITMAPbg;
HDChmdc,mdc,buffdc;
HWNDhWnd;
DWORDtPre,tNow;
intx=0;
第五行,用xy来记录被裁取的左上角点的坐标,初始值为(0,0),表示第一次显示时是在最左上角。
1.BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
2.{
3.// HWND hWnd;
4. HBITMAP bmp; //用于建立兼容位图
5.
6. hInst = hInstance; // 将实例句柄存储在全局变量中
7.
8. hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
9. CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
10.
11. if (!
hWnd)
12. {
13. return FALSE;
14. }
15.
16. MoveWindow(hWnd, 10, 10, 640, 480, true);
17. ShowWindow(hWnd, nCmdShow);
18. UpdateWindow(hWnd);
19.
20. hmdc = GetDC(hWnd);
21. mdc = CreateCompatibleDC(hmdc);
22. buffdc = CreateCompatibleDC(hmdc);
23.
24. //建立和窗口兼容的位图
25. bmp = CreateCompatibleBitmap(hmdc, 640, 480);
26. SelectObject(mdc, bmp);
27.
28. bg = (HBITMAP)LoadImage(NULL, L"bg.bmp", IMAGE_BITMAP, 640, 480, LR_LOADFROMFILE);
29. SelectObject(buffdc, bg);
30.
31. MyPaint(hmdc);
32.
33. return TRUE;
34.}
BOOLInitInstance(HINSTANCEhInstance,intnCmdShow)
{
//HWNDhWnd;
HBITMAPbmp;//用于建立兼容位图
hInst=hInstance;//将实例句柄存储在全局变量中
hWnd=CreateWindow(szWindowClass,szTitle,WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,0,CW_USEDEFAULT,0,NULL,NULL,hInstance,NULL);
if(!
hWnd)
{
returnFALSE;
}
MoveWindow(hWnd,10,10,640,480,true);
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
hmdc=GetDC(hWnd);
mdc=CreateCompatibleDC(hmdc);
buffdc=CreateCompatibleDC(hmdc);
//建立和窗口兼容的位图
bmp=CreateCompatibleBitmap(hmdc,640,480);
SelectObject(mdc,bmp);
bg=(HBITMAP)LoadImage(NULL,L"bg.bmp",IMAGE_BITMAP,640,480,LR_LOADFROMFILE);
SelectObject(buffdc,bg);
MyPaint(hmdc);
returnTRUE;
}
1.void MyPaint(HDC hdc)
2.{
3. // 截取背景图右边的部分
4. BitBlt(mdc, 0, 0, x, 480, buffdc, 640-x, 0, SRCCOPY);
5. // 截取背景图左边部分进行贴图
6. BitBlt(mdc, x, 0, 640-x, 480, buffdc, 0, 0, SRCCOPY);
7. // 将结合后的背景图贴到窗口
8. BitBlt(hdc, 0, 0, 640, 480, mdc, 0, 0, SRCCOPY);
9.
10. tPre = GetTickCount(); // 获得持续时间
11. x += 10;
12. if (x == 640)
13. {
14. x = 0;
15. }
16.}
voidMyPaint(HDChdc)
{
//截取背景图右边的部分
BitBlt(mdc,0,0,x,480,buffdc,640-x,0,SRCCOPY);
//截取背景图左边部分进行贴图
BitBlt(mdc,x,0,640-x,480,buffdc,0,0,SRCCOPY);
//将结合后的背景图贴到窗口
BitBlt(hdc,0,0,640,480,mdc,0,0,SRCCOPY);
tPre=GetTickCount();//获得持续时间
x+=10;
if(x==640)
{
x=0;
}
}
每次调用MyPaint()函数都会进行图形切割合并,并显示在窗口上。
运行结果:
会看到图像在向右循环滚动,感觉就是自己在空中快速飞行一样。
二.多背景卷动
多背静循环动画的背景循环原理其实与上面说过的单背景循环的原理相同。
不过由于不同的背景在远近层次上及实际视觉移动速度上不相同,因此在以贴图的