3D战斗游戏之运动模式准备篇2

2015年03月17日 10:44 0 点赞 0 评论 更新于 2017-04-27 12:11

参考:3D战斗游戏之运动模式准备篇1

在上一篇文章中,我们提到Cocos2d尚未支持3D运动,因此通过更改引擎代码的方式,自行实现了MoveTo3DMoveby3D。然而,这种方法较为激进,并非所有开发者都愿意对引擎代码进行修改,即便该引擎是开源的。在本文中,我们将介绍一种相对温和的实现方式。

实现原理

Cocos依靠update事件来逐帧刷新屏幕。要将一个物体从A点移动到B点,只需在两点间构建一条直线,并将其分割成若干小段,使物体每帧移动一小段距离。利用这种方法,无论是2D还是3D的移动都能够实现。

代码实现

假设存在一个bulletSprite精灵,并且已经为其pTargetPospSpeed进行了赋值,例如pTargetPos = Vec3(100, 100, -1000)pSpeed = 100.0f。以下是实现物体移动的代码:

Vec3 curPos = bulletSprite->getPosition3D();
Vec3 newFaceDir = pTargetPos - curPos;
newFaceDir.normalize();
Vec3 offset = newFaceDir * pSpeed * dt; // 当前点到目标点的距离矢量 * 速度 * 每帧时间 = 移动距离
curPos += offset;
bulletSprite->setPosition3D(curPos);

将上述代码放置在场景的update函数中,在每帧刷新时,程序会计算出该帧bulletSprite向着目标点的位移量,并重新设置其位置。在屏幕上呈现的效果就是子弹射向pTargetPos点。

代码封装与优势

这段代码可以进行封装,并通过schedule或者update方法进行调用,实现起来并不复杂,这里就不再赘述。这种实现方式的最大优势在于,子弹每帧的偏移量offset是实时计算的,因此可以轻松实现子弹的非直线飞行,例如让子弹呈鸟状、抛物线状等多种形态飞行。

参考示例

在上一篇文章中,有朋友提到《FantasyWarrior3D》中实现了3D子弹飞行效果。实际上,该游戏正是采用每帧计算子弹位置的方式来实现的。有兴趣的读者可以查看其AttackCommand.lua文件中的solveAttacks(dt)ArcherNormalAttack:onUpdate(dt)函数,下面是ArcherNormalAttack:onUpdate(dt)函数的代码片段供参考:

function ArcherNormalAttack:onUpdate(dt)
local selfPos = getPosTable(self)
local nextPos = cc.pRotateByAngle(cc.pAdd({x=self.speed*dt, y=0},selfPos),selfPos,self.facing)
self:setPosition(nextPos)
end

作者信息

boke

boke

共发布了 1025 篇文章