2009-08-30 12 views
2

私はiPhone用の基本的なプラットフォームゲームを作っています。私は衝突検出に問題が発生しました。iPhone SDK:衝突検出、四角形でなくてはなりませんか?

if (CGRectIntersectsRect(player.frame, platform.frame)) 
    pos2 = CGPointMake(0.0, +0.0); 
else 
    pos2 = CGPointMake(0.0, +10.0); 

衝突検出は、プレイヤーがプラットフォーム上にあるときに、既存のゲーム内の重力を停止することで、問題は衝突検出がプレイヤーの周りの長方形であるという事実である、衝突を行うには、とにかくありその周囲の四角形ではなく、画像の実際の形状(透明度付き)を検出しますか?

答えて

3

あなたはこれを自分でプログラムしなければならないでしょうし、ピクセルごとの衝突はおそらくiPhoneにとっては高すぎることに注意してください。私は、Collidableプロトコル(他のすべてのプログラミング言語でインターフェイスと呼ばれる)を記述し、collidedWith:(Collidable *)c関数を与え、衝突を許可するオブジェクトに対して実装するだけです。次に、ケースバイケースの衝突ロジックを記述することができます。同様に、衝突のために必要なすべての情報(X、Y、幅、高さ、またはX、Y、ピクセルデータ配列)とcollidesWithメソッドを持つ大きなスーパークラスを作ることができます。どちらの方法でも、さまざまなコリジョン方法を書くことができます。いくつかの点でピクセルコリジョンを実行するだけであれば、パフォーマンスヒットはそれほどありません。しかし、典型的には、のように、バウンディングボックスの衝突やその他の幾何学的な衝突を行うほうが速いのが一般的です。より速くです。

metanetsoftwareの人々は、axis separation collsiongrid based collisionの中で、衝突技術に関するいくつかの素晴らしいチュートリアルを作成しました。後者はあなたのゲームにとってより実用的であるように思えます。ただし、すべてのオブジェクトを他のすべてのオブジェクトと照合することにより、ブルートフォースの衝突を検出したい場合は、通常、画像よりも小さいというバウンディングボックスを作成するのが適切な方法です。これはスーパーマリオブラザーズを含む成功したプラットフォーマーの数です。重み付けされたバウンディングボックスも考えられます。つまり、1つのタイプのオブジェクトには1つの境界ボックスがあり、他のオブジェクトには異なるサイズのボックスがあります。たとえばマリオでは、敵よりも大きなコインを賭けるボックスがあります。

私はあなたに他のことを警告しましたが、私はあなたに任せて、ピクセルベースの衝突を行う方法を説明します。あなたはCGImageのaccess the pixel dataに行きたいと思っています。そして、すべてのピクセルを繰り返して、この画像が他の画像と位置を共有しているかどうかを確認します。これにはいくつかのコードがあります。

for (int i = 0; i < [objects count]; i++) 
{ 
    MyObject *obj1 = [objects objectAtIndex:i]; 

    //Compare every object against every other object. 
    for (int j = i+1; j < [objects count]; j++) 
    { 
     MyObject *obj2 = [objects objectAtIndex:j]; 

     //Store whether or not we've collided. 
     BOOL collided = NO; 

     //First, do bounding box collision. We don't want to bother checking 
     //Pixels unless we are within each others' bounds. 
     if (obj1.x + obj1.imageWidth >= obj2.x && 
      obj2.x + obj2.imageWidth >= obj1.x && 
      obj1.y + obj1.imageHeight >= obj2.y && 
      obj2.y + obj2.imageGeight >= obj1.y) 
     { 
      //We want to iterate only along the object with the smallest image. 
      //This way, the collision checking will take the least time possible. 
      MyObject *check = (obj1.imageWidth * obj1.imageHeight < obj2.imageWidth * obj2.imageHeight) ? obj1 : obj2; 

      //Go through the pixel data of the two objects. 
      for (int x = check.x; x < check.x + check.imageWidth && !collided; x++) 
      { 
       for (int y = check.y; y < check.y + check.imageHeight && !collided; y++) 
       { 
        if ([obj1 pixelIsOpaqueAtX:x andY:y] && [obj2 pixelIsOpaqueAtX:x andY:y]) 
        { 
         collided = YES; 
        } 
       } 
      } 
     } 
    } 
} 

pixelIsOpaque座標ではなく、ローカル座標ので、あなたがあなたを手放すプログラムは再びその外に、xとyを減算するように注意する必要があり、またはあなたがチェックされますときに、グローバルになりますので、私はそれを作りましたあなたのイメージの境界から外れています。

関連する問題