为什么我的随机路径代码不起作用

本文关键字:代码 不起作用 路径 随机 我的 为什么 | 更新日期: 2023-09-27 18:35:03

我有一些XNA塔防的代码。我设置了它,以便敌人(错误(从网格的某一侧随机向下移动,直到它击中房屋(目的地(或房屋一侧的行。

我调试了这个项目,错误被绘制并开始在对角线(某种(路径中移动。每次都是一样的(不是随机的(。我不知道我做错了什么。 它有时也会在我指定的代码中的位置给出OutOfMemory异常。我不知道我是否解释得很好,所以请随时提问。网格被森林包围,森林不是网格的一部分,所以这就是森林的意思。

public class Bug : Sprite
{
    public float startHealth;
    protected float currentHealth;
    protected bool alive = true;
    protected float speed = 0.5f;
    protected int bountyGiven;
    public int startplace;
    public bool at_house;
    public Queue<Vector2> path = new Queue<Vector2>();
    Random random = new Random();
    int x;
    int y;
    public int end_row;
    public int end_column;
    //Defines the space where the house is
    Vector2 house1 = new Vector2(10, 13) * 91;
    Vector2 house2 = new Vector2(10, 12) * 91;
    Vector2 house3 = new Vector2(10, 11) * 91;
    Vector2 house4 = new Vector2(10, 10) * 91;
    Vector2 house5 = new Vector2(11, 13) * 91;
    Vector2 house6 = new Vector2(11, 12) * 91;
    Vector2 house7 = new Vector2(11, 11) * 91;
    Vector2 house8 = new Vector2(11, 10) * 91;
    Vector2 house9 = new Vector2(12, 13) * 91;
    Vector2 house10 = new Vector2(12, 12) * 91;
    Vector2 house11 = new Vector2(12, 11) * 91;
    Vector2 house12 = new Vector2(12, 10) * 91;
    public float CurrentHealth
    {
        get { return currentHealth; }
        set { currentHealth = value; }
    }
    public bool IsDead
    {
        get { return currentHealth <= 0; }
    }
    public int BountyGiven
    {
        get { return bountyGiven; }
    }
    public float DistanceToDestination
    {
        get { return Vector2.Distance(position, path.Peek()); }
    }
    public Bug(Texture2D texture, Vector2 position, float health,
        int bountyGiven, float speed)
        : base(texture, position)
    {
        this.startHealth = health;
        this.currentHealth = startHealth;
        this.bountyGiven = bountyGiven;
        this.speed = speed;
        int startq = random.Next(1, 4);
        set_start(ref startq);
        //end_row and end_column detremine the row or column at which the bug turns toward the house.
        end_row = random.Next(10, 13);
        end_column = random.Next(10, 12);
        set_path(ref startq);
    }
    public void set_start(ref int startq)
    {
        //here i am initializing the "0,0" point for the bug so it's 0,0 is't in the forest
        //startx and starty should equal the number of tiles between the forest edge and the grass edge
        //startx is the x co-ord in the start place and starty is the y co-ord in the start
        int startx = 4;
        int starty = 4;
        //This generates a random number which determines the start for the bug
        //Between 0 and 22 because that is the number of edge tiles on one side
        int start = random.Next(0, 22);
        //start determines what place on a side the buggie spawns at
        //startq is a random int (1-4)(defined in constructor) which determnes which side the bug spawns at
        if (startq == 1)
        {
            starty += 22;
            startx += start;
        }
        if (startq == 2)
        {
            startx += 22;
            starty += start;
        }
        if (startq == 3)
        {
            startx += start;
        }
        if (startq == 4)
        {
            starty += start;
        }
        x = startx;
        y = starty;
        path.Enqueue(new Vector2(startx, starty) * 91);
    }
    public bool check_for_path_end(ref int startq, ref bool at_house)
    {
        bool path_ends;
        //checks if the bug has reached the house and if so signals using at_house
        if (path.Peek() == house1 || path.Peek() == house2 || path.Peek() == house3 || path.Peek() == house4
            || path.Peek() == house5 || path.Peek() == house6 || path.Peek() == house7 || path.Peek() == house8
            || path.Peek() == house9 || path.Peek() == house10 || path.Peek() == house11 || path.Peek() == house12)
        {
            at_house = true;
            return true;
        }
        //Should i add at_house = true to the else ifs? 
        else if (startq == 1 || startq == 3 && path.Peek().Y == end_row)
        {
            path.Enqueue(new Vector2(11, end_row) * 91);
            return true;
        }
        else if (startq == 2 || startq == 4 && path.Peek().X == end_column)
        {
            path.Enqueue(new Vector2(end_column, 11) * 91);
            path_ends = true;
        }
        else
        {
            path_ends = false;
        }
        return path_ends;
    }
    public void set_path(ref int startq)
    {
        bool path_ends;
        bool legal = true;
        int X = x;
        int Y = y;
        do
        {
            //determines which way the bug turns at it's different waypoints 1 = left, 2 = right, 3 = forward
            int turn = random.Next(1, 3);
            do
            {
                if (startq == 1)
                {
                    switch (turn)
                    {
                        case 1:
                            x += 1;
                            break;
                        case 2:
                            x -= 1;
                            break;
                        case 3:
                            y += 1;
                            break;
                    }
                }
                else if (startq == 2)
                    switch (turn)
                    {
                        case 1:
                            y -= 1;
                            break;
                        case 2:
                            y += 1;
                            break;
                        case 3:
                            x -= 1;
                            break;
                    }
                else if (startq == 3)
                {
                    switch (turn)
                    {
                        case 1:
                            x -= 1;
                            break;
                        case 2:
                            x += 1;
                            break;
                        case 3:
                            y += 1;
                            break;
                    }
                }
                else if (startq == 4)
                {
                    switch (turn)
                    {
                        case 1:
                            y += 1;
                            break;
                        case 2:
                            y -= 1;
                            break;
                        case 3:
                            x += 1;
                            break;
                    }
                }
                if (y > 3 && y < 28 && x > 3 && x < 28)
                {
                    //sets up a backup in case the bug goes off track
                    X = x;
                    Y = y;

这是例外的地方:

                        //Right here is where it gives the out of memory exception 
                        path.Enqueue(new Vector2(x, y) * 91);
                        legal = true;
                    }
                    else
                    {
                        //restores x and y to backups X and Y
                        x = X;
                        y = Y;
                        //adds to turn and repeats without randomizing turn or adding waypoints
                        turn += 1;
                        legal = false;
                    }
                } while (legal == false);
                path_ends = check_for_path_end(ref startq, ref at_house);
            } while (path_ends == false);
        }
        public bool check_corners()
        {
            bool start_is_corner;
            if (x == 2 && y == 24 || x == 24 && y == 24 || x == 24 && y == 2 || x == 2 && y == 2)
            {
                start_is_corner = true;
                int X = x;
                int Y = y;
                if (x == 4 && y == 27)
                {
                    bool z = true;
                    for (int i = 0; i < 13; ++i)
                    {
                        if (z == true)
                        {
                            Y -= 1;
                            path.Enqueue(new Vector2(X, Y) * 91);
                            z = false;
                        }
                        if (z == false)
                        {
                            X += 1;
                            path.Enqueue(new Vector2(X, Y) * 91);
                            z = true;
                        }
                    }
                }
                if (x == 27 && y == 27)
                {
                    bool z = true;
                    for (int i = 0; i < 13; ++i)
                    {
                        if (z == true)
                        {
                            Y -= 1;
                            path.Enqueue(new Vector2(X, Y) * 91);
                            z = false;
                        }
                        if (z == false)
                        {
                            X -= 1;
                            path.Enqueue(new Vector2(X, Y) * 91);
                            z = true;
                        }
                    }
                }
                if (x == 27 && y == 4)
                {
                    bool z = true;
                    for (int i = 0; i < 13; ++i)
                    {
                        if (z == true)
                        {
                            Y += 1;
                            path.Enqueue(new Vector2(X, Y) * 91);
                            z = false;
                        }
                        if (z == false)
                        {
                            X -= 1;
                            path.Enqueue(new Vector2(X, Y) * 91);
                            z = true;
                        }
                    }
                }
                if (x == 4 && y == 4)
                {
                    bool z = true;
                    for (int i = 0; i < 13; ++i)
                    {
                        if (z == true)
                        {
                            Y += 1;
                            path.Enqueue(new Vector2(X, Y) * 91);
                            z = false;
                        }
                        if (z == false)
                        {
                            X += 1;
                            path.Enqueue(new Vector2(X, Y) * 91);
                            z = true;
                        }
                    }
                }
            }
            else
            {
                start_is_corner = false;
            }
            return start_is_corner;
        }
        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
            if (path.Count > 0)
            {
                if (DistanceToDestination < speed)
                {
                    position = path.Dequeue();
                }
                else
                {
                    Vector2 direction = path.Peek() - position;
                    direction.Normalize();
                    velocity = Vector2.Multiply(direction, speed);
                    position += velocity;
                }
            }
            else
                alive = false;
            if (currentHealth <= 0)
                alive = false;
        }
        public override void Draw(SpriteBatch spriteBatch)
        {
            if (alive)
            {
                float healthPercentage = (float)currentHealth / (float)startHealth;
                base.Draw(spriteBatch);
            }
        }
    }
}

为什么我的随机路径代码不起作用

此方法是构造函数。这就是问题的来源:

public Bug(Texture2D texture, Vector2 position, float health, int bountyGiven, float speed)
    : base(texture, position)
{
    this.startHealth = health;
    this.currentHealth = startHealth;
    this.bountyGiven = bountyGiven;
    this.speed = speed;
    int startq = random.Next(1, 4);
    set_start(ref startq);
    //end_row and end_column detremine the row or column at which the bug turns toward the house.
    end_row = random.Next(10, 13);
    end_column = random.Next(10, 12);
    set_path(ref startq); // <<<<<<<<<<< HERE!
}

您在这里所做的是在初始化时预先确定错误的路径。您将整个路径存储在某个Queue中。最终,队列变得如此之大,以至于内存不足。

解决方案很简单。与其初始化一个知道他出生时将要向家迈出的每一步的Bug,不如做一个从某个地方开始的Bug并在每次更新时确定下一步回家将是什么。不要排队。

你的

错误在于你在构造函数中做了属于你的Update方法的东西。摆脱你的set_path方法。一个错误不够聪明,无法从一开始就知道回家的路。这就是阻碍你游戏的原因。使用 Update 方法计算下一步,而不是从队列中提取它:您也不需要该队列。

这就像你在下棋,在你甚至不知道对手的第一步是什么之前,你就在脑海中计算整个游戏。在游戏开始之前,你的鼻子就会流血。

我现在

真的没有时间弄清楚整个事情,但我可以告诉你你的内存不足错误发生了什么 - 它正在疯狂地构建一条通往某个地方的无限路径,因为终止条件没有抓住它。