目前玩家只能发射一次,摄像头会跟着企鹅飞,但不会回滚到弹射器,接下来我们尝试完成这些功能。该规则将执行以下操作:如果一个企鹅从Level的左侧或右侧离开,或者如果它以非常慢的速度移动,我们将触发下一个(企鹅)尝试启动。
实现更新方法
在我们实际执行的更新方法之前我们在Gameplay.m中添加一个常数定义,我们将用它来 检查是否有企鹅以很慢的最低速度来结束(移动):
static const float MIN_SPEED = 5.f;
该值为'5'能在我们的物理环境中良好的工作。如果您更改了对象的物理属性,你可能想试验一下这个值。现在我们可以实现update方法。此方法由cocos2d的每一帧自动调用:
- (void)update:(CCTime)delta { // if speed is below minimum speed, assume this attempt is over if (ccpLength(_currentPenguin.physicsBody.velocity) < MIN_SPEED){ [self nextAttempt]; return; } int xMin = _currentPenguin.boundingBox.origin.x; if (xMin < self.boundingBox.origin.x) { [self nextAttempt]; return; } int xMax = xMin + _currentPenguin.boundingBox.size.width; if (xMax > (self.boundingBox.origin.x + self.boundingBox.size.width)) { [self nextAttempt]; return; } }
首先当这可能看起来有点复杂的时候,这其实只是数学的一点点。我们将检查速度是否低于我们定义的限制。因此,我们使用ccpLength函数计算平方长度我们的点(基本上在x和速度相结合的y分量)。再者,我们检查企鹅是否已经出了Level的左或右边界,如果出界,则立即调用nextAttempt方法并立即返回(以避免nextAttempt被多次调用)。
实现nextAttempt方法
我们需要做的最重要的事情是在nextAttempt方法中滚动回弹射器。然而,因为我们已经在运行一个动作跟随企鹅,我们需要在启动另一个滚动的动作之前停止这个动作(否则cocos2d会混淆这两个相互矛盾的指示)。
Cocos2D中提供了一个可被任何的CCNode调用的名为stopAction的方法。然而,我们需要一个引用(变量)来停止动作。所以,第一步应该创建一个新的成员变量:
@implementation Gameplay { ... CCAction *_followPenguin; }
然后修改releaseCatapult的代码将滚动动作分配给这个新创建的变量:
// follow the flying penguin _followPenguin = [CCActionFollow actionWithTarget:_currentPenguin worldBoundary:self.boundingBox]; [_contentNode runAction:_followPenguin];
现在,我们已经准备好实现nextAttempt方法!将此方法添加到Gameplay.m中:
- (void)nextAttempt { _currentPenguin = nil; [_contentNode stopAction:_followPenguin]; CCActionMoveTo *actionMoveTo = [CCActionMoveTo actionWithDuration:1.f position:ccp(0, 0)]; [_contentNode runAction:actionMoveTo]; }
首先,我们重置_currentPenguin引用,因为一旦尝试完成后,我们认为当前没有企鹅。然后我们停止滚动动作。最后,我们创建一个新的动作往回滚动到弹射器。
现在我们几乎已经完成了,你应该已经能够使用测试功能了。运行你的游戏,并确认一切都如预期。
更多的只是一个优化
你可能已经意识到,当前存在一个需要解决的潜在问题:假设玩家拉回弹射器非常慢,那么下一个尝试可以会在当前企鹅发射之前被触发。
为了避免这种情况发生,我们将为企鹅添加一个标志来存储它是否已经被发射。打开Penguin.h并添加这个属性:
@property (nonatomic, assign) BOOL launched;
要在Gameplay.m访问这个新的属性我们需要加入这一行到文件的顶部来导入企鹅头:
#import "Penguin.h"
并改变成员变量_currentPenguin为企鹅类型代替CCNode:
Penguin *_currentPenguin;
现在,您还必须更改在touchBegan方法那里的企鹅的加载,因为CCBReader只返回CCNodes,所以这里需要进行类型转换:
_currentPenguin = (Penguin*)[CCBReader load:@"Penguin"];
现在我们已经接收了发射企鹅的属性,我们可以添加一个检查到更新方法中,使得在企鹅已经发射的情况下才执行:
- (void)update:(CCTime)delta { if (_currentPenguin.launched) { ... // <- all previous content of this method belongs inside of this if-statement } }
现在,所有的检查只会在企鹅发射后进行。
作为最后一步,我们需要在企鹅被发射后设置launched标志为TRUE。因此,在releaseCatapult方法中添加以下代码:
_currentPenguin.launched = TRUE;
这样我们的优化就完成了!!
原文:
https://www.makegameswith.us/tutorials/getting-started-with-spritebuilder/improve-gameplay/
此致,我们的教程也全部讲完了。希望大家在学习的时候多多交流与分享!转载请说明出处,wealpan将和您一起学习Spritebuilder,一起学习cocos2D!谢谢大家!