实验1 游戏程序设计基础.pdf
实验实验 1 1 游戏程序设计基础游戏程序设计基础 1、实验学时与难度实验学时与难度 实验估计时间:4 学时,难度系数:2。2、背景知识简介背景知识简介 1、游戏的组成要素。2、windows 消息机制 3、实验目的和要求实验目的和要求 1、实现 win32 程序的基本框架,并编写一个“漫天雪花”程序,如下图所示:4、实验环境实验环境 PC 机+Visual Studio2005 5、实验内容与步骤实验内容与步骤 步骤 1:打开 Visual studio 开发工具,如下图所示。选择菜单“文件”下的“新建”-“项目”。www.PDFCwww.PDFCwww.PDFC 注意:项目类型选择“win32”,模板选择“win32 项目”。给项目取一个名称,并指定项目所在的位置。然后点击“确定“按钮。此时会进入项目应用程序向导,如下图所示:www.PDFCwww.PDFCwww.PDFC选择下一步,在弹出的对话框中选择“应用程序类型“为”windows 应用程序“,附加选项为”空项目“。然后单击“完成”按钮。此时就进入了项目编辑窗口,如下图所示:第二步:编写 win32 应用程序框架代码 由于是空项目,所以首先需要添加一个.cpp 源文件到项目中来,鼠标右键单击“源文件“,选择”添加“-”新建项“。在弹出的对话框中,选择类别为“代码“,模板为”C+文件(.cpp)“,并给该文件取个名字为”snow“。单击”添加“按钮。www.PDFCwww.PDFCwww.PDFC此时就进入了 snow.cpp 的编辑窗口下。可以开始编写代码了。由于是 win32 应用程序,它的入口主函数是 WinMain,同时还需要编写一个做消息处理的回调函数。因此可以编写如下两个函数。#define WIN32_LEAN_AND_MEAN#include#include const int SCREEN_WIDTH=800;/窗口大小 const int SCREEN_HEIGHT=600;HWND g_hWnd;/保存全局窗口句柄 HINSTANCE g_hInstance;/保存全局实例句柄 /回调函数,完成对消息的处理,由操作系统直接调用 LRESULT CALLBACK WinProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)/根据不同的消息类型进行相应的处理 switch(uMsg)case WM_DESTROY:/窗口销毁时触发的消息 PostQuitMessage(0);break;default:break;/未被上述代码处理的消息都交由这里处理。return DefWindowProc(hwnd,uMsg,wParam,lParam);/*windows 主函数(程序运行的入口,从这里进入执行,离开该函数表示程序的结束)*/int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)/定义一个窗口类的对象(参考 MSDN)WNDCLASSEX winclass;winclass.cbSize=sizeof(WNDCLASSEX);winclass.style=CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW|CS_OWNDC;winclass.lpfnWndProc=WinProc;winclass.cbClsExtra=0;winclass.cbWndExtra=0;winclass.hInstance=hInstance;winclass.hIcon=LoadIcon(hInstance,IDI_APPLICATION);winclass.hCursor=LoadCursor(hInstance,IDC_ARROW);winclass.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);winclass.lpszMenuName=NULL;winclass.lpszClassName=MyGameWndClass;winclass.hIconSm=LoadIcon(hInstance,IDI_APPLICATION);/注册窗口类 www.PDFCwww.PDFCwww.PDFC if(!RegisterClassEx(&winclass)return 0;/将实例句柄用一个全局变量保存,方便在其他函数中使用 g_hInstance=hInstance;/根据上面定义的窗口类创建一个特定的窗口对象 HWND hwnd=CreateWindowEx(NULL,MyGameWndClass,aaa,WS_OVERLAPPEDWINDOW|WS_VISIBLE,/WS_POPUP|WS_VISIBLE,0,0,SCREEN_WIDTH,SCREEN_HEIGHT,NULL,NULL,hInstance,NULL );/将窗口句柄用一个全局变量保存,方便在其他函数中使用 g_hWnd=hwnd;ShowWindow(hwnd,SW_SHOW);/显示窗口 UpdateWindow(hwnd);/重新绘制一遍窗口 /启动消息循环,注意这里使用一种非阻塞的获取消息的方式 MSG msg;while(1)if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)if(msg.message=WM_QUIT)break;TranslateMessage(&msg);DispatchMessage(&msg);return 1;至此,一个 Win32 应用程序的基本框架搭建完成,以后做其他的程序可以重用这个框架。步骤 3:添加游戏素材资源 因为游戏中需要用到一副雪花图标资源,该资源的文件名为“snow.ico“,所以接下来把该图标资源加载到项目中来。首先,把“snow.ico“文件拷贝到项目工程目录下的”res“文件夹中,如果没有该文件夹,自己应该知道怎样创建吧。www.PDFCwww.PDFCwww.PDFC 鼠标右键点击“资源文件“,在弹出的菜单中选择”资源“,弹出如上对话框,然后选择”Icon“资源类型,这里选择”导入“按钮,而不是”新建“按钮。把刚刚拷贝过来的”snow.ico“导入进来。此时你会发现项目中多了两个文件,一个叫 snow.rc,称为资源脚本文件。另外一个叫 resource.h,记录了一些资源的 ID,比如我们加载的这个雪花图标的 ID是”IDI_ICON1”。由于程序中即将用到这些资源 ID,所以添加如下代码:#include“resource.h”步骤 4:添加游戏逻辑代码 首先创建 3 个游戏框架函数,分别是 void GameStart();/游戏的初始化,完成各种资源的加载,以及各种游戏数据的初始化 void GameRun();/游戏循环,每隔30ms调用一次,包含游戏的逻辑和游戏界面的绘制 void GameEnd();/游戏的清除工作,与 GameStart()相对,要做个负责任的编程人员。同时为了更好的模拟雪花的运动状态,建议创建一个雪花结构图,如下所示:const int MAX_NUM=20;/最大的雪花数量 typedef struct SNOW_STRUCT int pos_x;/初始横坐标 int x,y;/位置 int vx,vy;/速度 int ax,ay;/加速度(未用)SNOW;www.PDFCwww.PDFCwww.PDFCSNOW snowsMAX_NUM;/雪花数组 相关游戏框架代码如下:void GameStart()srand(GetTickCount();/生成随机数种子 /对雪花进行初始化 for(int i=0;iMAX_NUM;i+)snowsi.pos_x=snowsi.x=i*SCREEN_WIDTH/20;snowsi.y=0;snowsi.vy=1+rand()%3;/垂直速度范围(13)snowsi.vx=1+rand()%5;/水平速度范围(15)void GameRun()for(int i=0;i5|snowsi.pos_x-snowsi.x5)snowsi.vx=-snowsi.vx;snowsi.y+=snowsi.vy;/垂直范围控制,落到地下后重新开始 if(snowsi.ySCREEN_HEIGHT)snowsi.y=0;/重新生成随机速度 snowsi.vy=1+rand()%3;snowsi.vx=1+rand()%5;HDC hdc=GetDC(g_hWnd);RECT rect;GetClientRect(g_hWnd,&rect);/清屏(用一个黑刷子重新刷一下窗口)FillRect(hdc,&rect,(HBRUSH)GetStockObject(BLACK_BRUSH);/绘制雪花 for(int i=0;iMAX_NUM;i+)DrawIcon(hdc,snowsi.x,snowsi.y,LoadIcon(g_hInstance,MAKEINTRESOURCE(IDI_ICON1);ReleaseDC(g_hWnd,hdc);Sleep(30);/休息 30ms 写好游戏框架后插入到 WinMain 函数的相应位置(自己思考应该插在什么位置)。改进之处:1、将窗口做成一个全屏幕的界面,并按下 ESC 键时退出。www.PDFCwww.PDFCwww.PDFC判断按键按下和弹起,可以使用下面两个宏#define KEYDOWN(vk_code)(GetAsyncKeyState(vk_code)&0 x8000)?1:0)#define KEYUP(vk_code)(GetAsyncKeyState(vk_code)&0 x8000)?0:1)www.PDFCwww.PDFCwww.PDFC