web-dev-qa-db-ja.com

スプライトキットでの衝突の検出

スプライトキットで簡単なゲームを作ろうとしています。基本的な考え方は、ブロックを回避するためにジャンプできるプレーヤーが1人いるということです。しかし、プレイヤーがブロックに当たるとプレイヤーが消えて血のアニメーションが始まるようにする方法がわからないという問題があります。まず第一に、私はリンゴのウェブサイトで見つけたこのコードが何をするのか理解していません。

static const uint32_t blockCategory = 0x1 <<0;
static const uint32_t  playerCategory = 0x1 <<1;

私がdidBeginContact関数を呼び出して、NSLOG( "did call function")をその中に入れているより。しかし、デバッガーで出力を受け取ることはありません。

これが私の_playerと_blockのコードです:-( SKSpriteNode *)character {

_player = [SKSpriteNode spriteNodeWithImageNamed:@"soldier_run1"];
_player.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:_player.size.width /2 -5];
_player.physicsBody.dynamic = YES;
_player.physicsBody.usesPreciseCollisionDetection = YES;
_player.physicsBody.friction = 0;
_player.physicsBody.categoryBitMask = playerCategory;
_player.physicsBody.collisionBitMask = blokCategory;
_player.name = @"player";
SKAction *animAction = [SKAction animateWithTextures:playerTextures timePerFrame:0.1      resize:YES restore:YES];

私の_playerコード:

[_player runAction:[SKAction repeatActionForever:animAction]];

return _player;
}
-(SKSpriteNode *)block {
_blok = [[SKSpriteNode alloc] initWithColor:[SKColor blackColor] size:CGSizeMake(15, 40)];

//physics
_blok.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:_blok.size];
_blok.physicsBody.dynamic = NO;
_blok.name = @"block";
_blok.physicsBody.categoryBitMask = blokCategory;
_blok.physicsBody.collisionBitMask = playerCategory;
SKAction *moveBlock = [SKAction sequence:@[
                                          [SKAction moveToX:-20 duration:2] ]];
[_blok runAction:moveBlock ];
return _blok;
}

また、categoryBitMaskとcollisionBitMaskが何をするのか本当にわかりません。その作業が終わったら、キャラクターを画面から消して血のアニメーションを開始したいのですが、どうすればそれを実現できるのかわかりません。 if(_player && _block didcollide){}のようなことをしなければならないと思いますが、正確に行う方法がわかりません。

16
that guy

CategoryBitMaskは、スプライトが属するカテゴリを設定しますが、collisionBitMaskは、スプライトが衝突し、パススルーできないカテゴリを設定します。

衝突検出を行うには、contactTestBitMaskを設定する必要があります。ここでは、連絡時に連絡先デリゲートを呼び出すスプライトのカテゴリを設定します。

あなたがすでにしたことは正しいです。ここにあなたがする必要があるいくつかの追加があります:

_player.physicsBody.contactTestBitMask = blockCategory;
_blok.physicsBody.contactTestBitMask = playerCategory;

その後、次のように連絡先デリゲートを実装します。

-(void)didBeginContact:(SKPhysicsContact *)contact`
{
NSLog(@"contact detected");

SKPhysicsBody *firstBody;
SKPhysicsBody *secondBody;

if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
{
    firstBody = contact.bodyA;
    secondBody = contact.bodyB;
}
else
{
    firstBody = contact.bodyB;
    secondBody = contact.bodyA;
}

//Your first body is the block, secondbody is the player.
//Implement relevant code here.

}

衝突検出の実装に関する適切な説明については、 this チュートリアルを参照してください。

23
ZeMoon

衝突の処理は少し面倒です。 :)いくつかのアプローチがありますが、最初に始めるべき場所の1つは this Appleのかなり単純な例です。 readmeは優れたイントロを提供し、コードをいじり始めることができます。

別のアプローチ(Appleガイドに記載されています)は、ダブルディスパッチを使用することです(長い説明についてはウィキペディアを参照してください)。ただし、そのアプローチをすぐに理解しようとすることから始めません。ダイナミックセレクターや同様のテクニックに依存して魔法を実行できるようにすることを考えると、やや高度なアプローチですが、その警告があっても、誰かがそれを行う方法についてまとめた簡単な例と、多くのサポート説明を見つけることができます ここ

6
JZed