2018腾讯next idea高校游戏创意赛——《秦征》开发记录

这篇文章记录开发《秦征》demo时踩过的一些坑和设计上的思考。
演示视频(捂脸请原谅这拙劣的美工23333)
https://www.bilibili.com/video/av28456233

团队构成

从团队构成来看这次的确准备不周,原本预计有9个人,后来实习分走一大波,只剩下4个人,然后又有一个回家网不好上不了GitHub而退出,还有一个日常划水天天失联(等等这剧情是不是有点熟悉)。好在剩下的一位大佬十分认真负责,最后有惊无险地压线完成任务。

游戏设计

在构思参赛题目的时候恰好十分喜欢《全面战争战锤2》,加上曾经是《文明》中毒玩家,于是诞生了把战棋类和即时操作杂糅起来的玩法(后来想想这不就是RTS吗啊喂喂【强力拍桌】)。深入做了以后发现不然。棋类游戏的规则有高度抽象的特点,而RTS即时战略类往往有高度仿真的特点。棋类游戏得益于其抽象化的规则,可以使得玩家从全局战略的角度来考察局面,然而对战时间往往够长,而即时战略类则一般是拼手速、讲操作的战术层面对抗。全面战争给出的解决方案是分为战略视图和战术视图,只有当开始对战时才能看到战术视图。思路上来说,这个游戏的设计目标是在短短两分钟内,带来一次完整的战棋体验。

玩法

玩法融合了很多围棋要素和中国象棋要素。主要是操纵我方棋子去攻击敌方棋子,占领更多的地盘、摧毁敌方的宫殿。地盘可以带来诸多buff,还可以在我方地盘上创建新的棋子。

基于兵马俑的兵种设计

兵种分为步兵、弓兵、车兵
立俑
1. 攻击范围:上下左右一格范围。
2. 可以挥剑进行攻击
3.攻击力和防御力都是中等的基础兵种

跪射俑
1. 攻击范围:以自己为中心的九宫格。
2. 可以射出弓箭进行攻击,攻击力高于立俑,但是防御力比较弱。
3. 一种比较有优势的兵种配合是步兵在前线扛伤害,弓箭手在侧翼进行输出

战车俑
1.攻击范围:当前朝向的正前方一格
2. 对步兵会造成比非常大量的伤害。
3. 相应的,被步兵攻击侧面也会有很大损失。
4.战车俑有冲锋加成的概念:从上一次转向开始计算,每走一格累计一点冲锋加成,转向时清零。冲锋加成会造成额外的伤害。

胜负条件

胜利条件:攻占敌人的宫殿或者时间结束时,我方所占有的格子数比敌方多
失败条件:自己的宫殿被摧毁,或者场地中我方所占有的格子数目比敌方少
平局条件:既不满足胜利条件,也不满足失败条件的情况(一般不可能出现,除非双方都挂机)

操作方式

操作简洁直观,主要交互有 放入棋子、让棋子攻击敌人、让棋子移动到指定位置。

  1. 在场地内放入棋子:拖动兵牌到场地内属于玩家的格子上(蓝色区域)
  2. 操纵我方棋子攻击敌方棋子:点击我方棋子,再点击要攻击的敌方棋子,我方棋子会移动到合适位置进行攻击
  3. 操作我方棋子进行移动:点击我方棋子,再点击要移动到的位置,我方棋子会移动到指定的位置。

领土规则

  1. 当周围领土上属于我方的格子比较多时,棋子的移动速度会变快、攻击力会变高
  2. 只能在属于自己的领土上放置新的棋子。
  3. 某一时刻,只能有一个棋子站在一个格子上。
  4. 有一些格子是不可走的,在demo中标红(美术资源还没做)。

硬伤

我们做到最后发现,使得体验不如预想的竟然源于计算机经典问题——死锁。死锁在于我想去可以打到你的地方打你,你想去能达到我的地方打我。然后我到了能达到你的地方,你却已经不在那个位置了——你已经来打我了。然后循环往复,双方永远“在路上”。仔细一想解决方案也不是没有——变非抢占为抢占,也就是回合制[手动捂脸]
另外一个设计上不够优雅的是兵种特色并没有很好的体现出来

总结

总体来说是一次差强人意的设计尝试。问题出现了不少,比如说如何处理双方同时的移动,不仅导致了诸多bug,也暴露出设计上考虑的不周密,不过也还算有意思。

程序设计

这次我负责的主要是地图管理器、棋子管理器、游戏交互、AI管理器

游戏交互

创建棋子:主要是OnDrag的一系列引用。各个PointerEventHandler十分强大,继承一下接口就可以轻松实现拖拽效果。提一个暗坑。一定要记得创建EventSystem……否则可能要花很长时间找不存在的点击失效bug……
操作棋子:细节比较多,各种边缘情况都要考虑。采用了简单的有限状态机的方法。

寻路算法

这个在上学期unity课的作业时就做过,本来这次打算用估值函数的方法,后来发现是我太天真了,乖乖用回AStar算法。吸取了上一次经验,这次把寻路模块从地图管理器中独立出一个类,这个类只能被地图管理器调用,保证了模块性。
这个算法在看似简单,细节却不少,在实际使用中有几个坑点,也是我们卡壳比较久的地方。

  • 寻不到路的情况:如果不存在一条到达目的地的路径,那么会导致死循环无限调用。表现为unity卡死,调试都找不出来。这个时候返回值需要特别处理,告诉控制器你没有找到路。这个bug遇到过两次,有一次表现卡死,另一次则表现为栈溢出。解决时用了冗余的防错逻辑,不太优雅。
  • 多个棋子寻路时冲突的情况:这个bug和下面的bug是相辅相成的。不过在某一种情况下不同。那就是如果我方两个棋子企图同时到达一个格子,那么就会有一个先到达,另一个被打断移动,更换路线。这样看起来就很不美好,会造成后面一个到达者的重复劳动。结局方案是用了《游戏人工智能》中防止多个物体寻路终点接近导致碰撞的机制——每次出发前会告知地图管理器,这个位置已经被我预定了,切实移动到该位置后解除预定(感觉有点像加锁解锁的概念)。
  • 当曾经寻找到的路变为不可走的情况:我们采用了观察者模式的方法,如果发现下一个路已经无法走(一般是被敌人抢先到达),那么发布事件,接收者接收到后返回当前格子位置的正中心。

对战AI

这一块是最后两天冲刺时候的重点。我们的游戏本质上还是个棋类游戏,AI必须是基于棋手考虑的而不是棋子。一开始对构造AI的思路一无所知,后来看了《游戏人工智能》里面“功夫圈”模型后顿时茅塞顿开。

功夫圈模型介绍:ACT游戏中,你会发现如果有多个敌人冲过来,他们会冲到你跟前然后站住。每一时刻发动攻击的往往只有“被攻击容量”允许的几个敌人。比如我被攻击容量为2,那么同时只有两个敌人会来攻击我,其他人站着看戏。

具体使用:每一个潜在的被攻击者都有一个“被攻击容量”的数据结构。这个玩意有点像“信号量”。当一个攻击者攻击被攻击者时,攻击者被记录进“被攻击容量”中(P操作)。如果“被攻击容量”已经满了,AI控制器就判断这个潜在被攻击者不值得再投入兵力去打了。但攻击结束时(根据规则,是一方死亡时)释放容量(V操作)

选择攻击对象的细节:在候选攻击对象中(还有足够的“被攻击容量”的棋子)选择估值高的对象进行攻击。估值包括距离、剩余血量、兵种克制。

在哪里放置棋子也需要AI思考。我这样设计这一部分的逻辑:把战场划分成多个区域,根据区域内相对兵力的多寡(多和寡都不倾向放,只有兵力胶着的地方才放)放置棋子。

硬伤

由于死锁在设计上没有彻底解决,最后可能会出现我跑到你的位置打你,你跑到我的位置打我的搞笑“跳舞”局面。迫于ddl,最后使得敌人接近我方时强制停止,而后除非再次得到AI控制器的命令攻打我,否则等待我方主动打它并开始回击。理想状况下效果其实还不错,但由于AI控制器采取随机数指令,可能会导致看戏摸鱼的棋子存在。然后后来想想,即时大名鼎鼎的全面战争系列也没能解决士兵摸鱼的蠢事发生——那么就只能采用解决死锁的最佳方法——装作死锁不存在。

另外一个就是没有放棋子时考虑兵种克制和相对位置的问题。不过看上去好像影响不大。

猜你喜欢

转载自blog.csdn.net/kotomineshiki/article/details/81462322