产卵倍数相同的蛇食的问题
issue with spawning multiples of the same snake food
这是一个简单的蛇游戏,但我对蛇食有疑问。我用 generateSnakeFood();
生成了一种新食物并且效果很好,但是当我尝试创建多个蛇食时,它只是在不同的位置重新绘制了一个新的蛇食,这是因为只能有一个 SnakeFood 所以画笔在另一个区域画了一个新的。如果是这样,我该如何解决才能吃到多个相同的蛇食?
private Square SnakeFood = new Square();
private void generateSnakeFood()
{
int maxXPosition = pictureBox1.Size.Width / GameSetting.Width;
int maxYPosition = pictureBox1.Size.Height / GameSetting.Height;
SnakeFood = new Square { X = random.Next(0, maxXPosition), Y = random.Next(0, maxYPosition) };
}
private void UpdateGame(object sender, PaintEventArgs e)
{
Graphics canvas = e.Graphics
canvas.FillRectangle(Brushes.Red,
new Rectangle(
SnakeFood.X * GameSetting2.Width2,
SnakeFood.Y * GameSetting2.Width2,
GameSetting2.Width2, GameSetting2.Height2
));
}
is this because there can only be one of the SnakeFood so the brush
paints a new one in another area
是的。即使你做了 new Square
你仍然在重新实例化同一个变量。您代码的绘图部分仅读取 1 个变量并绘制 1 Square
。您将需要使用某种集合,以便获得不同的计数。这也意味着您将需要更改您检测到碰撞的代码以及您吃食物并将其移除的代码。
有很多方法可以实现这一点,可以是使用 List
并像这样更改您的代码
private List<Square> SnakeFoods = new List<Square>();
private void generateSnakeFood()
{
// create new random food using the new method
// doesn't mean it's valid yet
Square newFood = GenerateRandomFood();
// you need to make sure there is not another food at that same location
// in the collection or else you have a duplicate.
// if there is a duplicate you need to generate a new one until it's unique.
// Here I use linq, a feature available on List to check if
// you already have a food at that location in order to prevent doubles
// While it find ANY item in the collection that has the same X and Y it regenerate a new random food.
while(SnakeFoods.Any(snakeFood => snakeFood.X == newFood.X && snakeFood.Y == newFood.Y))
{
newFood = GenerateRandomFood();
}
// when the code get's here the loop above had taken care that
// newFood is not a duplicate so we can add it
SnakeFoods.Add(newFood);
}
// this will just return a new random food without storing it as we dont know if it's good
private Square GenerateRandomFood()
{
int maxXPosition = pictureBox1.Size.Width / GameSetting.Width;
int maxYPosition = pictureBox1.Size.Height / GameSetting.Height;
// just return new random food
return new Square { X = random.Next(0, maxXPosition), Y = random.Next(0, maxYPosition) };
}
绘图部分需要稍作改动,以便在集合上循环并绘制其中的所有食物。
private void UpdateGame(object sender, PaintEventArgs e)
{
Graphics canvas = e.Graphics
// one minor change is to loop to draw all foods (squares)
foreach(Square SnakeFood in SnakeFoods)
{
canvas.FillRectangle(Brushes.Red,
new Rectangle(
SnakeFood.X * GameSetting2.Width2,
SnakeFood.Y * GameSetting2.Width2,
GameSetting2.Width2, GameSetting2.Height2));
}
}
尽管所有这些更改都显示了多个食物源的工作代码,但您仍然需要制定代码来检查您是否吃过一个食物以及如何将其从列表中删除。我把它漏掉了,所以你还有工作要做和要学的东西。
这是一个简单的蛇游戏,但我对蛇食有疑问。我用 generateSnakeFood();
生成了一种新食物并且效果很好,但是当我尝试创建多个蛇食时,它只是在不同的位置重新绘制了一个新的蛇食,这是因为只能有一个 SnakeFood 所以画笔在另一个区域画了一个新的。如果是这样,我该如何解决才能吃到多个相同的蛇食?
private Square SnakeFood = new Square();
private void generateSnakeFood()
{
int maxXPosition = pictureBox1.Size.Width / GameSetting.Width;
int maxYPosition = pictureBox1.Size.Height / GameSetting.Height;
SnakeFood = new Square { X = random.Next(0, maxXPosition), Y = random.Next(0, maxYPosition) };
}
private void UpdateGame(object sender, PaintEventArgs e)
{
Graphics canvas = e.Graphics
canvas.FillRectangle(Brushes.Red,
new Rectangle(
SnakeFood.X * GameSetting2.Width2,
SnakeFood.Y * GameSetting2.Width2,
GameSetting2.Width2, GameSetting2.Height2
));
}
is this because there can only be one of the SnakeFood so the brush paints a new one in another area
是的。即使你做了 new Square
你仍然在重新实例化同一个变量。您代码的绘图部分仅读取 1 个变量并绘制 1 Square
。您将需要使用某种集合,以便获得不同的计数。这也意味着您将需要更改您检测到碰撞的代码以及您吃食物并将其移除的代码。
有很多方法可以实现这一点,可以是使用 List
并像这样更改您的代码
private List<Square> SnakeFoods = new List<Square>();
private void generateSnakeFood()
{
// create new random food using the new method
// doesn't mean it's valid yet
Square newFood = GenerateRandomFood();
// you need to make sure there is not another food at that same location
// in the collection or else you have a duplicate.
// if there is a duplicate you need to generate a new one until it's unique.
// Here I use linq, a feature available on List to check if
// you already have a food at that location in order to prevent doubles
// While it find ANY item in the collection that has the same X and Y it regenerate a new random food.
while(SnakeFoods.Any(snakeFood => snakeFood.X == newFood.X && snakeFood.Y == newFood.Y))
{
newFood = GenerateRandomFood();
}
// when the code get's here the loop above had taken care that
// newFood is not a duplicate so we can add it
SnakeFoods.Add(newFood);
}
// this will just return a new random food without storing it as we dont know if it's good
private Square GenerateRandomFood()
{
int maxXPosition = pictureBox1.Size.Width / GameSetting.Width;
int maxYPosition = pictureBox1.Size.Height / GameSetting.Height;
// just return new random food
return new Square { X = random.Next(0, maxXPosition), Y = random.Next(0, maxYPosition) };
}
绘图部分需要稍作改动,以便在集合上循环并绘制其中的所有食物。
private void UpdateGame(object sender, PaintEventArgs e)
{
Graphics canvas = e.Graphics
// one minor change is to loop to draw all foods (squares)
foreach(Square SnakeFood in SnakeFoods)
{
canvas.FillRectangle(Brushes.Red,
new Rectangle(
SnakeFood.X * GameSetting2.Width2,
SnakeFood.Y * GameSetting2.Width2,
GameSetting2.Width2, GameSetting2.Height2));
}
}
尽管所有这些更改都显示了多个食物源的工作代码,但您仍然需要制定代码来检查您是否吃过一个食物以及如何将其从列表中删除。我把它漏掉了,所以你还有工作要做和要学的东西。