COCOS2D - 删除与另一个精灵碰撞的子项

时间:2014-03-01 02:36:13

标签: cocos2d-iphone

我正在开发一款让玩家控制太空船的游戏。我想这样做,如果spaceShip精灵与spaceJunk发生碰撞,垃圾就会消失。

到目前为止,这是我的代码。

HelloWorldLayer.h

 #import <GameKit/GameKit.h>


   // HelloWorldLayer
   @interface HelloWorldLayer : CCLayerColor
{
CCSprite *_starShip;
CCSprite *_Paddle1;
CCSprite *_paddle2;

}

// returns a CCScene that contains the HelloWorldLayer as the only child
+(CCScene *) scene;

@end

HelloWorldLayer.M

// Import the interfaces
#import "HelloWorldLayer.h"

// Needed to obtain the Navigation Controller
#import "AppDelegate.h"

#pragma mark - HelloWorldLayer

// HelloWorldLayer implementation

//Import SpaceThings

#import "SpaceThings.h"

@implementation HelloWorldLayer{

}


// Helper class method that creates a Scene with the HelloWorldLayer as the only child.
+(CCScene *) scene
{
    // 'scene' is an autorelease object.
    CCScene *scene = [CCScene node];

    // 'layer' is an autorelease object.
    HelloWorldLayer *layer = [HelloWorldLayer node];

    // add layer as a child to scene
    [scene addChild: layer];

    // return the scene
    return scene;
}

-(void)gameLgoic:(ccTime)dt
{
    [self addSpaceThings];
}


-(void) addSpaceThings
{
   // _junk = [CCSprite spriteWithFile:@"catplaceholder.png"];

    SpaceThings * spaceThings = nil;

    if (arc4random() % 2 == 0){
        spaceThings = [[[Astroids alloc] init] autorelease];
    }else{
        spaceThings = [[[SpaceJunk alloc]init] autorelease];

    }

    //determine where to spawn the space junk along the X-axis
    CGSize winSize = [CCDirector sharedDirector].winSize;
    int minX = spaceThings.contentSize.width/2;
    int maxX = winSize.width - spaceThings.contentSize.width/2;
    int rangeX =maxX - minX;
    int actualX = (arc4random() % rangeX) + minX;


    //spawn the sprite slightly above the screen
    spaceThings.position = ccp(actualX, winSize.height+_starShip.contentSize.height/2);
    [self addChild:spaceThings];

    //set the speed of junk
    int minDuration = spaceThings.minMoveDirection;
    int maxDuarton = spaceThings.maxMoveDirection;
    int rangeDuration = maxDuarton - minDuration;
    float actualDuraton = (arc4random() % rangeDuration)+ minDuration;

    //move junk logic
    CCMoveTo * actionMove = [CCMoveTo actionWithDuration:actualDuraton position:ccp(actualX, -spaceThings.contentSize.height/2)];
    CCCallBlockN *actionMoveDone = [CCCallBlockN actionWithBlock:^(CCNode *node){[node removeFromParentAndCleanup:YES];}];
    [spaceThings runAction:[CCSequence actions:actionMove, actionMoveDone, nil]];

    if (CGRectIntersectsRect(_starShip.boundingBox, spaceThings.boundingBox)){
        [self removeChild:spaceThings cleanup:YES];

    }




}

// on "init" you need to initialize your instance
-(id) init
{
    if (self =[super initWithColor:ccc4(255,255,255,255)]){
        CGSize winSize = [CCDirector sharedDirector].winSize;
        _starShip = [CCSprite spriteWithFile:@"theShip.gif"];
        _starShip.position = ccp(winSize.width/2, 1.25*_starShip.contentSize.height);
        //make the starship appear
        [self addChild:_starShip];

        //make the paddles
        //bottom left one
        _Paddle1 = [CCSprite spriteWithFile:@"spritePaddle.jpeg"];
        int bottomOfScreenX = 0 + _Paddle1.contentSize.width/2;
        int bottomOfScreenY = 0+_Paddle1.contentSize.height/2;
        _Paddle1.position = ccp(bottomOfScreenX,bottomOfScreenY);
        [self addChild:_Paddle1];
        //bottom right one
        _paddle2 = [CCSprite spriteWithFile:@"spritePaddle.jpeg"];
        int bottomRightOfScreenX = winSize.width - _paddle2.contentSize.width/2;
        _paddle2.position = ccp(bottomRightOfScreenX, bottomOfScreenY);
        [self addChild:_paddle2];


        //make thingsInSpace spawn at a set interval

        int setInterval = (arc4random() % 3);
        [self schedule:@selector(gameLgoic:) interval:setInterval];
        //enable touch
        [self setIsTouchEnabled:YES];



    }
    return self;
}

// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
    // in case you have something to dealloc, do it in this method
    // in this particular example nothing needs to be released.
    // cocos2d will automatically release all the children (Label)

    // don't forget to call "super dealloc"
    [super dealloc];

}

-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    //make the screens and create events
    CGSize winSize = [CCDirector sharedDirector].winSize;
    NSSet *allTouches = [event allTouches];
    UITouch *touch = [allTouches anyObject];
    CGPoint location = [touch locationInView:[touch view]];
    location = [[CCDirector sharedDirector] convertToGL:location];

    //check to see if the left paddle is being pressed
    if (CGRectContainsPoint([_Paddle1 boundingBox], location)){
         int bottomLeftOfScreenX = 0 + _Paddle1.contentSize.width/1.25;
        //make an action
        //the Y-coordinate of starShip must be the same since the ship must move parallel to it.
       id action = [CCMoveTo actionWithDuration:2 position:ccp(bottomLeftOfScreenX,1.25*_starShip.contentSize.height) ];
        //have starship call this action
        [_starShip runAction:action];
        [action setTag:1];

    }
    //check to see if the right paddle is being pressed
    if (CGRectContainsPoint([_paddle2 boundingBox], location)){
        int bottomRightOfScreenX = winSize.width - _paddle2.contentSize.width/1.25;
        //make an action
        //the Y-coordinate of starShip must be the same since the ship moves parallel to it
        id action2 = [CCMoveTo actionWithDuration:2 position:ccp(bottomRightOfScreenX,1.25*_starShip.contentSize.height) ];
        //starShip is now running this specified action
        [_starShip runAction:action2];
        [action2 setTag:2];
    }


}

-(void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
   //if the player stops touching the pads, all the aciton should stop.

    //left button stop
    [_starShip stopActionByTag:1];
    //right button stop
    [_starShip stopActionByTag:2];

}

#pragma mark GameKit delegate

-(void) achievementViewControllerDidFinish:(GKAchievementViewController *)viewController
{
    AppController *app = (AppController*) [[UIApplication sharedApplication] delegate];
    [[app navController] dismissModalViewControllerAnimated:YES];
}

-(void) leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController
{
    AppController *app = (AppController*) [[UIApplication sharedApplication] delegate];
    [[app navController] dismissModalViewControllerAnimated:YES];
}
@end

spaceThings.h

#import <Foundation/Foundation.h>
#import "cocos2d.h"

@interface SpaceThings : CCSprite
@property (nonatomic, assign) int minMoveDirection;
@property (nonatomic, assign) int maxMoveDirection;

-(id)initWithFile:(NSString *)file minMoveDirection:(int)minMoveDirection maxMoveDirection:(int)maxMoveDirection;

@end

@interface Astroids : SpaceThings
@end

@interface SpaceJunk : SpaceThings
@end

SpaceThings.M

#import "SpaceThings.h"


@implementation SpaceThings

-(id)initWithFile:(NSString *)file minMoveDirection:(int)minMoveDirection maxMoveDirection:(int)maxMoveDirection
{
    if ((self =[super initWithFile:file])){
    self.minMoveDirection = minMoveDirection;
    self.maxMoveDirection = maxMoveDirection;
    }
    return self;
}

@end

@implementation Astroids

-(id)init
{
    if (self = [super initWithFile:@"astroid.jpeg" minMoveDirection:2 maxMoveDirection:5]){

    }
    return self;
}

@end

@implementation SpaceJunk
-(id)init
{
    if (self = [super initWithFile:@"blueDot.jpg" minMoveDirection:4 maxMoveDirection:7]){

    }
    return self;
}


@end   

我想知道CGRectInteresectRect部分代码的放置位置。正如我目前尝试放置在SpaceJunk alloc init部分中,并且当船与垃圾碰撞时它不会移除子。

1 个答案:

答案 0 :(得分:1)

    int setInterval = (arc4random() % 3);
    [self schedule:@selector(gameLgoic:) interval:setInterval];

使setInterval值浮动并为调度程序赋予小值。

也不要在循环内部[spaceThings runAction。如果需要,则进行一些条件检查并仅在需要时运行。

然后你的CGRectIntersectsRect会在相互交叉时触发。

快乐编码。