我有一些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);
}
}
}
}
答案 0 :(得分:7)
此方法是构造函数。这就是问题所在:
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
方法计算下一步而不是从队列中提取它:您也不需要该队列。
就像你在下棋,在你甚至不知道对手的第一步将会是什么之前,你正在计算整个游戏。在游戏开始前你的鼻子会流血。
答案 1 :(得分:2)
我现在没有时间来解决整个事情,但我可以告诉你内存错误发生了什么 - 它正在疯狂地建立一条到达某处的无限路径,因为终止条件没有抓住它。