Tizeng's blog Ordinary Gamer

LudumDare Gamejam开发笔记

2020-04-20
Tizeng

游戏玩法

jam主题为“keep it alive”,我们希望游戏的玩法尽量简单易懂,讨论的时候想到很多点子,最后决定下来做一个类似chrome自带小恐龙跑酷那样的游戏,成品链接在这里

功能

背景移动

游戏逻辑上不复杂,2D视角上实现一个人物不断往前移动的效果只需要保持人物不动,把背景素材向后移动即可,移动的方式是直接用帧间隔乘以速度加上当前的x坐标,然后在到达某一位置(出屏幕)时将其置回初始位置,如此往复。体现出人物移动的背景主要是房屋和草地,为了达到一种不断出现房屋的效果,我使用了两个房屋素材让它们交替出现,这样可以减小每次玩家看到房屋的间隔。草地的话是不停的向后移动,两个有屏幕长度的草地素材就够,当素材1向后移动时素材2紧接着一起移动,1移出屏幕后2刚好到达1的初始位置,然后把1置到2的初始位置,如此往复。

除了凸显玩家向前移动的背景,还有两个远景,山和云,山和房子一样在人物开始跑的时候才往后移,和房子、草地同一套逻辑,只是速度慢很多,云也是一样,只是不论玩家移不移动云都移动。玩家在游戏开始若干秒延迟后(可配置)开始移动,为了让所有向后移动的GameObject都是用同一个脚本Mover,我设置了三个可配置的field:是否需要延迟、是否循环出现、是否同步GM速度。

  1. 延迟的时间由GameManager控制,其他模块如果需要知道设置的延迟就去问GM,配置了延迟时间的Mover就会读取GM中的配置,在update中每次减去帧间隔,直到小于零就开始移动。
  2. 循环控制的是该GameObject是否需要像背景那样连续出现,比如下图中两个house,就是在游戏开始和过关的时候移动,不会反复出现
  3. 人物移动的速度就是背景移动的速度,该速度统一在GM中配置,但有些背景的速度不与人物速度相关,比如远景,它们的速度就自己单独配置

house

游戏过关之后角色会继续往前跑进入house2,这时就不是背景移动了,而是角色自己动,但是在这之前house2要先出现,也就是说完成关卡后要先关闭玩家输入,让house2开始进入屏幕,到达位置后响应一个回调(这里使用的是coroutine),让背景停止移动,主角开始移动,主角到达指定位置后再响应显示过关ui的回调。house2使用的是Obstacle脚本,为了方便控制移动的开始和结束。

游戏数据

数据用了一个static类DataManager来存,它不继承MonoBehavior,所有成员都为static,这样就算场景reload数据也不会丢失。当前关卡、玩家总分等数据都在其中。

障碍物

Spawner脚本负责生成障碍物,先定义好若干障碍物的prefab,每次生成时随机一个index,然后从prefab数组中读取要生成的障碍物,再从两个配置数组:spawnPoints、isNeedOffset中分别读取spawn的位置和是否需要上下的偏移。

game loop

游戏开始前先显示主菜单,并用Time.timeScale = 0来冻结场景,点击开始游戏后进入swipe界面,可以左右滑动选择照片(不影响关卡内容),点击确定后播放一段显示“like”的动画,在动画结束时执行一个事件,开启教学菜单,然后按空格开始游戏。

游戏开始后,每装上一个障碍物就扣一滴血,变更ui表现,如果血量为0,那么trigger死亡动画,然后进入GameOver界面,显示总分,点击回到主菜单。每次关卡载入都是对场景reload,只是reload时会根据当前关卡计算主角的移动速度,关卡越高速度越快,速度基数和涨幅在GM中控制。

待优化

  • 很多需要用到回调函数的地方都用Coroutine实现了,这样其实并不优雅,应该使用C#的delegate注册专门的回调函数来实现
  • swipe界面和关卡没有建立联系
  • 跳跃手感可以优化一下,目前的实现只是一个addforce,可以改成根据按下的时间决定跳跃的高度
  • 一些可以用响应回调的地方强行用update或Coroutine隔段时间检测一下,不优雅

Debug日志

  1. StopCoroutine没有停止之前的coroutine

原因是之前调用StartCoroutine时传进去的是方法而不是方法名称的字符串,这样StopCoroutine会无法识别。也可以在start时存储coroutine的实例,然后stop的时候直接将这个实例传进去。

  1. 主角多个collider重复触发damage

Comments

Content