1

こんにちは、cocos2d ゲームで衝突検出に問題があります。弾丸がキャラクターに当たるかどうかをテストする必要があるゲームに取り組んでいます。CGRectIntersectsRect メソッドを使用して、衝突が発生するかどうかを確認しています。シミュレーターでは、弾丸がキャラクターの上を通過するのを見ることができますが、何も起こりません。弾が当たったらキャラクターが消えるようにしたいです。私のコードには、弾丸が文字に当たった場合に「COLLISION」を出力する CCLOG ステートメントがあります。また、箇条書きと文字の contentSize.width を出力する CCLOG ステートメントが他に 2 つあります。弾丸の contentSize.width は 20.0 である必要がありますが、幅が 0 として出力されることがあります。衝突検出のコードは次のとおりです。

-(void)testForBulletCollision:(ccTime)delta{
CCLOG(@"bullet.contentsize.width = %f",bullet.contentSize.width);
CCLOG(@"character.contentsize.width = %f",character.contentSize.width);
if (CGRectIntersectsRect([bullet boundingBox], [character boundingBox]))
{
    CCLOG(@"BULLET COLLISION");
    character.visible = NO;
    bullet.visible = NO;
}
}

キャラクター作成のコードはこちら。

character = [CCSprite spriteWithFile:@"mcharacter.png"];
    character.position = ccp(screenWidth/3.4, screenHeight/2 - 100);
    [self addChild:character z:-3];

弾丸と弾丸アニメーションを作成するためのコードを次に示します。

-(void)shootTheBullets:(ccTime)delta{
bullet = [CCSprite spriteWithFile:@"thebullet.png"];
bullet.color = ccRED;
bullet.position = redEnemy.position;
[self addChild:bullet z:-1];
bulletRect = CGRectMake(bullet.position.x - (bullet.contentSize.width/2),
                        bullet.position.y - (bullet.contentSize.height/2),
                        bullet.contentSize.width,
                        bullet.contentSize.height);


CCLOG(@"bullet.contentSize.width = %f", bullet.contentSize.width);
bulletMoveLeft = [CCMoveTo actionWithDuration:4.0 position:ccp(-screenWidth,       screenHeight/2)];
[bullet runAction:bulletMoveLeft];

[self schedule: @selector(stopBullets:)interval:18.0f/1.0f];
}

-(void)stopBullets:(ccTime)delta{
[self unschedule:@selector(shootTheBullets:)];
}

これが出力です。

2013-08-07 16:31:43.637 ザック アプリ[1320:a0b] bullet.contentsize.width = 0.000000 2013-08-07 16:31:43.638 ザック アプリ[1320:a0b] character.contentsize.width = 64.000000 2013- 08-07 16:31:43.638 ザック アプリ[1320:a0b] bullet.contentsize.width = 0.000000 2013-08-07 16:31:43.638 ザック アプリ[1320:a0b] character.contentsize.width = 64.000000 2013-08- 07 16:31:43.639 ザック App[1320:a0b] bullet.contentsize.width = 0.000000 2013-08-07 16:31:43.639 ザック App[1320:a0b] character.contentsize.width = 64.000000 2013-08-07 16 :31:43.685 ザック App[1320:a0b] bullet.contentsize.width = 0.000000 2013-08-07 16:31:43.686 ザック App[1320:a0b] character.contentsize.width = 64.000000 2013-08-07 16:31 :43.686 ザック アプリ[1320:a0b] bullet.contentsize.width = 0.000000 2013-08-07 16:31:43.687 ザック アプリ[1320:a0b] character.contentsize.width = 64.000000 2013-08-07 16:31:43.687 Zach App[1320:a0b] 箇条書き。contentsize.width = 0.000000 2013-08-07 16:31:43.688 Zach App[1320:a0b] character.contentsize.width = 64.000000 2013-08-07 16:31:43.688 Zach App[1320:a0b] bullet.contentsize.幅 = 0.000000 2013-08-07 16:31:43.689 ザック アプリ[1320:a0b] character.contentsize.width = 64.000000 2013-08-07 16:31:43.689 ザック アプリ[1320:a0b] bullet.contentsize.width = 0.000000 2013-08-07 16:31:43.690 ザック アプリ[1320:a0b] character.contentsize.width = 64.000000 2013-08-07 16:31:43.691 ザック アプリ[1320:a0b] bullet.contentSize.width = 20.000000 2013 -08-07 16:31:43.836 ザック アプリ[1320:a0b] bullet.contentsize.width = 0.000000 2013-08-07 16:31:43.837 ザック アプリ[1320:a0b] character.contentsize.width = 64.000000 2013-08 -07 16:31:43.838 ザック アプリ [1320:a0b] bullet.contentsize.width = 0.000000 2013-08-07 16:31:43.838 ザック アプリ[1320:a0b] character.contentsize.width = 64.000000 2013-08-07 16:31:43。839 ザック アプリ[1320:a0b] bullet.contentsize.width = 0.000000 2013-08-07 16:31:43.840 ザック アプリ[1320:a0b] character.contentsize.width = 64.000000 2013-08-07 16:31:43.841 ザックApp[1320:a0b] bullet.contentsize.width = 0.000000 2013-08-07 16:31:43.842 ザック アプリ[1320:a0b] character.contentsize.width = 64.000000 2013-08-07 16:31:43.843 ザック アプリ[ 1320:a0b] bullet.contentsize.width = 20.000000 2013-08-07 16:31:43.843 ザック App[1320:a0b] character.contentsize.width = 64.000000000000 2013-08-07 16:31:43.843 ザック App[1320:a0b] character.contentsize.width = 64.000000000000 2013-08-07 16:31:43.843 ザック App[1320:a0b] character.contentsize.width = 64.000000

4

2 に答える 2

1

「shootTheBullets」を呼び出すたびに、「弾丸」が指すポインターを置き換えています。これは、ポインターが元のオブジェクトを指していないため、コンテンツのサイズが 0 と報告される理由だと思います。バウンディング ボックスがキャラクターと交差するかどうかを確認するために、弾丸を配列などで収集し、それらを反復処理する必要があります。

編集:

CCSprite を配置したときに CCNode が返される理由はわかりませんが、基本的な要件の簡単な抜粋を次に示します。

免責事項: cc2d 1.1、非 ARC 用です。今手元にあるものです。

Bullet.h

#import "CCSprite.h"

@interface Bullet : CCSprite
{
    float damage;
    CGPoint velocity;
}

@property float damage;
@property CGPoint velocity;

+(Bullet *) bulletWithDamage:(float) damage andVelocity:(CGPoint) velocity;

@end

Bullet.m

#import "Bullet.h"
@implementation Bullet
@synthesize damage, velocity;
+(Bullet *) bulletWithDamage:(float) damage andVelocity:(CGPoint) velocity
{
    Bullet *bullet = [[[self alloc] initWithFile:@"Icon.png"] autorelease];
    bullet.damage = damage;
    bullet.velocity = velocity;
    bullet.scale = 0.2f;
    return bullet;
}

-(id) init
{
    if( (self = [super init]) )
    {}
    return self;
}
@end

PlayTest.h

#import "cocos2d.h"

@interface PlayTest : CCLayer
{
    NSMutableArray *bullets;
    CCSprite *character;
    CGSize winSize;
}

@end

PlayTest.m

#import "PlayTest.h"
#import "Bullet.h"

@implementation PlayTest

-(id) init
{
    if( (self=[super init]))
    {
        winSize = [CCDirector sharedDirector].winSize;
        bullets = [[NSMutableArray alloc] initWithCapacity: 10];

        character = [CCSprite spriteWithFile:@"Icon.png"];
        character.position = ccp(winSize.width/3.4f, winSize.height/2.0f - 100.0f);
        [self addChild:character z:-3];

        [self schedule:@selector(shootTheBullets:) interval:1.0f repeat: 10 delay: 3.0f];
        [self scheduleUpdate];
    }

    return self;
}

-(void)shootTheBullets:(ccTime)delta{

    float randX = CCRANDOM_0_1() * 0.5f;
    Bullet *b = [Bullet bulletWithDamage:5.0f andVelocity:ccp( randX, -1.0f)];
    b.position = ccp(40.0f, winSize.height);
    [bullets addObject:b];

    [self addChild: b];

}

-(void) update:(ccTime)dt
{
    [self moveTheBullets];
    [self checkCollisions];
}

-(void) moveTheBullets
{
    for (int i=0; i< bullets.count; i++)
    {
        Bullet *b = (Bullet *)[bullets objectAtIndex:i];
        b.position = ccpAdd(b.position, b.velocity);
    }
}

-(void) checkCollisions
{
    NSMutableArray *collisions = [NSMutableArray arrayWithCapacity:10];
    BOOL characterHit = NO;
    for (int i=0; i< bullets.count; i++)
    {
        Bullet *b = (Bullet *)[bullets objectAtIndex:i];
        if(CGRectIntersectsRect(character.boundingBox, b.boundingBox) )
        {
            NSLog(@"bullet collision with character");
            [collisions addObject: b];
            characterHit = YES;
        }
        else if (b.position.y < 0.0f)
        {
            NSLog(@"bullet went off screen without hitting anything");
            [collisions addObject: b];
            b.damage = 0.0f;
        }
    }

    for (int i=0; i< collisions.count; i++)
    {
        Bullet *b = (Bullet *)[collisions objectAtIndex:i];

        // you could damage the character here, something like:
        // characterDamage -= b.damage


        [self removeChild:b cleanup:YES];
        [bullets removeObject: b];
        NSLog(@"bullets count is %d", bullets.count);
    }

    if(characterHit) // show character got damaged
    {
        if( ![character numberOfRunningActions])
        {
            id one = [CCActionTween actionWithDuration:0.1f key:@"opacity" from:255 to:128];
            id two = [CCActionTween actionWithDuration:0.1f key:@"opacity" from:128 to:255];
            id onetwo = [CCSequence actions: one, two, nil];
            [character runAction: onetwo];
        }
    }
}

-(void) dealloc
{
    [bullets release];
    [super dealloc];
}

@end
于 2013-08-08T02:23:04.203 に答える