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

我看到的一件事可能是一个可能的原因,那就是一开始你在两个对象周围构建了一个盒子:

    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 通常会随着您下降(而不是上升)而增长。这意味着您实际上想要取底部的最大值和顶部的最小值,因为顶部总是小于底部。看起来你已经知道了,尽管从这一行来看:

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

我会继续寻找(没有实际项目很难测试)。我给你的另一个建议是做一些调试绘图。在交叉函数认为像素接触或不接触的地方绘制。

于 2012-09-22T17:16:12.147 回答
0

由于滞后,您的角色每帧移动的距离可能超过块高度,因此碰撞可能会认为它位于块之间,并导致它飞过。

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

检查一下,它为我解决了问题。

减慢移动速度,或者将位置变化限制为块的大小应该可以解决这个问题。

于 2012-09-22T18:50:51.277 回答