寻求建议,为XNA中的2D游戏创建反射“光束”的最佳方法

时间:2012-06-19 00:36:19

标签: c# xna 2d collision-detection sprite

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

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

Here is a screen cap of the game so far

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

我只是想知道是否有人对于检测障碍物,它们的旋转以及确定反射光束的方向(镜像的哪一侧被击中)的最佳方法有任何建议,然后我完全承诺某事可能会变得非常复杂或甚至不起作用?

这是我的Beam类当前的样子......除了一个类从一个名为Object和Object的基类继承之外,所有类都在属于单独的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)));
    }
}

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

2 个答案:

答案 0 :(得分:3)

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

相反,取你的光束并迭代所有镜子,计算光束和镜子平面的交点(处理没有交叉点的情况),然后检查交叉点以确保它在物理镜像内。记录在最短距离内发生的匹配。

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

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

如果有一个 LOT 的镜子你可以把它拿得更远,然后将屏幕切成扇区,每个扇区都有一个镜像列表。只检查当前扇区中的镜像,如果你没有找到它接下来进入的扇区并重复。这是一个更多的数学投射光束射线,以换取排除大多数镜子没有一个指令。如果您正在处理用户放置的镜像,我怀疑它们是否足够值得这样做。

答案 1 :(得分:1)

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