小游戏联机对战引擎之帧同步(四)

最近,有小伙伴在后台留言,让我赶紧更新帧同步。这几天因为有其他事情,所以一直没更新。

于是乎,周末这两天,赶紧撸起代码来,把子弹的同步和碰撞检测加了上去。好友拉我开黑都把他无情的拒绝了。

先说下我的思路吧。本来,我想着战斗时,右摇杆点击之后就一直发射子弹,间隔0.2秒发射一次,只要控制方向就可以了。但是,通过schedule和interval实现之后,发现效果不是太理想。然后,我又改造了一下interval,想实现类似于引擎的update驱动那样,然后通过手动累加时间,每到0.2秒就触发一次发射,写完之后,感觉效果倒是还可以。但是,到真机上测试,不知道为什么,真机上不显示连续发射的子弹。

于是,最终我放弃了这种方式。改为每次松开摇杆时,发射一颗子弹。我之前玩过一款对战小游戏就是这样做的,不过是,我这没有加瞄准线,这个后期可以再加。效果视频如下。(interval实现的代码被我注释了,以后再研究)

然后说下,子弹同步的思想。逻辑层每个玩家类下都维护了一个子弹类的数组,然后每一帧计算出所有子弹的位置信息。表现层,也维护了一个子弹类的数组用于和逻辑层一一对应。


需要注意的是,两个数组的顺序一定要保证一致,不然子弹会错乱。这个实现方法,是在逻辑层把需要销毁的子弹先delete,也就是子弹对象置为undefined,这样不会改变数组的长度,然后在表现层再同步删除子弹数组中所有undefined的对象。

子弹的位置,是以地图map节点为父节点计算出来的位置。因为,玩家的坦克父节点也是map,这样计算碰撞时比较方便。但是,需要注意的是,逻辑层是在每一帧时计算的位置,子弹位置和坦克位置之间是有偏移量的。由于坦克位置是不连续的,因此子弹位置也是不连续的。所以,不能在表现层直接设置子弹位置,因为,表现层的坦克位置是插值来的。因此,需要在表现层用当前插值后的坦克位置加上这个偏移量。代码在Hero.ts的copyBullets方法下。

表现层所有子弹都是只给初始位置,然后通过引擎update自动计算每个子弹的后续位置。因为,我发现如果用插值计算子弹位置,子弹前进过程中会一卡一卡的。

关于碰撞检测,需要在逻辑层维护一个坦克和子弹的大小,即宽高。然后遍历所有敌方未死亡的坦克,判断子弹是否和敌方坦克相交。

刚开始我是在逻辑层做计算,检测到碰撞之后,在表现层同步的删除子弹对象,然后把子弹节点也销毁。但是,多次测试发现,画面呈现的是,子弹会提前或者延后销毁。也就是子弹还没走到坦克的位置就已经不见了,或者是子弹已经穿出了坦克还没被销毁。

因此,最后,我在表现层也做了一个碰撞检测。这个只是为了让玩家的画面看起来不会那么奇怪。(明明子弹碰到了敌方坦克,为什么子弹还在。)实际计算伤害时,还是以逻辑层为准。伤害计算后续更新。

代码已经在gitee仓库更新了,小伙伴们可以自行下载。(建议加星,或者建立本地仓库连接,pull代码更方便。)

点击留言

扫描二维码

获取更多精彩

如若清风

关注公众号,回复666666

 即可领取学习大礼包

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值