使用SpriteBuilder制作Cocos2D游戏完全中文教程(九)

打磨我们的游戏(Polish Gameplay)

目前玩家只能发射一次,摄像头会跟着企鹅飞,但不会回滚到弹射器,接下来我们尝试完成这些功能。该规则将执行以下操作:如果一个企鹅从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!谢谢大家!


你可能感兴趣的:(ios,cocos2d,Spritebuilder)