【问题标题】:Simple collision detection in cocos2d box2d..nothing happens on collisioncocos2d box2d中的简单碰撞检测..碰撞没有发生
【发布时间】:2012-02-11 15:48:32
【问题描述】:

我正试图弄清楚如何做到这一点,我有一个名为“玩家”的精灵和名为“摇滚”的精灵 我正在尝试检测两个精灵之间的碰撞......但碰撞时没有任何反应!

这是我所做的:

-(void)addRock {

rock = [CCSprite spriteWithFile:@"rock.png" 
                                     rect:CGRectMake(0, 0, 27, 40)]; 

// Determine where to spawn the target along the X axis
CGSize winSize = [[CCDirector sharedDirector] winSize];
int minX = rock.contentSize.width/2;
int maxX = winSize.width - rock.contentSize.width/2;
int rangeX = maxX - minX;
int actualX = (arc4random() % rangeX) + minX;
// Create the target slightly off-screen along the right edge,
// and along a random position along the X axis as calculated above
rock.position = ccp(actualX, 500);
rock.tag = 1;
[rockArray addObject:rock];
[self addChild:rock];

播放器代码如下:

-(id) init{
if( (self=[super initWithColor:ccc4(255, 255, 255, 255)] )) {
    CGSize winSize = [[CCDirector sharedDirector] winSize];
    player = [CCSprite spriteWithFile:@"Player.png" 
                                           rect:CGRectMake(0, 0, 27, 40)];
    player.position = ccp(winSize.width/2, winSize.height/4+15); //position of where the player is placed
    player.tag = 2;
    [playerArray addObject:player];
    [self addChild:player];

精灵移动完成:

-(void)spriteMoveFinished:(id)sender {


CCSprite *sprite = (CCSprite *)sender;
[self removeChild:sprite cleanup:YES];

if (sprite.tag == 1) { // rock
    [rockArray removeObject:sprite];
} else if (sprite.tag == 2) { // players
    [playerArray removeObject:sprite];

init(数组初始化):

rockArray = [[NSMutableArray alloc]init];
    playerArray = [[NSMutableArray alloc]init];
    [self schedule:@selector(update:)];

更新方法

- (void)update:(ccTime)dt {


    NSMutableArray *rocksToDelete = [[NSMutableArray alloc] init];
    for (rock in rockArray) {
        CGRect rockRect = CGRectMake(
                                       rock.position.x - (rock.contentSize.width/2), 
                                       rock.position.y - (rock.contentSize.height/2), 
                                       rock.contentSize.width, 
                                       rock.contentSize.height);


    NSMutableArray *playersToDelete = [[NSMutableArray alloc] init];
    for (player in playerArray) {
        CGRect pRect = CGRectMake(

                                        player.position.x - (player.contentSize.width/2), 
                                        player.position.y -(player.contentSize.height/2), 
                                        player.contentSize.width,
                                        player.contentSize.height);

        if (CGRectIntersectsRect(rockRect, pRect)) {
            [rocksToDelete addObject:rock];
        }

        for (rock in rocksToDelete) {
            [rockArray removeObject:rock];
            [self removeChild:rock cleanup:YES];                                    
        }

        if (rocksToDelete.count > 0) {
            [playersToDelete addObject:player];
        }
        [rocksToDelete release];

        for (player in playersToDelete) {
            [playerArray removeObject:player];
            [self removeChild:player cleanup:YES];
        }
        [playersToDelete release];

我整晚都在努力解决我的问题。我似乎可以让碰撞检测工作。如果是这样,有人可以给我一个简短的代码吗?

【问题讨论】:

    标签: objective-c cocos2d-iphone collision-detection box2d-iphone


    【解决方案1】:

    要检查两个精灵之间的碰撞,您必须每帧(或您选择的频率)调用一个方法来检查是否发生了碰撞。 在 init 方法中添加以下代码:

    [self scheduleUpdate];
    

    ...这将在每一帧上调用以下方法(您必须添加到您的类实现中):

    -(void)update:(ccTime)delta {
       if (CGRectIntersectsRect(player.boundingBox, rock.boundingBox)) {
           //Do Stuff
       }
    }
    

    要使前面的代码正常工作,您必须将 Player 和 Rock sprite 声明为成员变量,以便可以在整个类中使用它们。

    如果场景中有多个岩石精灵要检查碰撞,则必须使用数组。快速示例:

    1 在你的类接口中声明一个数组:

    NSMutableArray *rockArray;
    

    2 在init方法中为它分配内存

    rockArray = [NSMutableArray array];
    

    3 在“addRock”方法中,将创建的岩石精灵添加到数组中,然后作为子元素添加到场景中

    -(void) addRock {
       CCSprite *rock = [CCSprite spriteWithFile:@"rock.png" 
                                         rect:CGRectMake(0, 0, 27, 40)];
       //...
    
       [rockArray addObject:rock];
       [self addChild:[rockArray lastObject]];
    }
    

    4 在“更新”方法中,您现在循环遍历数组并检查摇滚和播放器之间的碰撞

    for (CCSprite *_rock in rockArray) {
       if (CGRectIntersectsRect(player.boundingBox, rock.boundingBox)) {
               //Do Stuff e.g remove that rock from the scene
               [self removeChild:_rock cleanup:YES];
           }
    }
    

    希望这会有所帮助 ;-) 如有任何问题,请随时提出

    【讨论】:

    • 当我声明 CCSpriteplayer 和 CCSpriterock 时,我在 .m 文件中收到一条警告,上面写着“'player' 的本地声明隐藏了实例变量”,并且对于 rock
    • 我在 .h 文件中声明 CCSpriteplayer 和 CCSpriterock
    • 如果您在 .h 文件(接口)中声明变量,您可以通过实现(.m 文件)中的名称访问这些变量,例如player = [CCSprite spriteWith...];
    • 好的,我已经在实现中声明了CCSpriteplayer和CCSpriterock,在.m文件中我把它改成了player=[CCSprit...... ..] 并且效果很好....但是在更新方法的循环中,它说'rock'的本地声明隐藏了循环内'rock.boundingbox'和'removechild:rock'的实例变量跨度>
    • 嗨,我已经编辑了我上面的问题,我已经添加了我到目前为止所做的代码,它编译得很好,但是当两个对象碰撞时它什么也没有发生!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多