对于学习过计算机相关专业的同学来说,C++语言是一门必不可少的学习课程,但是真正灵活掌握的不多。为使大家灵活驾驭C++语言技术,今天推荐大家学习《C++开发手册:基础·案例·应用》这本书。
该书提供了丰富的学习内容,是一本侧重编程基础+实践的C++图书,提供包含以上示例、案例12个与两个大型项目等附赠资源。小编从书中精选了1个案例,通过该实例,带领大家探索C++语言之旅——快乐吃豆子。
快乐吃豆子的英文名称为Pacman,可在多种系统、平台上运行,是一款非常经典的动作休闲游戏。
经典游戏吃豆子本案例将使用WindowsAPI,依照面向对象的设计方法,逐步完成一个让人爱不释手的MINIGAME。
在吃豆子(Pacman)游戏中,玩家可以操作的角色是一张“大嘴”。游戏的目的是操作“大嘴”躲避敌人吃掉所有的豆子。游戏中物体所在的场地是二维的平面,并且存在墙与障碍物,本游戏一共有3关,运行效果如图所示。
吃豆子游戏第1关
吃豆子游戏第2关
吃豆子游戏第3关
本系统的软件开发及运行环境具体如下:
操作系统:Windows10。
语言:C++。
开发环境:VisualStudio。
在编写快乐吃豆子游戏前,需要先了解实现该程序的业务流程。根据该程序的业务需求,设计如图所示的业务流程图。
业务流程
下面是制作游戏快乐吃豆子的步骤。
1.用visualstudio创建窗口程序(1)创建项目打开VisualStuido,弹出新建窗口,选择菜单项“创建新项目”--“Windows桌面应用程序”,点击“下一步”。在弹出的配置新项目的界面中,首先输入项目名“pacman”,然后选择保存项目路径,最后点击“创建”按钮,如图所示。
配置新项目
至此,我们尚未输入一行代码,IDE(集成开发工具,这里我们用的是VisualStudio)己经为我们生了一个程窗口程序。接下来我们会在此程序的基础上,进行加加减减,逐步实现快乐吃豆子游戏程序。
(2)制作游戏窗口在上一节中,未写一行代码,就实现了一个窗口程序,而且还自带菜单等功能。接下来要修改这个窗口的大小,以符合游戏的要求。具体步骤如下:
包含必要头文件
为了方便以后使用,先在stdafx.h文件中包含以后用到的标准库头文件。打开stdafx.h文件,在文件最下方,增加:
01#includememory
02#includevector
03#includealgorithm
04#includefunctional
后续程序中的其他文件的第一行代码都是“#include"stdafx.h"”,因此在stdafx.h文件中包含的文件相当于包含于每一个程序文件中。
修改窗口大小
打开pacman.cpp文件,该文件默认创建了一个窗口,该窗口不符合游戏窗口的条件。我们来改造一下,把窗口设定为指定的大小,并设置其位置为电脑屏幕的左上角,具体步骤如下:
√在pacman.cpp文件中找到“#include"pacman.h"”一行,在下面插入:
01usingnamespacestd;
02#defineWLENTH//高
03#defineWHIGHT//宽
04#defineSTAGE_COUNT3//一共三关
05staticHWNDg_hwnd;//游戏窗口句柄
√在pacman.cpp文件中找到下面的语句:
01HWNDhWnd=CreateWindowW(szWindowClass,szTitle,WS_OVERLAPPEDWINDOW,
02CW_USEDEFAULT,0,CW_USEDEFAULT,0,nullptr,nullptr,hInstance,nullptr);
这是创建窗口的语句,指定了窗口的标题、风格、初始大小和位置。将上面的语句替换成下面的语句:
01//创建窗口
02HWNDhWnd=CreateWindowW(szWindowClass,szTitle,WS_OVERLAPPEDWINDOW
03,0//在屏幕中的位置x
04,0//在屏幕中的位置y
05,WLENTH//宽
06,WHIGHT//高
07,nullptr,nullptr,hInstance,nullptr);
上述代码限制了窗口的大小,并指定窗口的初始位置在屏幕的左上角。
√在这几句的下面找到:
01if(!hWnd){
02returnFALSE;
03}
在下面追加:
04//保存游戏窗口,后面会用到
05g_hwnd=hWnd;
说明:到此为止,游戏的主窗口己经改造好了。读者可以尝试运行一下。运行结果如图所示,一个宽度为像素,高度为像素的游戏主窗口。
经过上述操作,已完成游戏主窗口代码的编写。
改造后的游戏窗口
建立游戏循环游戏中需要快速的显示画面和更新游戏状态,因此需要一个一直运行的循环来驱动画面和状态的更新。在创建win32程序时,己经自动生成了一个消息循环,主要用来处理windows系统消息。我们修改这个消息循环,使它既可以处理Windows消息,又可以做为游戏循环使用。
打开pacman.cpp文件,找到:
01//主消息循环:
02while(GetMessage(msg,nullptr,0,0)){
03if(!TranslateAccelerator(msg.hwnd,hAccelTable,msg)){
04TranslateMessage(msg);
05DispatchMessage(msg);
06}
07}
上面的代码是VisualStudio自动生成的窗口消息循环。这个循环中使用的GetMessage函数只有在有消息时才会返回,无消息时阻塞。把上述代码替换成如下代码:
01//主消息循环:
02boolbRunning=true;
03while(bRunning){
04//获取消息
05if(PeekMessage(msg,NULL,0,0,PM_REMOVE)){
06if(msg.message==WM_QUIT){
07break;
08}
09TranslateMessage(msg);
10DispatchMessage(msg);
11}
12}
2.碰撞检测的实现在地图类GMap类中,使用了bool型的二维矩阵储存地图上墙壁位置的信息。当值为false时,则表示该位置有墙壁;当值为true时,说明该位置没有墙壁。
依照碰撞检测的标准,首先应该更新物体所在的行、列数据。
01boolGObject::Achive()
02{
03intn=(point.x-pStage-LD/2)%pStage-LD;
04intk=(point.y-pStage-LD/2)%pStage-LD;
05booll=(n==0k==0);
06returnl;
07}
08voidGObject::AchiveCtrl()
09{
10if(Achive())
11{
12dArray=PtTransform(point.x);//更新列
13dRow=PtTransform(point.y);//更新行
14}
15}
16intGObject::PtTransform(intk)
17{
18return(k-(pStage-LD)/2)/pStage-LD;
19}
首先,讲解下PtTransform这个函数。在类中将它声明为访问权限为protected的函数,它的作用是将物体在屏幕上的坐标转换为行\列坐标。
用图分析,以左上角第一个格子为基准:
坐标偏移与转换
第一个格子的左上角坐标为0。以列为例,当换算方格中心坐标与第一个方格的距离时,需要先减去第一个方格的左边界与中心坐标的距离,然后整除方格大小。
同样的,在Archive函数中判断物体是否到达方格的判断条件是查看方格的中心是否和物体中心重合应用矩阵坐标与窗口坐标的转换。
后面的步骤还有:地图类的设计、数据更新和绘图,如果想要获得更详细的步骤和代码的话,可以参考《C++开发手册:基础·案例·应用》这本书。
点击“阅读原文”
了解开发手册全系图书
预览时标签不可点收录于合集#个上一篇下一篇