ImageVerifierCode 换一换
格式:DOCX , 页数:45 ,大小:35.33KB ,
资源ID:10459332      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/10459332.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(游戏开发基础7.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

游戏开发基础7.docx

1、游戏开发基础7游戏开发基础(7)第七章 游戏编程的特点第一节 概述:电脑游戏在计算机发展使用中可以说扮演了一个极为有趣的角色,一方面不为很多人所赞同,认为是一种浪费;而另一方面电脑游戏却是推动计算机的各项技术迅速发展的最有力的力量之一。这一点,可以从3d类游戏对硬件无止境的需求,游戏迷对游戏图像的质量、游戏的交互性、人机界面的友好性等方面的需求体现出来(当然游戏迷对游戏的的构思、创意的要求也是苛刻且无止境的,但这一点只有靠您自己的想象力,我们是爱莫能助了)。从游戏近期的发展中,我们从3d游戏的发展,可以看到从Doom到现在的古墓丽影2、雷神之锤2,3d游戏的画面从生硬单调的多边形到今天柔和复杂

2、几进乱真的场景、道具、怪物,敌人从只会疯狂向你冲来到今天会偷袭、会审时度势地采取合适的方式方法向你进攻;游戏无论从硬件支持还是编程技术方面都有突飞猛进的进展。在游戏发展的过程中,很多技术也随之发展起来了,例如各种图形加速卡的出现和发展,directx的出现,和各个成功游戏中采用的各种优化技术都推动了计算机技术的发展。游戏可以说是集合了每个时期计算机行业中最先进的硬件技术和最新的编程思想,比如近期的游戏都是采用了面向对象的编程思想的基于Windows的软件,大部分图象要求高的游戏都要求或支持图形加速卡。同时游戏编程中也有自己基本的方式方法、结构和理论,在这一章的学习中我们将讨论这些问题。在这一章

3、中我们将讨论下面几个问题:程序入口 即是游戏获取外部操作的讯息,得到下次刷新所需的新参数的手段。如同一般的SDK Windows应用程序一样,程序的入口为WINMAIN()。游戏初始化 包括创建标准的WINDOWS程序所需的初始化程序以及游戏内部的初始化程序,例如游戏系统初始化、游戏图形的装入、游戏声音的装入等。游戏内部循环: 游戏的循环入口是WINDOWS消息循环内部的一个函数调用,游戏内部循环包括刷新游戏单位、画游戏单位两部分。刷新游戏单位: 用于每一帧刷新游戏单位的状态,例如改变游戏单位的状态、改变游戏单位的位置、获取外部信息等。画游戏单位: 用于每一帧往屏幕上画游戏单位的图象,并进行特

4、殊处理以提高速度。计算机人工智能: 主要用于受计算机处理的游戏单位的行为控制算法,程序部分位于刷新计算机游戏单位部分中。游戏内存管理: 这一部分对于优质高效的游戏软件是十分重要的,内存管理不当会导致游戏性能的降低,甚至引起死机。游戏交互设计: 交互设计是游戏可玩性的关键,友好的交互界面和交互方式可以使游戏增色不少。游戏图象底层设计: 游戏软件的主要处理时间花在处理图象和画图象上,所以游戏图象底层的设计对于游戏的最终效果是十分重要的。游戏多媒体设计: 主要包括图形界面设计、游戏音乐音效设计、游戏动画设计、游戏影象设计的几个方面,更广泛的说还包括游戏所有运行过程的功能设计。第二节 程序入口这个标题

5、看起来似乎很难理解,它的意思就是当游戏被启动时,计算机从什么地方开始运行程序的。在Windows的应用程序上,Winmain()函数一般就是程序入口。游戏开始后,就调用Winmain()函数,然后再按语句的顺序或所接受到的消息调用相应的函数。从第三章Windows编程基础中我们了解到Winmain()函数的的结构、运行过程,现在我们就游戏编程的角度来讨论Winmain()函数的编制。int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nCmdShow )MSG msg;whi

6、le( lpCmdLine0 = - | lpCmdLine0 = /)lpCmdLine+;switch (*lpCmdLine+)case e:bUseEmulation = TRUE;break;case w:bFullscreen = FALSE;break;case f:bFullscreen = TRUE;break;case 1:CmdLineBufferCount = 1;break;case 2:case d:CmdLineBufferCount = 2;break;case 3:CmdLineBufferCount = 3;break;case s:bStretch = T

7、RUE;break;case S:bWantSound = FALSE;break;case x:bStress= TRUE;break;case ?:bHelp= TRUE;bFullscreen= FALSE; / give help in windowed modebreak;while( IS_SPACE(*lpCmdLine) )lpCmdLine+;GameMode.cx = getint(&lpCmdLine, 640);GameMode.cy = getint(&lpCmdLine, 480);GameBPP = getint(&lpCmdLine, 8);/* create

8、window and other windows things*/if( !initApplication(hInstance, nCmdShow) )return FALSE;/* Give user help if asked for* This is ugly for now because the whole screen is black* except for the popup box. This could be fixed with some* work to get the window size right when it was created instead* of

9、delaying that work. see ddraw.c*/if( bHelp )MessageBox(hWndMain,F12 - QuitnNUMPAD 2 - crouchnNUMPAD 3 - applenNUMPAD 4 - rightnNUMPAD 5 - stopnNUMPAD 6 - leftnNUMPAD 7 - jumpnnCommand line parametersnn-e Use emulatorn-S No Soundn-1 No backbuffern-2 One backbuffern-4 Three backbuffersn-s Use stretchn

10、-x Demo or stress moden,OUR_APP_NAME, MB_OK );/* initialize for game play*/if( !InitGame() )return FALSE;dwFrameTime = timeGetTime();while( 1 )if (PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE)if (!GetMessage( &msg, NULL, 0, 0)break;TranslateMessage(&msg);DispatchMessage(&msg);else if (!bPaused & (bIsA

11、ctive | !bFullscreen)ProcessFox(lastInput);lastInput=0;elseWaitMessage();if (AveFrameRateCount)AveFrameRate = AveFrameRate / AveFrameRateCount;Msg(Average frame rate: %d, AveFrameRate);return msg.wParam; /* WinMain */我们知道在消息循环之中只有一个消息-WM_QUIT可以结束这个循环,退出WINDOWS。所以我们要在消息循环之前完成所有的工作即所有的初始化。关于初始化这个概念在下一

12、节我们将详细讨论。在我们提供的例程(在光盘的sample目录中)中的foxbear.c里的WMain()中我们可以看到在消息循环之前先运行DDint()函数对DirectDraw进行初始化,检测命令行参数并对相关的参数进行赋值和确定显示模式,进行窗口的初始化,检测bhelp的值以确定是否显示帮助对话框,进行游戏的初始化。在一个游戏的消息循环中除了包含一般Windows应用程序的消息循环所应包含的部分外还应有调用有关检测游戏单位状态位置、刷新游戏单位和重画新图以及有关人工智能的函数的部分。在例程中的消息循环部分包含了一个关于检测游戏单位状态位置、刷新游戏单位和重画新图函数的调用。在这些调用中一般

13、有两种方法:1.在消息循环中直接调用有关函数。比如说在一个RPG的游戏中每个循环都检测主角的的位置是否发生改变,若改变了则在新位置上重画主角的图。2.通过检测WM_TIMER消息,以决定是否调用有关函数。即是每隔一段时间(若干个时钟周期),检测一次,然后决定函数的调用与否。在上面的两种方法里,第一种是现在较常用的,它的缺点是CPU资源占用相对较多,但对不同的机型适应性较强,较稳定。第二种在一些较老的游戏或对速度要求不高的游戏中较常见,与第一种相比它的CPU资源占用相对较少,但在不同的机型中表现差异极大。在谈WinMain()的编制时,窗口函数(WINPROC)的编制是必须说的。窗口函数可以说是

14、把功能不同的函数通过Switch-Case结构连起来组成一个复杂程序的线索。它的基本编写方法在Windows编程基础中我们就已经谈到了。仔细阅读例程中的MainWndProc()函数相信对您是有相当大的帮助的。/* MainWndProc* Callback for all Windows messages*/long FAR PASCAL MainWndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )PAINTSTRUCT ps;HDC hdc;switch( message )case WM_SIZE:case WM

15、_MOVE:if (IsIconic(hWnd)Msg(FoxBear is minimized, pausing);PauseGame();if (bFullscreen)SetRect(&rcWindow, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN);elseGetClientRect(hWnd, &rcWindow);ClientToScreen(hWnd, (LPPOINT)&rcWindow);ClientToScreen(hWnd, (LPPOINT)&rcWindow+1);Msg(WIND

16、OW RECT: %d,%d,%d,%d, rcWindow.left, rcWindow.top, rcWindow.right, rcWindow.bottom);break;case WM_ACTIVATEAPP:bIsActive = (BOOL)wParam & GetForegroundWindow() = hWnd;if (bIsActive)Msg(FoxBear is active);elseMsg(FoxBear is not active);/ while we were not-active something bad happened that caused us/

17、to pause, like a surface restore failing or we got a palette/ changed, now that we are active try to fix things/if (bPaused & bIsActive)if (RestoreGame()UnPauseGame();elseif (GetForegroundWindow() = hWnd)/ we are unable to restore, this can happen when/ the screen resolution or bitdepth has changed/

18、 we just reload all the art again and re-create/ the front and back buffers. this is a little/ overkill we could handle a screen res change by/ just recreating the front and back buffers we dont/ need to redo the art, but this is way easier./if (InitGame()UnPauseGame();break;case WM_QUERYNEWPALETTE:

19、/ we are getting the palette focus, select our palette/if (!bFullscreen & lpPalette & lpFrontBuffer)HRESULT ddrval;ddrval = IDirectDrawSurface_SetPalette(lpFrontBuffer,lpPalette);if( ddrval = DDERR_SURFACELOST )IDirectDrawSurface_Restore( lpFrontBuffer );ddrval= IDirectDrawSurface_SetPalette(lpFront

20、Buffer,lpPalette);if( ddrval = DDERR_SURFACELOST )Msg( Failed to restore palette after second try);/ Restore normal title if palette is ours/if( ddrval = DD_OK )SetWindowText( hWnd, OUR_APP_NAME );break;case WM_PALETTECHANGED:/ if another app changed the palette we dont have full control/ of the pal

21、ette. NOTE this only applies for FoxBear in a window/ when we are fullscreen we get all the palette all of the time./if (HWND)wParam != hWnd)if( !bFullscreen )if( !bStress )Msg(* PALETTE CHANGED, PAUSING GAME);PauseGame();elseMsg(Lost palette but continuing);SetWindowText( hWnd, OUR_APP_NAME - palet

22、te changed COLORS PROBABLY WRONG );break;case WM_DISPLAYCHANGE:break;case WM_CREATE:break;case WM_SETCURSOR:if (bFullscreen & bIsActive)SetCursor(NULL);return TRUE;break;case WM_SYSKEYUP:switch( wParam )/ handle ALT+ENTER (fullscreen)case VK_RETURN:bFullscreen = !bFullscreen;ExitGame();DDDisable(TRU

23、E); / destroy DirectDraw objectGameMode.cx = 320;GameMode.cy = 200;InitGame();break;break;case WM_KEYDOWN:switch( wParam )case VK_NUMPAD5:lastInput=KEY_STOP;break;case VK_DOWN:case VK_NUMPAD2:lastInput=KEY_DOWN;break;case VK_LEFT:case VK_NUMPAD4:lastInput=KEY_LEFT;break;case VK_RIGHT:case VK_NUMPAD6

24、:lastInput=KEY_RIGHT;break;case VK_UP:case VK_NUMPAD8:lastInput=KEY_UP;break;case VK_HOME:case VK_NUMPAD7:lastInput=KEY_JUMP;break;case VK_NUMPAD3:lastInput=KEY_THROW;break;case VK_F5:bShowFrameCount = !bShowFrameCount;if( bShowFrameCount )dwFrameCount = 0;dwFrameTime = timeGetTime();break;case VK_F

25、6:static i;/ find our current mode in the mode list/if(bFullscreen)for (i=0; iNumModes; i+)if (ModeListi.bpp = (int)GameBPP &ModeListi.w = GameSize.cx &ModeListi.h = GameSize.cy)break;elsefor (i=0; i= NumModes)i = 0;Msg(ModeList %d %d,i,NumModes);GameMode.cx = ModeListi.w;GameMode.cy = ModeListi.h;G

26、ameBPP = ModeListi.bpp;bStretch = FALSE;InitGame();break;case VK_F7:GameBPP = GameBPP = 8 ? 16 : 8;InitGame();break;case VK_F8:if (bFullscreen)bStretch = !bStretch;InitGame();elseRECT rc;GetClientRect(hWnd, &rc);bStretch = (rc.right != GameSize.cx) |(rc.bottom != GameSize.cy);if (bStretch = !bStretc

27、h)SetRect(&rc, 0, 0, GameMode.cx*2, GameMode.cy*2);elseSetRect(&rc, 0, 0, GameMode.cx, GameMode.cy);AdjustWindowRectEx(&rc,GetWindowStyle(hWnd),GetMenu(hWnd) != NULL,GetWindowExStyle(hWnd);SetWindowPos(hWnd, NULL, 0, 0, rc.right-rc.left, rc.bottom-rc.top,SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);b

28、reak;case VK_F9: DevIndex +;bUseEmulation = FALSE;if (DevIndex = MaxDevIndex)DevIndex = 0;ExitGame();DDDisable(TRUE); / destroy DirectDraw objectInitGame();break;case VK_F4:/ treat F4 like ALT+ENTER (fullscreen)PostMessage(hWnd, WM_SYSKEYUP, VK_RETURN, 0);break;case VK_F3:bPaused = !bPaused;break;case VK_ESCAPE:case VK_F12:PostMessage(hWnd, WM_CLOSE, 0, 0);return 0;break;case WM_PAINT:hdc = BeginPaint( hWnd, &ps );if (bPaused)char *sz = Game is pau

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1