你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> (NO.00004)iOS實現打磚塊游戲(十二):伸縮自如,我是如意金箍棒(上)!

(NO.00004)iOS實現打磚塊游戲(十二):伸縮自如,我是如意金箍棒(上)!

編輯:IOS開發綜合

大熊貓豬·侯佩原創或翻譯作品.歡迎轉載,轉載請注明出處.
如果覺得寫的不好請告訴我,如果覺得不錯請多多支持點贊.謝謝! hopy ;)


通用的星星類已經完成了,下面我們來實現具體的變長和縮短道具.

變長的反彈棒

我們想實現如下功能:在掉落變長星之後,如果反彈棒接到它,則使反彈棒的長度變為原先的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 *)star
                         stick:(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];
}

你看到以上方法的第一感覺估計是:好長啊!其實內容很好理解,基本上它做了如下幾件事:

如果反彈棒已經變長了,則啥也不做返回 如果反彈棒處在變短狀態,則恢復其原本大小.這裡考慮到了其他可能改變反彈棒的疊加效果.在反彈棒變短的代碼邏輯中,我們同樣會考慮到這一點. 創建一個變長的反彈棒對象,但暫時將其隱藏,因為我們還想實現一個反彈棒由短變長的動畫效果.因為這個動畫很短,所以不會影響用戶的操控.如果你希望更完美的實現用戶操控的連續性,你可以將反彈棒的觸摸處理臨時”嫁接”到這個臨時對象上,當然是有點麻煩,篇幅原因,這裡只是點到為止. 在10秒之後將反彈棒恢復為原來大小

變長道具制作完畢,我們現在編譯運行app,看一下效果:

這裡寫圖片描述

 

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved