2D逐像素碰撞检测不起作用

本文关键字:不起作用 碰撞检测 像素 2D | 更新日期: 2023-09-27 18:27:56

我想提前对我将发布的代码量说声抱歉,但我似乎无法让我的碰撞检测工作起来,当我玩测试时,玩家和物体相互通过,没有任何效果。

我收到0个警告或错误,但Player playerBot对象似乎与我从GLEED2D导入的任何级别项目都没有交互。

我做的一件事是将物品的矩形和颜色数组的值存储在列表中,这样它们就可以很容易地迭代,也许这就是问题的根源。

如果你能发现我的代码不起作用的原因,我将不胜感激。我已经删除了任何绝对不相关的代码,如果有帮助的话,我将使用GLEED2D1.3运行VS2010。

再次感谢。

// Item Class ImageItem Downcast
public class ImageItem : Item
{
    public Texture2D Texture;
}
// Level
Level level;
// Ints
int iNumOfItems = 0;
int iTextureDataListNum = 0;
int iRectangleListNum = 0;
// Lists
List<Color []> itemTextureDataList = new List<Color[]>();
List<Rectangle> itemRectangleList = new List<Rectangle>();
protected override void Initialize()
{
    if (filename.Length > 0) level = Level.FromFile(filename, Content);
    else level = Level.FromFile("level1.xml", Content);
    foreach (Layer layer in level.Layers)
    {
        foreach (Item item in layer.Items)
        {
            iNumOfItems =+ 1;
        }
    }
    // Creates Player Ship
    playerBot = new Player(new Vector2(400f, 240f), new Vector2(0f, 0f));
    base.Initialize();
}
protected override void LoadContent()
{
    Texture2D pixel = new Texture2D(GraphicsDevice, 1, 1, false, SurfaceFormat.Color);
    pixel.SetData(new[] { Color.White });
    spriteBatch = new SpriteBatch(GraphicsDevice);
    // Player Bot
    playerBot.LoadContent(Content, "Images/Player Bot Sprite Sheet", 40, 40, 4);
    // Assigns level textures color data to array
    foreach (Layer layer in level.Layers)
    {
        foreach (Item item in layer.Items)
        {
            ImageItem imageItem = item as ImageItem;
            if (imageItem != null)
            {
                Texture2D texture = imageItem.Texture;
                itemTextureDataList[iTextureDataListNum] = new Color[imageItem.Texture.Width * imageItem.Texture.Height];
                imageItem.Texture.GetData(itemTextureDataList[iTextureDataListNum]);
                iTextureDataListNum++;
            }
        }
    }
    // Creates a rectangle for every level texture
    foreach (Layer layer in level.Layers)
    {
        foreach (Item item in layer.Items)
        {   
            ImageItem imageItem = item as ImageItem;
            if (imageItem != null)
            {
                itemRectangleList[iRectangleListNum] = new Rectangle((int)imageItem.Position.X, (int)imageItem.Position.Y, imageItem.Texture.Width, imageItem.Texture.Height);
                iRectangleListNum++;
            }
        }
    }
    spriteBatch = new SpriteBatch(GraphicsDevice);
}
protected override void Update(GameTime gameTime)
{
    // Player Update
    playerBot.Update(gameTime);
    ((Sprite)playerBot).Update(gameTime);
    // Check for player collisons with level
    for (int i = 0; i < iNumOfItems - 1; i++)
    {
        if (IntersectPixels(playerBot.colRectangle, playerBot.textureDataArray, itemRectangleList[i], itemTextureDataList[i]) == true)
        {
            playerBot.StopMovement();
        }
    }
    base.Update(gameTime);
}
// Level Collision Detection Method
static bool IntersectPixels(Rectangle rectangleA, Color[] dataA, Rectangle rectangleB, Color[] dataB)
{
    // Find the bounds of the rectangle intersection
    int top = Math.Max(rectangleA.Top, rectangleB.Top);
    int bottom = Math.Min(rectangleA.Bottom, rectangleB.Bottom);
    int left = Math.Max(rectangleA.Left, rectangleB.Left);
    int right = Math.Min(rectangleA.Right, rectangleB.Right);
    // Check every point within the intersection bounds
    for (int y = top; y < bottom; y++)
    {
        for (int x = left; x < right; x++)
        {
            // Get the color of both pixels at this point
            Color colorA = dataA[(x - rectangleA.Left) + (y - rectangleA.Top) * rectangleA.Width];
            Color colorB = dataB[(x - rectangleB.Left) + (y - rectangleB.Top) * rectangleB.Width];
            // If both pixels are not completely transparent
            if (colorA.A != 0 && colorB.A != 0)
            {
                // Then an intersection has been found
                return true;
            }
        }
    }
    // No intersection fond
    return false;
}

//精灵级

public void Update(GameTime gameTime)
{
    textureDataArray = new Color[texture.Width * texture.Height];
    texture.GetData(textureDataArray);

//玩家等级

public void StopMovement()
{
    velocity.X *= -1;
    velocity.Y *= -1;
}

2D逐像素碰撞检测不起作用

我在这里要说的第一件事是,您的方法应该更加面向对象。在项目列表旁边存储纹理列表和矩形列表是一种"糟糕"的技术,在调试时最终会让你头疼。

因此,首先,不要有一个Color[]列表和一个Rectangle列表,而是在ImageItem类中添加一个Color[]和一个矩形,然后使用它们,或者至少创建一个名为"CollisionData"的小类,它有一个矩形和一个Color],并将它们存储在一个列表中。

其次,注意有一个矩形相交(矩形a,矩形B),它得到了你的矩形相交。因此,您可以使用它来整理您的代码。

您的颜色检查可以简化为(ColorA.A*ColorB.A!=0),因为为零将导致结果为零。

关于没有得到任何错误,在冲突检查循环的开始处放置一个断点。应用程序是否损坏?如果是,iNumItems的值是多少?(您可以将鼠标悬停在它上面,以查看断开点的当前值)。如果没有,则无法访问代码的该部分。将另一个断点放得再靠后一点,直到它被击中,然后找出代码没有执行的原因。