基于WIN32 API界面编程实现的华容道小游戏

catastrophe

发布日期: 2018-10-06 22:07:42 浏览量: 311
评分:
star star star star star star star star star star
*转载请注明来自write-bug.com

1 游戏简介

华容道是古老的中国智力游戏,由“曹操败走华容道,正与关公狭路逢。只为当初恩义重,放开金锁走蛟龙”这一故事情节引申而来。华容道有一个4*5的二十个方块构成的棋盘,下方边界中间有一个宽为2方格的出口,还包含1个2*2的大滑块代表曹操,5个2*1的滑块代表五虎上将,4个1*1的小滑块代表小兵。游戏的目的是利用棋盘中两个1*1的空格来移动所有滑块,不允许跨越棋子,设法用最少的步数,最终使最上方被包围的曹操从出口成功脱逃。我在保持“横刀立马阵型”的基础上美化了滑块的图案,借用了时下流行的游戏“阴阳师”这一主题,赋予这个古老游戏一个新的面貌。

2 程序功能

在Win32下以图形界面提供给用户游戏平台,游戏开始时,所有滑块的起始位置都是确定的,用户通过鼠标点击选中滑块,被选中的滑块会闪烁,鼠标点击空白处,滑块会移动到相应位置,每次只能移动一步。

3 设计思路

WIN32界面编程要点:

  • 主函数WinMain函数最重要的是注册窗口和创建窗口以及message的get、translate和dispatch
  • GamePaint函数运用window的GDI函数完成了核心步骤,即所有图像的绘制过程
  • CallBack回调函数则是从客户的所有操纵中接受信息并把它处理后反应为在游戏中的各步操作

用户操作方面包含数据表示和操作控制两个方面。

3.1 数据表示

将棋盘分为4*5大小的20个块,即建立一个橫为4,纵为5的二维数组,首先用结构体定义游戏中使用的坐标:

  1. typedef struct _coord
  2. {
  3. short x;④
  4. short y;
  5. int select;
  6. }game_coord, *Pgame_coord;

x为横坐标,y为纵坐标,select为判断滑块是否选中,初始值为0,当被选中后select变为1,画边框函数根据判断函数勾勒对应边框。

游戏中,兵将需要使用不同的图片,故需要用不同的数字标志不同的棋子,在主函数WM_CREATE的消息中,创建一个新游戏时,需要同时创建4个兵,5个将和一个核心滑块,因此需要以下函数:

  1. void CreateGame(HWND hwnd)
  2. {
  3. SetBoundary();
  4. CreateSoldier();
  5. CreateGeneral();
  6. CreateCMAN();
  7. CreateEmpty();
  8. }
  • Setboundary用于设置x=4,y=5的边界
  • CreateSoldier用于创建四个小兵,分别赋予他们对应的x和y值
  • CreateGeneral用于创建五个将,分别赋予他们每人对应的两个部分的x和y值
  • CreateCMAN用于创建核心滑块,赋予其四个部分对应的x和y值
  • CreateEmpty用于创建两个空白,分别赋予他们对应的x和y值

棋盘上的所有部分都用(x, y)数据点来表示,在GamePaint绘制函数中将图案赋予他们,成为区域,得到如下效果。

3.2 操作控制

操作包含选中和移动。

设置全局变量nCode[2]来保存两次鼠标点击的滑块数据。当主函数第一次接收到WM_LBUTTONDOWN鼠标点击信息时,通过TransferPos(LOWORD(lParam), HIWORD(lParam))函数找到鼠标点击的对应位置,并将它转换成对应滑块的序号,用nCode[0]来记录,此刻再调用Dispatch函数,将选中的滑块序号转化为对应的某种类型的确定的某一滑块,并将其对应的select值设置为1,调用GamePaint函数将被选中的滑块勾出黑色边框。

当主函数第二次接收到WM_LBUTTONDOWN鼠标点击信息时,通过TransferPos(LOWORD(lParam), HIWORD(lParam))函数找到鼠标点击的对应位置,并将它转换成对应滑块的序号,用nCode[1]来记录,此刻调用DispatchCode(nCode)函数,将两次鼠标点击信息传入,在函数内部设置flag变量,来控制鼠标第一次选中的滑块类型,和判断鼠标第二次是否选中空白,然后进入CanMove(p, i, flag, j)函数,p为第一次选中滑块的坐标,i为选中某类型的第几个滑块,flag为选中滑块的类型,j为选中第几个空白。CanMove函数只需判断被选中单元到目的地是否可行即可,程序定义了上下左右四个方向,要判断所到之处是否全为空格,若成功则互换两个滑块的坐标,若不成功则返回0值。DispatchCode函数返回的值表示是否有移动,若有移动则需要调用GamePaint函数进行重绘,效果如下图所示。

效果1 效果2

3.3 其他

游戏中定义了全局变量step来记录玩家移动了多少步,并实时显示在屏幕下方,玩家一共有88次机会,若步数用尽,则会弹出提示框游戏结束,若在步数限制内成功解救大滑块,则会弹出提示框游戏胜利,如下图所示。

游戏失败 游戏胜利

4 总结

  • 首先是了解每个函数的作用和主要函数的参数形式,然后对老师的代码进行模仿,第一步实现了游戏坐标的设置,对每个滑块的坐标进行了生成、定义以及获得函数,并通过理解该写老师的ui.c文件,实现了将抽象的点类数据以色素块的形式展现在屏幕上。
  • 第二步是获取用户的鼠标操作和滑块移动,先开始不会处理将两次鼠标点击信息同时储存的步骤,于是只能实现鼠标点击相应滑块后,滑块自己向周围空白可移动的方向移动,但是这样的信息处理出现了bug,即当所选中的滑块可以同时向左向右(或向上向下)移动时,它只能单调地向某个方向移动,这样就使得当用户想让滑块右移的时候无法满足其需求,于是只能回头,依然是得实现鼠标两次点击实现滑块的移动。
  • 第三步即前文所述,创建了全局变量nCode[2]和count,通过count++来判断鼠标点击的次数,同时nCode储存两次鼠标点击的信息,从而成功实现了用户第一次点击滑块,第二次点击空白,使用户能顺着自己的心意使滑块向自己想要的目的地移动。但同时出现的一点不妥,因为count在鼠标点击的同时自加,只有在两次点击都有效时才能实现移动功能,如果用户不小心点错,界面又没有是否选中的提示,很容易在一次次点击中使count的值错乱,从而点击屏幕没有响应,于是给选中的滑块进行标示就变成一件不得不实现的事情了。
  • 第四步,在游戏坐标结构体中增加了select变量,用来判断该滑块是否被选中,通过模仿画边框的函数成功实现了用户点击某滑块,该滑块会加上黑色边框的效果。
  • 第五步,为了对游戏进行美化,将色素块换成了“阴阳师”游戏中可爱的人物图片,在这一过程中经历了麻烦的事情,像同学求助贴图操作,明明是一样的代码却一直不能实现位图的成功粘贴,最终在老师的帮助下发现了函数调用的问题,成功实现了贴图操作,非常感谢老师和伸出援手帮助我的同学们~
  • 第六步,给游戏加上了背景音乐,先开始根据网上教程使用了PlaySound函数,但因为头文件以及字符串无法读取的问题不能成功使用,在终于成功播放出音乐后又遇到了新的问题——该函数必须在音乐全部播放结束后才会接受和处理下一步操作,导致把它加在哪条语句之后都很不方便,于是改用mciSendString函数,成功实现了背景音乐的添加。

至此,暑期小学期实现华容道小游戏的作业完美收工!对自己的努力和成果较为满意。在这个过程中,学到了很多东西,不光是学习上的知识还有收集信息处理问题以及自己尝试学习解决问题的能力,附上最终效果图,可惜听不到音乐^_^

效果图1 效果图2
上传的附件 cloud_download WIN32 API实现的小游戏-华容道.part1.rar ( 52.43mb, 14次下载 ) cloud_download WIN32 API实现的小游戏-华容道.part2.rar ( 35.91mb, 8次下载 )
error_outline 下载需要8点积分

发送私信

如果你改变不了沙漠,又没本事离开沙漠,那你只能把自己变成仙人掌

7
文章数
8
评论数
最近文章
eject