代码之家  ›  专栏  ›  技术社区  ›  redoc01

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

  •  0
  • redoc01  · 技术社区  · 10 年前

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

            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不会打印出“新爆炸”,所以这意味着永远不会调用时间来使爆炸消失:

                    //
        //  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 回复  |  直到 10 年前
        1
  •  1
  •   Droppy    10 年前

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

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

    • 创建新的 Explosion 对象,它是 CCSprite .
    • 移动 爆炸 反对加入其中;除了设置其位置之外,其他都是。
    • 也在 [Explosion init] 方法,调度一个1秒计时器将其从父级中删除。

    这是一种更好的模式,允许在该对象中定义对象的行为;但是,如果您愿意,您可以影响它(例如,您可以通过 timeToRemove 值作为参数 init ). 欢迎使用对象定向:)