0

さて、私は XNA プログラミングにかなり慣れていないので、プラットフォーマーをコーディングしようとしています。ピクセルパーフェクトなコリジョンを実装しましたが、明らかな理由もなく失敗することがあり (パターンを理解できませんでした)、ヒーロー スプライトがプラットフォームを通過します。

static bool IntersectsPixel(Rectangle rect1, Color[] data1, Rectangle rect2, Color[] data2)
    {
        int top = Math.Max (rect1.Top, rect2.Top);
        int bottom = Math.Min(rect1.Bottom, rect2.Bottom);
        int left = Math.Max (rect1.Left,rect2.Left);
        int right = Math.Min(rect1.Right,rect2.Right);


        //Top
        for(int y = top; y<bottom;y++)
            for (int x = left; x < right; x++)
            {
                Color color1 = data1[x-rect1.Left + (y-rect1.Top) * rect1.Width];

                Color color2 = data2[x - rect2.Left + (y - rect2.Top) * rect2.Width];

                if (color1.A != 0 && color2.A != 0)
                    return true;
            }



        return false;
    }

そして、これが更新方法です

     protected override void Update(GameTime gameTime)
    {

        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();


       foreach(Platform platform in platformList)
       {
           Rectangle check = new Rectangle(hero.GetRectangle().X - 300, hero.GetRectangle().Y - 300, 600, 600);
            if(check.Intersects(platform.rectangle))
           if (IntersectsPixel(hero.GetRectangle(), hero.textureData, platform.rectangle, platform.platformTextureData))
           {
               int direction = CheckDirection(platform,hero);
               if (hero.hasJumped == true && direction == 3 && hero.velocity.Y <= 0 )
                   {
                         hero.velocity.Y = 0f;
                         hero.SetPosition(new Vector2((float)hero.GetPosition().X, (float)platform.rectangle.Bottom));


                       break;
                   }
               else
               if (direction == 4 && hero.velocity.X >= 0)
               {
                   hero.velocity.X = 1;
                   hero.SetPosition(new Vector2((float)platform.rectangle.Left - (float)hero.GetRectangle().Width, (float)hero.GetPosition().Y));
                   break;
               }
               else
                   if (direction == 2 && hero.velocity.X <= 0)
                   {
                       hero.velocity.X = -1;

                       hero.SetPosition(new Vector2((float)platform.rectangle.Right - 1, (float)hero.GetPosition().Y));
                       break;
                   }
                   else

               if (direction == 1 && hero.velocity.Y >= 0)
               {
                   hero.velocity.Y = 0;
                   hero.hasJumped = false;
                   hero.SetPosition(new Vector2((float)hero.GetRectangle().X, (float)platform.rectangle.Y - (float)hero.GetRectangle().Height + 1));
                   hero.SetRectangle(new Rectangle((int)hero.GetPosition().X, (int)hero.GetPosition().Y, (int)hero.GetSize().X, (int)hero.GetSize().Y));
                   break;
               }




               }


           }


        hero.Update(gameTime);
        camera.Update(gameTime, hero, screenBounds);
        base.Update(gameTime);
    }

そして、ここに方向チェックがあります:

     private int CheckDirection(Platform platform,Hero hero)
    {
        int distance = Math.Abs(platform.rectangle.Top - hero.GetRectangle().Bottom);
        int direction = 1; //Top
        if (distance > Math.Abs(platform.rectangle.Right - hero.GetRectangle().Left))
        {
            distance = Math.Abs(platform.rectangle.Right - hero.GetRectangle().Left);
            direction = 2;
        }
        if (distance > Math.Abs(platform.rectangle.Bottom - hero.GetRectangle().Top))
        {
            distance = Math.Abs(platform.rectangle.Bottom - hero.GetRectangle().Top);
            direction = 3;
        }
        if (distance > Math.Abs(platform.rectangle.Left - hero.GetRectangle().Right))
        {
            direction = 4;
            distance = Math.Abs(platform.rectangle.Left - hero.GetRectangle().Right);
        }
        return direction;
    }

これらはすべて、衝突検出に関連する私の機能です。この原因について何か考えられることがあれば、お知らせください。

どうもありがとうございました !

4

2 に答える 2

0

ラグが原因で、キャラクターがフレームごとにブロックの高さを超えて移動する可能性があるため、衝突によってブロックとブロックの間にあると見なされ、通過する可能性があります。

https://gamedev.stackexchange.com/questions/30458/platformer-starter-kit-collision-issues

それをチェックしてください、それは私のために問題を解決しました。

動きを遅くするか、位置の変化をブロックのサイズに固定することで、これを解決できます。

于 2012-09-22T18:50:51.277 に答える
0

考えられる理由の 1 つは、最初に両方のオブジェクトの周りにボックスを作成することです。

    int top = Math.Max (rect1.Top, rect2.Top);
    int bottom = Math.Min(rect1.Bottom, rect2.Bottom);
    int left = Math.Max (rect1.Left,rect2.Left);
    int right = Math.Min(rect1.Right,rect2.Right);

反転しない限り、通常、XNA の Y は下に行くにつれて (上ではなく) 正になります。つまり、Top は常に Bottom よりも小さいため、実際には Bottom の Max と Top の Min を取得する必要があります。この行を見ると、すでにそれを知っているようです。

    for(int y = top; y<bottom;y++)

私は探し続けます (実際のプロジェクトなしでテストするのは難しいです)。もう 1 つの推奨事項は、デバッグ描画を行うことです。交差関数がピクセルが接触しているかどうかを判断する場所を描画します。

于 2012-09-22T17:16:12.147 に答える