IOS - 在Cocos2d中使用CCCallBlock,小行星游戏

时间:2014-08-02 10:50:15

标签: ios objective-c cocos2d-iphone

游戏允许用户控制船只并击落小行星,当小行星被激光击中时我显示爆炸,但我需要爆炸在1秒后消失。所以我在Cocos2d中使用了CCCallBlock,但是块似乎没有激发内部方法:

        for(int i = 0; i < fireArray.count; i++){

        CCSprite *fire = [fireArray objectAtIndex:i];

        for(int j = 0; j < asteroidArray.count; j++){
            CCSprite *asteroid = [asteroidArray objectAtIndex:j];


            if (CGRectIntersectsRect(fire.boundingBox, asteroid.boundingBox)) {

            CCSprite *explode = [[CCSprite alloc] initWithFile:@"explode.png"];
            [explode setPosition:ccp([asteroid position].x, [asteroid position].y)];
            CGSize imageSize = explode.contentSize;
            [self addChild:explode];

            [self runAction:[CCSequence actions:[CCDelayTime actionWithDuration:1],
                     [CCCallBlock actionWithBlock:^
                        {
                        [self removeExpode:explode];
                        }], Nil]];

            //[self stopAllActions];

            [explodeDeleteArray addObject:explode];
            [asteroidDeleteArray addObject:asteroid];
            }



        }

        }



    -(void)removeExpode:(CCSprite *)explodeObj{

        [explodeObj removeFromParentAndCleanup:YES];
    }

更新

我创建了Explode自定义Sprite但是init似乎永远不会触发,因为NSLog没有打印出来&#34; new explode&#34;所以这意味着永远不会被召唤的时间让爆炸消失:

                //
    //  Explode.m
    //  Asteroids
    //
    //  Created by trikam patel on 02/08/2014.
    //  Copyright 2014 trikam patel. All rights reserved.
    //

    #import "Explode.h"


    @implementation Explode


    // on "init" you need to initialize your instance
    -(id) init
    {
        if( (self=[super init]) ) {

        NSLog(@"new explode");
        NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1
                                  target:self
                                selector:@selector(removeExplode)
                                userInfo:nil
                                 repeats:YES];


        }
        return self;
    }


    -(void)removeExplode{

        NSLog(@"removeExplode");
        [self removeFromParentAndCleanup:YES];

    }

    @end


    if (CGRectIntersectsRect(fire.boundingBox, asteroid.boundingBox)) {

            Explode *explode = [[Explode alloc] initWithFile:@"explode.png"];
            [explode setPosition:ccp([asteroid position].x, [asteroid position].y)];
            [self addChild:explode];

            [asteroidDeleteArray addObject:asteroid];
    }

更新

代码现在似乎有效:

                        //
        //  Explode.m
        //  Asteroids
        //
        //  Created by trikam patel on 02/08/2014.
        //  Copyright 2014 trikam patel. All rights reserved.
        //

        #import "Explode.h"


        @implementation Explode


        // on "init" you need to initialize your instance
        -(id) init
        {
            if( (self=[super init]) ) {

            [super initWithFile:@"explode.png"];

            [self schedule:@selector(removeExplodeShedule:) interval:1];

            }
            return self;
        }

        -(void)removeExplodeShedule:(ccTime)res{

            [self removeFromParentAndCleanup:YES];

            [self unschedule:@selector(removeExplodeShedule:)];

        }

        @end

1 个答案:

答案 0 :(得分:1)

您正在使用Apple specifically advise you avoid的模式(请参阅要避免的模式部分)。

有一个建议(在这个网站上),解决方法是复制块,但我认为你最好将行为构建到爆炸对象中:

  • 创建一个新的Explosion对象,它是CCSprite
  • 的子类
  • Explosion对象的大部分初始化移动到其中;除了设定其位置之外的所有人。
  • 同样在[Explosion init]方法中,安排1秒计时器将其自身从父级中删除。

这是一个更好的模式,允许在该对象中定义对象的行为;但是如果需要,您可以影响它(例如,您可以将timeToRemove值作为init的参数传递。欢迎来到面向对象:)