c#中的二维光线投射问题[NOT unity 3D]

时间:2015-05-27 15:33:19

标签: c# 2d raycasting

我正在用C#制作一个2D游戏,用我自己的渲染引擎我用c#和OpenGL制作。现在我正在制作Enemys。它是一个隐形游戏,所以我需要知道敌人是否可以看到玩家。这可以使用光线投射来完成。我实现了它,但它慢,慢。假设我有大约200个物体和200条射线。每个射线在路上用一个小碰撞盒(x pos,ypos,1,1)检查50次碰撞。现在是200 * 200 * 50的碰撞检查。即使使用多线程和100%使用的CPU(i7 4810mq,3.8ghz,quadcore,多线程),游戏运行速度可怕的4.1 fps。我需要优化我的代码,但不知道如何。我需要优化光线投射,而不是游戏。所以不是:检查对象是否超出范围并将其遗漏,将多个碰撞盒合并为1等代码:

public class RayCast
{
    private int maxSteps;
    private bool hit = false;
    private Box tester;
    private float[] linex, liney;

    private string[] tags;
    private Box target;

    public RayCast(int maxSteps)
    {
        tester = target = new Box(0,0,0,0);
        this.maxSteps = maxSteps;
        linex = new float[maxSteps];
        liney = new float[maxSteps];
        tags = new string[maxSteps];

        for(int i = 0; i < maxSteps; i++)
        {
            linex[i] = 0;
            liney[i] = 0;
            tags[i] = "";
        }
    }

    public void CastRay(float startx, float starty, float velx, float vely, float steps)
    {
        float xx = startx;
        float yy = starty;

        if(steps > maxSteps)steps = maxSteps;
        for (int i = 0; i < steps; i++)
        {
            //Console.WriteLine("linex,liney: " + linex[i] + "," + liney[i]);
            linex[i] = xx;
            liney[i] = yy;
            xx += velx;
            yy += vely;
        }
    }

    public void CheckRay(Sprite[] s)
    {
        hit = false;
        for (int i = 0; i < maxSteps; i++)
        {
            for (int j = 0; j < s.Length; j++)
            {
                tester.Set(linex[i], liney[i],0.01f, 0.01f);
                if (tester.Collides(s[j].GetRectangle()))
                {
                    target.Set(s[j].GetRectangle().X, s[j].GetRectangle().Y, s[j].GetRectangle().Width, s[j].GetRectangle().Height);
                    target.SetTag(s[j].GetTag());
                    hit = true;
                    break;
                }
                if (hit) break;
            }
        }
    }

    public bool GetHit()
    {
        return hit;
    }
    public Box GetTarget()
    {
        return target;
    }
}

并在游戏中使用它:

private void RayCast()
    {
        for (int i = 0; i < 10; i++)
        {
            if (player.isLeft()) rc.CastRay(player.GetX() + player.GetWidth(), player.GetY() + 0.3f, -0.12f, 0f, 50);
            else rc.CastRay(player.GetX(), player.GetY(), 0.12f, 0f, 50);
            rc.CheckRay(walls);
        }

        if (rc.GetHit()) Console.WriteLine("RayCast did HIT [" + rc.GetTarget().GetTag() + "] @ [" + rc.GetTarget().GetX() + "," + rc.GetTarget().GetY() + "," + rc.GetTarget().GetW() + "," + rc.GetTarget().GetH() + "]");
        else Console.WriteLine("RayCast did NOT");
    }

感谢任何帮助。

提前感谢,

科迪

0 个答案:

没有答案