0
点赞
收藏
分享

微信扫一扫

基于C++的《元素战争》基于win32框架的电脑游戏设计

一、游戏介绍

​ 《元素战争》是一款基于 win32 框架的电脑游戏。作为一款即时战略性游戏,玩家需要充分利用手中的八卦排兵布阵,赢得游戏以获得更多的八卦,来扩大自己的元素部队。

​ 游戏暂时共设计两关,玩家通过排兵布阵选择出战的元素和数量,游戏开始后自动与电脑方元素进行对战。游戏融合了中国古代道家阴阳五行的思想,金、木、水、火、土五大元素之间相生相克,同一元素对不同的元素攻击效果各不相同。如何选择合适的出战元素并将它们放置在合适的位置,既是游戏的一大挑战,也是游戏的趣味性所在。

​ 游戏背景:古书《尚书·洪范》记载:“五行:一曰水,二曰火,三曰木,四曰金,五曰土。水曰润下(滋润),火曰炎上(燃烧),木曰曲直(弯曲,舒张),金曰从革(成分致密,善分割),土爰稼穑(意指播种收获)。润下作咸,炎上作苦,曲直作酸,从革作辛,稼穑作甘。”古人认为,金、木、水、火、土五种元素,是构成宇宙万物及各种自然现象变化的基础。五行相生相克,若它们之间发生战争,谁又会更胜一筹?

二、游戏设计

  • 玩家在开始界面可点击“游戏背景”了解设计背景;点击“玩法介绍”了解游戏大概流程;点击“关卡选择”,选择想要进入的关卡。建议按顺序由易到难体验游戏。

  • 进入“角色选择”页面。玩家需根据元素属性介绍和关卡中电脑方的元素配置选择己方参战元素和数量。玩家只有一定数量的八卦,不同元素所需要的八卦数量不同,建议合理分配。玩家只可以在对战擂台上放置元素。

  • 开始游戏。电脑方元素全部死亡即为胜利,将得到下一关八卦数量增加的奖励。在此之前,若己方元素全部死亡,则为失败,下一关游戏八卦数量减少。

  • 卦数量降至 0,则游戏结束。玩家需要返回开始界面,重新开始新一轮游戏。若玩家在两个关卡都取得胜利,则游戏通关,数据将被初始化,玩家亦需要返回开始界面重新开始新一轮游戏。

2.1 界面设计

图 1:开始界面,包括关卡选择、玩法介绍、游戏背景

图 2:人物选择界面

玩家可通过点击元素名称查看元素简介

图 3:打斗画面

图 4:玩家两关均胜利,开启自由对战模式

图 5:自由对战模式,玩家需设定双方上场人数,然后各自排兵布阵

2.2 交互设计

​ 玩家主要通过鼠标左键点击按钮跳转界面。

​ 特别地,在角色选择界面,玩家需点击人物(元素)名称查看人物特性,之后再次点击人物名称确认选择该人物,然后点击擂台上某位置放置元素。而在自由对战模式下,玩家需先点击“人物数量”下的数字增加双方人物上场数量,点击八卦确认后,再开始排兵布阵。

​ 玩家除了通过点击游戏界面右上角的暂停键进入暂停界面,还可以通过按 ESC 键进入暂停界面。

2.3 流程设计

图 6:玩家角度的游戏流程图(可放大查看)

三、游戏实现

  • 写出 win32 程序框架,包括前向声明、数据初始化、主消息循环、设置窗口大小等;
  • 加载图像资源,添加按钮和按钮事件,添加鼠标和键盘点击事件,添加计时器事件;
  • 添加游戏所需要的各种函数,如碰撞检测,胜负判定,死亡人物动画播放,添加按钮,添加主角,单位行为函数等;
  • 初始化游戏场景;
  • 添加绘制函数,绘制图像。

3.1 代码流程

图 7:游戏程序的主要模块及其功能、游戏的运行流程、模块之间调用关系

3.2 核心模块

碰撞检测

两个角色相碰则交换其速度(根据动量守恒定律)。角色碰到屏幕边界则坐标值回移。

算法:两层遍历所有人物,若两个人物 X 坐标和 Y 坐标相减的绝对值小于人物图片大小,则速度交换。

单位行为函数

每种单位行为不同,追随的目标和攻击的效果不同。单位行为函数实现了我的构想。

算法:遍历所有人物,找到角色的目标人物,若目标人物状态为存活,则将其放入一个 vector 中。选择 vector[0]为追随目标。计算角色与追随目标之间的距离,判断是否在角色攻击范围内,选择角色状态。若是行走状态,则根据上一秒的速度和最大速度判断是做加速运动还是匀速运动,改变人物速度;若是攻击状态,则根据元素特性对 vector 中的目标展开攻击(减慢速度、降低生命值或降低目标攻击力)。最后画面运行到下一帧,清空目标 vector。(因为下一消息中人物可能死亡,不需要再将其放入 vector 中)

人物选择与自由对战模式

实现玩家在阅读人物简介后选择人物排兵布阵打败电脑方的效果。也可以自由选择双方出战元素,比较不同元素的特性。

算法:人物选择:进入人物选择场景后,若玩家点击元素名称,则显示人物介绍,再次点击则开启选择模式(choose 被置为 true),若放置元素位置在擂台上(根据鼠标坐标判断),则在鼠标位置生成一个结构体,播放人物动画,同时将 choose 置为 false。

自由对战模式:点击人物数量,若数量小于 10,则数量 +1,否则不予增加。点击右方按钮确认,将玩家一选择(bool choose1)置为 true。重复人物选择过程。再次点击右方按钮确认,将玩家二选择(bool choose2)置为 true,玩家一选择置为 false,开始玩家二选择。两个玩家布置完毕,点击开始游戏按钮开始战斗。

四、总结与感悟

遇到的问题

  • 不知道怎么实时显示八卦数量和人物数量

​ 查资料发现了 TEXTOUT 函数,于是设定了全局变量存储八卦和人物数量。然后发现 TEXTOUT 函数需要的是 TCHAR 类型变量,和 int、char 之间存在一个转换。最后找到了 itoa 函数,成功输出了可以改变字体、颜色、大小的文字。

  • 玩家该怎么选择人物?

​ 为了不再写一个界面放人物介绍,我采用了点击元素名称显示人物介绍,再次点击进入选择模式,第三次点击选择放置元素的位置的方法。框架里已经给出显示鼠标位置的函数,所以想法清晰之后写起来不困难了~

  • 碰撞函数怎么实现?

    两个人物碰撞后,根据动量守恒,速度交换反向,这样之后他们可能再次互相吸引,再碰撞反向……这样既不会元素完全重叠,也不影响人物函数效果。

    但是仅仅是速度反向,人物还是有可能跑到屏幕外面。于是我采取了暴力方式:碰到屏幕边缘坐标就往回移 5 像素。于是人物有可能出现撞墙效果……(但是问题解决了!)

  • 人物不按照我预想的跑

​ 当时在人物的速度改变上遇到了很大的困难。因为碰撞函数实现了速度反向,如何设置合理的加速度和速度最大值使人物继续向着目标移动是一大难题。最后经过反复调试设置了比较合理的加速度和合适的 if 条件。

  • 动画显示不出来?怎么播放死亡动画?

​ 开始的时候人物的动画存在不止一行里,不知道如何处理。后来把一个动画的每一帧存在一行里,通过数组规定播放每一帧的长度。

​ 为了在人物死亡后播放动画,我给人物添加了 live 变量,死亡后改变该变量。改变后将生成与该人物同一属性的一个结构体,开始播放死亡动画(unit 此时不再被绘制出来,取而代之的是另一个结构体)。同时添加了一个判断,只有所有死亡动画都播放完毕时,才会进入下一个场景(胜利或失败)。

心得体会:

​ 刚开始的时候完全看不懂框架,不能理解每个部分的作用。后面在助教的建议下开始改改按钮、增加图片,前两个礼拜在美工的路上一去不复返。有了界面之后,加上天天看框架结构,突然我就能理解我要做什么了。水滴石穿,办法总比困难多哈哈。

​ 虽然做得肯定比不上大佬,但成功完成大作业让我充满成就感。在做游戏的过程中对于函数的调用和整体项目构建的概念更加深刻,学会了从一个更宏观的角度来看程序。同时也意识到代码的可读性非常重要,注释是一定要有的。冗余重复的代码会给自己添加很多工作量,所以写代码的时候要有大纲,不然反复改真的很痛苦。(最好存一份附件,以免自己都改完了又想改回去。)

​ 写游戏的过程中也大大提高了自学能力(和 ps 能力),学会了许多新函数(比如 textout、mci 等等),学会了许多新概念(句柄等等),学会了如何迅速从别人的代码或回答中提取有效信息来修改自己的代码……虽然做大作业的过程非常焦虑,但做完大作业真的快乐!!

老师和助教辛苦啦!

五、参考资料

  • https://www.csdn.net/
  • https://github.com/QianMo/Direct3D-Win32-Book-Src-Code
  • https://blog.csdn.net/luoyikun/article/details/42191863
  • https://588ku.com
  • http://www.biyezuopin.vip
举报

相关推荐

0 条评论