收藏 分享(赏)

VC++C语言贪吃蛇与俄罗斯方块.doc

上传人:hyngb9260 文档编号:4406573 上传时间:2018-12-27 格式:DOC 页数:80 大小:540KB
下载 相关 举报
VC++C语言贪吃蛇与俄罗斯方块.doc_第1页
第1页 / 共80页
VC++C语言贪吃蛇与俄罗斯方块.doc_第2页
第2页 / 共80页
VC++C语言贪吃蛇与俄罗斯方块.doc_第3页
第3页 / 共80页
VC++C语言贪吃蛇与俄罗斯方块.doc_第4页
第4页 / 共80页
VC++C语言贪吃蛇与俄罗斯方块.doc_第5页
第5页 / 共80页
点击查看更多>>
资源描述

1、实例分析一、贪吃蛇 阶段一:贪吃蛇程序整体类结构 贪吃蛇游戏介绍一条蛇在密闭的围墙内,在围墙内随机出现一个食物,通过按键盘上的四个方向键控制蛇向上接着又出现食物,等待被蛇吃掉,如果蛇在移动过程中,撞到墙壁或身体交叉蛇头撞到自己的身体游戏结束。贪吃蛇游戏示意图: 贪吃蛇游戏类设计贪吃蛇游戏需要设计两个类:1) 蛇类:蛇自身的属性包括蛇头、蛇尾、蛇的位置等等;蛇的方法包括出生、移动、吃食等等, CSnake 类结构下图所示:CSnake 类变量名 数据类型 意 义m_length int 蛇的长度m_newSnake Snake_Struct 蛇的新态的所有节点运动状态m_oldSnake Sna

2、ke_Struct 蛇的旧态的所有节点运动状态m_pStateArray BitmapState* 蛇的所有节点显示位图的状态属性成员m_pPos SPoint* 蛇体坐标函数名 属 性 函数功能GetRightState() private 返回当前应当显示的身体状态Move() public 蛇移动ChangeDirect() public 改变移动方向AddBody() public 蛇的身体增长SetHeadPos() public 设置蛇头的坐标GetStateArray() public 取蛇的状态标识数组GetPos() public 取蛇的位置数组IsHeadTouchBody

3、() public 检测蛇头是否触碰到其身体GetLength() public 获取蛇身的长度Initial() public 游戏初始化CSnake() public 构造函数方法成员CSnake() public 析构函数注:1. Snake_Struct为结构体类型,定义为:struct Snake_Struct/定义蛇体状态MoveState head; /头部MoveState *body; /身体MoveState tail; /尾部;2. MoveState为枚举类型,定义为:/节点运动状态(方向),4 个成员分别对应 4个方向enum MoveStateS_NONE,S_UP

4、,S_DOWN,S_LEFT,S_RIGHT;3. BitmapState为枚举类型,定义为:/节点图像显示运动状态(方向),第一个成员代表无方向,后 12个成员之分别对应 12个方向EnumBitmapStateM_NONE,M_UP_UP,M_DOWN_DOWN,M_LEFT_LEFT,M_RIGHT_RIGHT,M_UP_LEFT,M_UP_RIGHT,M_LEFT_UP,M_LEFT_DOWN,M_RIGHT_UP,M_RIGHT_DOWN,M_DOWN_RIGHT,M_DOWN_LEFT4. SPoint为结构体类型,定义为:struct SPointint x,y;/ 横、纵坐标;

5、2) 桌面类:桌面类的属性包括桌子的宽度、高度、食物、蛇等等;方法包括设置桌面环境,获取食物等等,CTable 类结构下图所示:CTable 类变量名 数据类型 意 义m_width int 桌子的宽度m_height int 桌子的高度m_foodNumber int 水果的数目m_blockNumber int 障碍物(毒果)的数目m_snake CSnake 桌子上的蛇属性成员m_board int* 桌子面板(二维数组)函数名 属 性 函数功能InitialTable() public 初始化桌面AddBlock() public 在某个位置放置毒果AddFood() public 在

6、某个位置放置食物ClearFood() public 清除某个位置的果实GetSnake() public 获取蛇对象GetBoard() public 取桌子对象方法成员GetData() public 取桌子某个位置数据SnakeMove() public 检测蛇头是否触碰到其身体ChangeSnakeDirect() public 改变蛇的方向CTable() public 构造函数CTable() public 析构函数阶段二:贪吃蛇程序整体类间调用关系CSnake:SetHeadPos()CTable:ChangeSnakeDirect()设置自动移动定时器和增加食物定时器游戏开始C

7、Table:InitialTab()CTable:AddFood()桌面初始化初始化蛇头和蛇移动方向随机初始化一个食物到桌面SetTimer()CTable:AddFood()蛇移动蛇吃食?蛇增长继续?蛇死亡?桌面上随机生成食物CTable:SnakeMove()CTable:ClearFood()CSnake:AddBody()退出程序ESC是是否否StartGame()SPACECSnake:IsHeadTouchBody()TB_STATE_SBLOCK阶段三:Win32 SDK 程序消息机制分析光标消息? 1、 释放设备缓存2、 退出消息循环是程序结束否时钟消息?是1、蛇移动或者添加食

8、物2、显示游戏图像销毁窗口?是是否否缺省消息处理消息处理完毕隐藏光标程序立即终止改变蛇头移动方向向上游戏开始GetMessagege()有效消息?是否按键消息?是否向上向下?向左?向右?改变蛇头移动方向向下改变蛇头移动方向向左改变蛇头移动方向向右否否否是是是是Esc?否空格?是否否是结束状态?是阶段四:游戏控制的实现因为有定时器,所以蛇会定时自动移动,为了蛇能继续长大、不碰壁和碰到毒果,必须通过改变方向来改变蛇的移动方向。设定键盘的上下左右键为蛇移动方向的控制键,捕获到键盘消息后,发送给窗口过程。对应的上下左右 4 个方向按键的消息为:VK_UP、VK_DOWN、 VK_LEFT、 VK_RI

9、GHT。相应这四个消息、便可以对蛇的移动状态进行控制,保存在蛇的各个记录蛇状态的成员变量里,然后通过这些信息。绘制出相应的蛇的实时移动状态图,达到控制目的。阶段五:界面的实现与图像资源的加载啊 游戏界面介绍啊此游戏界面为全屏模式,首先根据屏幕分辨率大小,建立一个全屏窗口,以像素为单位作为游戏界面:屏幕最外层四个方向为各 80 像素的围墙(障碍物) ,在上围墙中间又覆盖了一个记分板,中间剩余的部分为游戏区。为了提高游戏的界面显示性能,导入了相关的位图图像资源:包括游戏图标资源、围墙位图资源 brick.bmp、蛇及蛇的各种状态资源 bitmap1.bmp、食物及毒果资源(障碍物) 、游戏记分板资

10、源 scoreboard.bmp、游戏结束画面资源 end.bmp。 游戏界面的实现和图像资源的加载 定义各种图像设备环境(全局变量):HDC windowDC = NULL; /windows屏幕设备HDC bufferDC = NULL; /缓冲设备环境HDC picDC = NULL; /snake图像设备HDC endDC = NULL; /游戏终结图像设备HDC scoreDC = NULL; /分数板设备 定义各种位图缓冲区(全局变量)HBITMAP picBMP = NULL; /snake图像位图句柄HBITMAP bufferBMP = NULL;/缓冲位图句柄HBITMAP

11、 endBMP = NULL; /游戏终结图像内存句柄HBITMAP hbmpWall = NULL; /墙位图句柄HBITMAP hbmpScore = NULL;/分数板位图句柄 定义应用程序窗口句柄(全局变量)HWND hAppWnd = NULL; /应用程序窗口句柄在 WinMain()函数中,要完成程序主窗口的创建和各种设备环境和缓冲区的加载。 设计和注册一个窗口 获取显示器宽和高(像素)/取整个屏幕的尺寸width=GetSystemMetrics(SM_CXSCREEN);/返回屏幕宽度(像素)height=GetSystemMetrics(SM_CYSCREEN);/返回屏幕

12、高度(像素) 创建窗口调用 CreateWindow()函数时候指定窗口宽和长分别为 width和height。 显示和更新窗口 计算客户区大小GetClientRect(hAppWnd, g_iClientWidth = g_ClientRect.right-g_ClientRect.left;g_iClientHeight = g_ClientRect.bottom-g_ClientRect.top;/将游戏区域分成纵,横均为块的小方块/并计算每块区域的大小tableBlockWidth = (g_iClientWidth-2*WALL_WIDTH)/20;tableBlockHeight

13、 = (g_iClientHeight-2*WALL_HEIGHT)/20; /获取当前主窗口设备句柄(与windowDC关联)GetDC()函数返回一个客户区显示设备环境windowDC=GetDC(NULL);CreateCompatibleDC()函数用于创建一个和WindowDC兼容的设备环境bufferDC=CreateCompatibleDC(windowDC);picDC=CreateCompatibleDC(windowDC);endDC=CreateCompatibleDC(windowDC);scoreDC=CreateCompatibleDC(windowDC);Crea

14、teCompatibleBitmap()函数用于创建一个和windowDC 兼容的位图缓冲环境。bufferBMP=CreateCompatibleBitmap(windowDC,g_iClientWidth,g_iClientHeight);LoadImage()函数:加载位图资源,并返回图片指针picBMP=(HBITMAP)LoadImage(NULL,“snake.bmp“,IMAGE_BITMAP,160,80,LR_LOADFROMFILE);/加载蛇图片位图hbmpWall=(HBITMAP)LoadImage(NULL,“brick.bmp“,IMAGE_BITMAP,16,1

15、6,LR_LOADFROMFILE);/加载墙位图endBMP=(HBITMAP)LoadImage(NULL,“end.bmp“,IMAGE_BITMAP,369,300,LR_LOADFROMFILE);/加载游戏结束位图hbmpScore=(HBITMAP)LoadImage(NULL,“scoreboard.bmp“,IMAGE_BITMAP,265,55,LR_LOADFROMFILE);/加载得分板位图设置位图与设备环境的关联SelectObject(bufferDC,bufferBMP);SelectObject(picDC,picBMP);SelectObject(endDC,

16、endBMP);SelectObject(scoreDC,hbmpScore);进入游戏后,将所有游戏数据存在桌面类成员变量中,调用ShellDraw(bufferDC)函数用于绘制桌面初始化环境:包括游戏墙壁、和游戏区、得分板。调用GameAreaDraw(bufferDC)函数用于绘制游戏区域到缓冲:绘制桌面上的食物、毒果和蛇的不断移动状态、游戏结束图。阶段六:系统与整合与代码调试snake.h#ifndef _GREED_SNAKE_#define _GREED_SNAKE_/蛇坐标m_pPos移动增量#define SNAKE_MOVE 1/带参数宏,释放动态申请的空间#define

17、SAFE_DELETE(p) delete (p);(p)=NULL;#define SAFE_DELETE_ARRAY(p) delete(p);(p)=NULL;#include /节点图像显示运动状态(方向)enum BitmapStateM_NONE,M_UP_UP,M_DOWN_DOWN,M_LEFT_LEFT,M_RIGHT_RIGHT,M_UP_LEFT,M_UP_RIGHT,M_LEFT_UP,M_LEFT_DOWN,M_RIGHT_UP,M_RIGHT_DOWN,M_DOWN_RIGHT,M_DOWN_LEFT;/节点运动状态(方向),个成员分别对应个方向enum MoveS

18、tateS_NONE,S_UP,S_DOWN,S_LEFT,S_RIGHT;/坐标位置结构struct SPointint x;/横坐标int y;/纵坐标;class CSnakestruct Snake_Struct/定义蛇体状态MoveState head; /头部MoveState *body; /身体(数组)MoveState tail; /尾部;private:int m_length; /蛇身体的长度Snake_Struct m_newSnake; /蛇的新态的所有节点运动状态Snake_Struct m_oldSnake; /蛇的原态的所有节点运动状态BitmapState *

19、m_pStateArray; /蛇的所有节点显示位图的状态SPoint *m_pPos; /蛇体坐标private:BitmapState GetRightState(MoveState oldDirect,MoveState newDirect);public:void Move(void); void ChangeDirect(MoveState d);void AddBody(int n=1);void SetHeadPos(int x,int y);BitmapState* GetStateArray(void);SPoint* GetPos(void);bool IsHeadTouc

20、hBody(int x,int y);int GetLength( void );void Initial( void );public:CSnake(int x_pos=0,int y_pos=0,int len=1); /构造函数CSnake(); /析构函数;#endif /_GREED_SNAKE_table.h#ifndef _GAME_TABLE_#define _GAME_TABLE_/桌面环境状态#define TB_STATE_OK 0 /正常#define TB_STATE_FOOD 1 /食物#define TB_STATE_BLOCK 2 /障碍毒果#define TB

21、_STATE_SBLOCK 3 /障碍墙#include“snake.h“class CTableprivate:int m_width; /桌子的宽度int m_height; /桌子的高度int m_foodNumber; /水果的数目int m_blockNumber; /障碍物(毒果)的数目CSnake m_snake; /桌子上的蛇int *m_board; /桌子面板public:CTable();CTable();/初始化桌子面板void InitialTable(int w,int h);/食物的操作bool AddBlock(int x,int y);bool AddFood

22、(int x,int y);bool ClearFood(int x,int y);/物件获取CSnake* GetSnake(void);int* GetBoard(void);int GetData(int x,int y);/蛇的操作void SnakeMove(void);bool ChangeSnakeDirect(MoveState d);#endif /_GAME_TABLE_snake.cpp#include “snake.h“CSnake:CSnake(int x_pos,int y_pos,int len)if(len0;i-)/改变蛇身状态m_newSnake.bodyi

23、=m_newSnake.bodyi-1;m_newSnake.body0=m_newSnake.head; /改变蛇头状态/根据新旧位图显示状态特性取正确的状态m_pStateArray0=GetRightState(m_oldSnake.head,m_newSnake.head);/为蛇头获取新的移动显示状态for(i=0;i0;i-)m_pPosi=m_pPosi-1;/蛇头的新位置根据蛇的运动方向判断做相应偏移switch(m_newSnake.head)case S_UP:/向上,蛇头纵坐标减一m_pPos0.y-=SNAKE_MOVE;break;case S_DOWN:m_pPos

24、0.y+=SNAKE_MOVE;break;case S_LEFT:m_pPos0.x-=SNAKE_MOVE;break;case S_RIGHT:m_pPos0.x+=SNAKE_MOVE;break;/蛇的身体增长/void CSnake:AddBody(int n)/ 分配临时的“save类型“变量,用作保留/ 蛇的各种数据状态int i;Snake_Struct saveOldSnake,saveNewSnake;BitmapState *savestateArray;SPoint *savePos;/保存蛇的位置信息/ possavePos=new SPointm_length+2

25、;for(i=0;i=0)/回调函数void DrawGame(void);void ShellDraw( HDC hdc );void GameAreaDraw(HDC hdc);void OnTimer(UINT uTIMER_ID);/定时void StartGame( void ); /游戏开始void EndGame( void ); /游戏结束/创建一个桌子CTable table;int tableBlockWidth = 0; /桌子的格子的宽度int tableBlockHeight = 0; /桌子的格子的高度int iScores = 0; /游戏的得分基数UINT uG

26、ameState = GAME_STATE_WAIT; /当前游戏状态HDC windowDC = NULL; /windows屏幕设备HDC bufferDC = NULL; /缓冲设备环境HDC picDC = NULL; /snake图像内存设备HDC endDC = NULL; /游戏终结图像内存设备HDC scoreDC = NULL; /分数板内存设备HWND hAppWnd = NULL; /本application窗口句柄HBITMAP picBMP = NULL; /snake图像位图句柄HBITMAP bufferBMP = NULL;/缓冲位图句柄HBITMAP endB

27、MP = NULL; /游戏终结图像内存句柄HBITMAP hbmpWall = NULL; /墙位图句柄HBITMAP hbmpScore = NULL;/分数板位图句柄HBRUSH hbrushWall = NULL;/墙画刷/定时器标识UINT uSnakeMoveTimer; /蛇的移动时钟名称UINT uFoodAddTimer; /水果的产生时钟名称/框架的位置数据定义/GDI RECT 而不是MFC CRectRECT g_ClientRect; /客户区RECTRECT g_GameValueRect;/分数区RECTint g_iClientWidth; /游戏客户区宽度in

28、t g_iClientHeight; /游戏客户区高度int WINAPI WinMain(HINSTANCE hCurrentInst,HINSTANCE hPrevInstance,PSTR lpszCmdLine,int nCmdShow)WNDCLASS wndClass;HWND hWnd;MSG msg;UINT width,height;/定义窗口wndClass.style=CS_HREDRAW | CS_VREDRAW;wndClass.lpfnWndProc=WndProc;wndClass.cbClsExtra=0;wndClass.cbWndExtra=0;wndCla

29、ss.hInstance=hCurrentInst;wndClass.hIcon=LoadIcon(NULL,MAKEINTRESOURCE(IDI_MAIN);wndClass.hCursor=LoadCursor(NULL,IDC_ARROW);wndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);/背景设置为白色wndClass.lpszMenuName=NULL;wndClass.lpszClassName=“Snake_CLASS“;/注册窗口RegisterClass(/取整个屏幕的尺寸width=GetSystemM

30、etrics(SM_CXSCREEN);height= GetSystemMetrics(SM_CYSCREEN);/创建窗口hWnd=CreateWindow(“Snake_CLASS“,“skyblue snake“,WS_POPUP,0,0,width,height,NULL,NULL,hCurrentInst,NULL);hAppWnd = hWnd;/当前窗口句柄/显示窗口ShowWindow(hWnd,nCmdShow);UpdateWindow(hWnd);/获取窗体大小GetClientRect(hAppWnd, g_iClientWidth = g_ClientRect.ri

31、ght-g_ClientRect.left;g_iClientHeight = g_ClientRect.bottom-g_ClientRect.top;/将游戏区域分成纵,横均为块的小方块/并计算每块区域的大小tableBlockWidth = (g_iClientWidth-2*WALL_WIDTH)/20;tableBlockHeight = (g_iClientHeight-2*WALL_HEIGHT)/20;/获取当前主窗口设备与windowDC关联windowDC=GetDC(NULL);/创建与windowDC兼容(当前窗口)的内存设备环境(缓冲区)bufferDC=Create

32、CompatibleDC(windowDC);picDC=CreateCompatibleDC(windowDC);endDC=CreateCompatibleDC(windowDC);scoreDC=CreateCompatibleDC(windowDC);/位图的初始化或载入位图bufferBMP=CreateCompatibleBitmap(windowDC,g_iClientWidth,g_iClientHeight);/创建位图缓冲区picBMP=(HBITMAP)LoadImage(NULL,“snake.bmp“,IMAGE_BITMAP,160,80,LR_LOADFROMFI

33、LE);/加载蛇图片位图hbmpWall=(HBITMAP)LoadImage(NULL,“brick.bmp“,IMAGE_BITMAP,16,16,LR_LOADFROMFILE);/加载墙位图endBMP = (HBITMAP)LoadImage(NULL,“end.bmp“,IMAGE_BITMAP,369,300,LR_LOADFROMFILE);/加载游戏结束位图hbmpScore=(HBITMAP)LoadImage(NULL,“scoreboard.bmp“,IMAGE_BITMAP,265,55,LR_LOADFROMFILE);/加载得分板位图/设置位图与设备环境的关联Se

34、lectObject(bufferDC,bufferBMP);SelectObject(picDC,picBMP);SelectObject(endDC,endBMP);SelectObject(scoreDC,hbmpScore);/建立画刷与其名相对应的图像的关联,/以备用刷子将墙刷出来,用PatBlt()实现hbrushWall = CreatePatternBrush(hbmpWall);StartGame();/游戏开始while(GetMessage(DispatchMessage(return msg.wParam;LRESULT CALLBACK WndProc(HWND hW

35、nd,UINT message,WPARAM wParam,LPARAM lParam)/判断消息类型switch(message)case WM_TIMER:OnTimer(UINT)wParam);break;case WM_KEYDOWN:/按键消息switch(wParam)/消息内容case VK_ESCAPE:/Esc按键消息exit(0);/程序异常终止break;case VK_UP:/向上table.ChangeSnakeDirect(S_UP);break;case VK_DOWN:/向下table.ChangeSnakeDirect(S_DOWN);break;case

36、VK_LEFT:/向左table.ChangeSnakeDirect(S_LEFT);break;case VK_RIGHT:/向右table.ChangeSnakeDirect(S_RIGHT);break;case VK_SPACE:/空格if(uGameState = GAME_STATE_END )/如果游戏状态为结束状态StartGame();/重新开始游戏break;return 0;case WM_SETCURSOR:/光标消息SetCursor(NULL);/光标隐藏 return 0;case WM_DESTROY: /销毁窗口消息/释放缓冲区所占内存ReleaseDC(hW

37、nd,picDC);ReleaseDC(hWnd,bufferDC);ReleaseDC(hWnd,windowDC);PostQuitMessage(0);/发出VM_QUIT消息,退出消息循环return 0;return DefWindowProc(hWnd,message,wParam,lParam);/void DrawGame(void)/绘制外壳区域到缓冲ShellDraw(bufferDC);/绘制游戏区域到缓冲GameAreaDraw(bufferDC);/将整个画面从缓冲DC拷贝出屏幕BitBlt(windowDC,0,0,g_iClientWidth,g_iClientHeight,bufferDC,0,0,S

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 网络科技 > C/C++资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报