我正在制作一个iOS游戏,一个盒子会在跳跃时旋转(像这样:http://www.lessmilk.com/games/3/)。我尝试了很多方法,其中一个似乎可以接受:
触摸开始时,我运行此代码:
[_box.physicsBody applyImpulse:ccp(0, 5000)];
CCActionRotateBy *r2 = [CCActionRotateBy actionWithDuration:0.9f angle:360.f];
CCActionSequence *moveSequence = [CCActionSequence actionWithArray:@[r2]];
[_box runAction:moveSequence];
这是相当不错的,但后来我发现存在性能问题。由于未知原因,当盒子在空中并且它正在旋转时,框架似乎减少了(或者我觉得因为动画不顺畅)。
有谁知道问题是什么或有更好的想法来实现这个? 谢谢,
答案 0 :(得分:3)
由于您的精灵与物理相关联,并且您正在为精灵运动应用线性脉冲。因此,您可以尝试使用物理旋转精灵,而不是使用动画来旋转精灵。尝试将角速度应用于精灵:
_box.physicsBody.angularVelocity = someConstantValue;
我希望你能获得更好的表现和顺畅。
答案 1 :(得分:2)
通常情况下,你不希望你的精灵都是由物理和直接操纵驱动的。你基本上是用物理引擎来控制精灵。
你可能会考虑,而不是将物理学应用于盒子,只需要进行常规帧更新来移动和旋转精灵,而不是尝试混合物理和动作。大多数物理引擎都有办法让物理对象像木偶一样移动,并且仍然可以正确地触发碰撞,但不是由物理引擎直接控制。考虑一下,你可能会有更好的结果。
编辑:
为了实现你想要的动作,我要做的就是直接使用update()函数动画(或者Cocos2D等效的任何东西 - 我现在对SpriteKit更熟悉)。 (下面未经测试的代码。)
你想要以点/秒为单位的常量x速度开始,比方说,100。在你的update()函数中,你获取自上次update()函数以来的增量,以秒为单位,并将其乘以获得x位置变化的速度:
float newX = oldX + delta * xVelocity;
要进行跳跃,你需要保持一个“isJumping”BOOL,如果是,则添加一个抛物线Y距离并旋转该框。这样做的简单方法是在你希望跳跃的任何X距离上从0到1斜坡上升,并将其映射到抛物线运动上。
float newY = 0; // zero is the ground plane
if (self.isJumping) {
self.jumpRamp += delta * xVelocity / jumpLength;
if (self.jumpRamp > 1.0) {
self.zRotation = self.jumpRamp * M_PI;
// Map the jump ramp onto (-1,1), and then square it to get parabolic motion
// Since the jump ramp goes from (0,1), we subtract .5 and multiply by 2
// to get a range from (-1, 1). Then we square that.
float parabolic = ((self.jumpRamp - .5) * 2) * (self.jumpRamp - .5) * 2));
// This yields (0,1), with the parabola pointing up. We need to
// invert it, scale it, and move it up so the end points are on the "floor".
newY = self.maxJumpHeight * (1.0 - parabolic);
} else {
self.isJumping = NO;
self.zRotation = 0;
self.jumpRamp = 0;
}
}
现在你有你想要的动作。剩下的就是碰撞检测,您可以使用与之前完全相同的方式进行碰撞检测。只需断开盒子与物理学的驱动(看起来,使用Box2D,你会使用“运动”身体而不是“动态”身体)。您仍然可以像以前一样获得碰撞消息,但是您将直接控制框的行为,而不是依赖于物理或动作。