(NO.00004)iOS实现打砖块游戏(十二):伸缩自如,我是如意金箍棒(上)!

通用的星星类已经完成了,下面我们来实现具体的变长和缩短道具.

变长的反弹棒

我们想实现如下功能:在掉落变长星之后,如果反弹棒接到它,则使反弹棒的长度变为原先的2倍.

看似很简单,但实际有一个问题.你不能仅仅延长反弹棒精灵纹理的长度,因为你在这个游戏中使用的是物理引擎,反弹棒的物理对象的大小是不可以在游戏运行中随意变化的.

所以我们需要想办法延长反弹棒的物理大小,当然同时也要延长其精灵帧的大小,这样才能相互配合达到逼真的延长效果.

这里本猫使用偷梁换柱的方法,用Ai制作一个延长后的反弹棒,并调整它的物理对象适应新的长度,然后在反弹棒需要变长时,用新长棒代替原来的短棒.

首先用Ai制作一个长的反弹棒.然后在SpriteBuilder中创建一个StickLonger.ccb文件,设置好其物理对象的边界:

实现变长星道具

回到Xcode中,在Stick类的接口文件中添加一个新属性:

+(instancetype)stickLonger;

在Stick.m中实现该类方法:

+(instancetype)stickLonger{Stick *stick = (Stick*)[CCBReader load:@”Elements/StickLonger”];stick.name = @”stickLonger”;return stick;}

可以看到除了stick对象发生了变化,其名称也和普通的stick有所区别.

回到GameScene.m中在小球与砖块的碰撞处理中添加以下一句:

[Star spawnStar:(Brick*)brick];

接着我们要处理星星和反弹棒接触时的事件:

-(BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair star:(CCNode *)starstick:(CCNode *)stick{//star形状是五角星,可能会在短时间内多次发生碰撞;但在star已经由第一次碰撞时删除掉从而导致star为nil//所以这里要确保star不为nil.//star删除也不能保证其一定为nil,所以增加判断其parent是否为nil.(2015-11-09 2006)StarType starType;@synchronized(self){if (!star || !star.parent) {return YES;}starType = ((Star*)star).starType;[star removeFromParentAndCleanup:YES];}switch (starType) {case starTypeStickLonger:@synchronized(self){[self scheduleBlock:^(CCTimer *timer){[Star doStickLongerWork:self.stickInGameScene];} delay:0];}break;case starTypeUnknown:case starTypeMax:NSAssert(NO, @”error star type!”);break;default:break;}return YES;}

为什么其中使用了同步伪指令呢?因为其中的代码会改变GameScene中反弹棒的状态,而该状态在GameScene中也可能同时被改变,所以我们需要将其做同步处理.

扩展Star类

最后我们在Star类中添加doStickLongerWork方法:

+(void)doStickLongerWork:(Stick *)stick{GameScene *gameScene = [GameScene sharedGameScene];CCPhysicsNode *physicsWorld = (CCPhysicsNode*)stick.parent;@synchronized(gameScene){if ([stick.name isEqualToString:@”stickLonger”]) {return;}if ([stick.name isEqualToString:@”stickShorter”]) {Stick *stickNormal = [Stick stickNormal];stickNormal.position = stick.position;[stick removeFromParent];//[physicsWorld removeChild:stick cleanup:YES];[physicsWorld addChild:stickNormal];gameScene.stickInGameScene = stickNormal;return;}}CGPoint position = stick.position;__block Stick *stickLonger;@synchronized(gameScene){stickLonger = [Stick stickLonger];//[physicsWorld removeChild:stick cleanup:YES];[stick removeFromParent];stickLonger.position = position;[physicsWorld addChild:stickLonger];stickLonger.visible = NO;gameScene.stickInGameScene = stickLonger;CCSprite *stickNode = (CCSprite*)[CCBReader load:@”Elements/StickNode”];stickNode.position = stickLonger.position;[gameScene addChild:stickNode z:50];CCActionScaleTo *longerAction = [CCActionScaleTo actionWithDuration:0.4f scaleX:2.0f scaleY:1.0f];CCActionCallBlock *blk = [CCActionCallBlock actionWithBlock:^{[stickNode removeFromParent];stickLonger.visible = YES;}];CCActionSequence *seq = [CCActionSequence actions:longerAction,blk,nil];[stickNode runAction:seq];}[stickLonger scheduleBlock:^(CCTimer *timer){@synchronized(gameScene){Stick *stickNormal = [Stick stickNormal];stickNormal.position = stickLonger.position;[stickLonger removeFromParent];[physicsWorld addChild:stickNormal];gameScene.stickInGameScene = stickNormal;}} delay:10];}

你看到以上方法的第一感觉估计是:好长啊!其实内容很好理解,基本上它做了如下几件事:

如果反弹棒已经变长了,则啥也不做返回

如果反弹棒处在变短状态,则恢复其原本大小.这里考虑到了其他可能改变反弹棒的叠加效果.在反弹棒变短的代码逻辑中,我们同样会考虑到这一点.

往事是尘封在记忆中的梦,而你是我唯一鲜明的记忆,

(NO.00004)iOS实现打砖块游戏(十二):伸缩自如,我是如意金箍棒(上)!

相关文章:

你感兴趣的文章:

标签云: