1

我正在开发 XNA 平台游戏,需要一些帮助来解决碰撞问题。游戏发生在一个洞穴中,问题是艺术风格会很粗略,因此地形(洞穴)会有很大差异,所以我不能使用瓷砖。但是我需要检查角色和洞穴的像素完美碰撞,但是当我无法在每个图块周围放置矩形时,我不知道该怎么做,因为没有。

我想了很多想出了一些想法:

- 一个大矩形围绕整个关卡,一个围绕角色,并使用像素完美碰撞。但我认为这不会起作用,因为矩形也会包含背景。

- 手动放置矩形。非常丑陋的代码,可能会导致很多错误和错误。

- 无论如何都要使用瓷砖,并且有数百种瓷砖类型。再次,非常丑陋的代码,它似乎是错误的。

- 使用碰撞引擎。我最好从头开始制作游戏。

如果我解释得不好,我很抱歉,但这是一个相当复杂的问题(至少对我来说),我在网上找不到任何解决方案。很高兴有任何想法,谢谢。

4

1 回答 1

5

我认为你应该使用每像素碰撞检测来做你想做的事情。你可以让你的角色,并使他的纹理透明(使用图像alpha),除了实际角色。然后你可以有terrain纹理,这将是你的洞穴。使洞穴的部分角色应该能够移动透明,这样你就可以拥有另一个纹理,这将是整个关卡的背景。这是一个粗略的例子:

人物(粉色BG透明:)

在此处输入图像描述

洞穴(白色透明)

在此处输入图像描述

背景:

在此处输入图像描述

三者相加:

在此处输入图像描述

这只是给你一个非常粗略的想法(因为我只是用谷歌搜索了背景并用油漆画了洞穴)。然后你可以在洞穴纹理(不是洞穴背景)和角色纹理之间使用 alpha 像素碰撞检测。有关如何轻松使用逐像素碰撞的教程,请参阅this 。HTH。这是您可以使用的一些碰撞代码(rectangleA应该是角色的矩形、dataA角色的像素数据、rectangleB洞穴的矩形(可能是整个屏幕)和dataB洞穴的像素数据(不是背景))因为你不使用背景图像的像素数据,则不会使用此数据检查碰撞:

    /// <param name="rectangleA">Bounding rectangle of the first sprite</param>
    /// <param name="dataA">Pixel data of the first sprite</param>
    /// <param name="rectangleB">Bouding rectangle of the second sprite</param>
    /// <param name="dataB">Pixel data of the second sprite</param>
    /// <returns>True if non-transparent pixels overlap; false otherwise</returns>
    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 found
        return false;
    }
于 2014-02-15T14:32:36.730 回答