0

对不起,如果这个问题有点开放式,但我对 C# 和 XNA 很陌生......事实上这个论坛!

我正在创建一个游戏,需要一束光从一个固定点(附加的屏幕截图左下角,属于名为 PowerStation 的类)发出,并从用户可以移动和旋转的镜子反射。我添加了每像素碰撞检测方法,可以在附加的捕获中看到(镜子变成红色)。

这是迄今为止游戏的屏幕截图

目前我一直在尝试通过创建一个点并沿着光的路径移动它直到检测到碰撞来测试光束路径的障碍物;从那里记录行进的距离,然后以非均匀的方式将光束精灵拉伸所需的量。这已经被证明很困难,我认为这种方法还有很长的路要走。

我只是想知道是否有人对检测障碍物、它们的旋转以及确定反射光束的方向(被镜子的哪一侧击中)的最佳方法有任何建议,然后我才完全承诺可能会得到的东西真的很复杂,甚至从来没有工作过?

这是我的 Beam 类目前的样子......除了一个类之外,所有类都继承自一个名为 Object 的基类,并且 Objects 都在属于单独类 Items 的静态 objectList 中声明。抱歉,如果这是不好的,混乱的编码!

        class Beam : Object
{
    private Vector2 start;
    private double length;
    private Vector2 POC;



    public Beam(Vector2 pos)
        : base(pos)
    {

        spriteName = "beam";
        depth = 0.2f;
        solid = true;
        foreach (Object o in Items.objectList)
        {
            if (o.GetType() == typeof(PowerStation))
            {
                start = o.Origin;
            }
        }
    }

    public override void Update()
    {
        Point newPoint = new Point((int)Origin.X, (int)Origin.Y);
        while ((!(collision(new Mirror(new Vector2(0, 0))))) && (newPoint.X > 0) && (newPoint.Y > 0)) // && boundaries of window
        {
            newPoint.Y--; //will be changed to a Vector
        }

        POC = PointOfCollision(new Mirror(new Vector2(0, 0))); // Need to make it do POC of newPoint, not just the Beam Object!
        length = FindLength(start, new Vector2(50, 50));
        //Scale = new Vector2( , );     //amount to scale sprite


        base.Update();
    }

    private double FindLength(Vector2 pos1, Vector2 pos2)
    {
        return (Math.Sqrt(Math.Pow(Math.Abs(pos2.X - pos1.X), 2.0f) + Math.Pow(Math.Abs(pos2.Y - pos1.Y), 2.0f)));
    }
}

任何帮助将不胜感激!提前致谢

4

2 回答 2

3

忘记像素——因为镜子显然可以在任何角度,你肯定会有与镜子相交的地方,而不是在一个均匀的像素上。虽然您可以简单地将撞击点计算为偶数像素,但这会为光束产生略微错误的路径。

取而代之的是,使用您的光束并遍历所有镜子,计算光束与镜子平面的交点(处理没有相交的情况),然后检查相交以确保它在物理镜子内。记录在最短距离内发生的匹配。

您几乎可以肯定地通过提前计算所有镜子的边界框来加快计算速度,并在检查光束时注意它从当前点朝向哪个象限——您可以拒绝至少一半(通常是 3/4)的所有镜子每个镜像都有两个整数比较。

重复直到没有交叉点(光束逃逸)或者它击中了阻止它而不是反射它的东西。

如果有很多镜子,您可以更进一步,将屏幕分割成多个扇区,每个扇区都有一个镜子列表。只检查当前扇区中的镜像,如果没有成功,请找出它接下来进入哪个扇区并重复。这是一个更多的数学投射光束,以换取在没有单一指令的情况下排除大多数镜子。如果您正在处理用户放置的镜子,我怀疑它们是否足够值得这样做。

于 2012-06-19T04:31:53.037 回答
1

将所有内容表示为矢量:您的光束和它们反弹的形状的侧面。然后是非常简单的代数来检测交叉点和反射角。它也将比任何基于像素的检测快得多。

于 2012-06-19T01:05:04.123 回答