【发布时间】:2025-11-22 17:40:02
【问题描述】:
我已经编写和修改了经典蛇游戏的源代码。随着等级的增加,会生成更多的苹果(例如,等级 1 将生成 1 个苹果,等级 2 将生成 2 个苹果,依此类推。)当我到达 5 级时,生成了 5 个苹果,同时我的进程内存,从 400MB 到 2GB。那就是弹出“ArgumentException”错误并且游戏崩溃的地方。抱歉我的代码不好,因为我还在学习。
显示给我的 draw() 方法的错误,我每 500 毫秒调用一次以刷新板。
Board.cs 中的 draw() 方法发生错误
public void draw(Position p, Image pic)
{
squares[p.getRowNo(), p.getColNo()].Image = pic;
}
form1.cs 中的刷新方法
private void refresh(Object myObject, EventArgs myEventArgs)
{
mySnake.move(mode); //Move the snake based on mode
mainBoard.draw();
apples.draw(); //<----- draw apples
mySnake.draw();
//increment the duration by amount of time that has passed
duration += speed;
timerLBL.Text = Convert.ToString(duration / 1000); //Show time passed
//Check if snake is biting itself. If so, call GameOver.
if (mySnake.checkEatItself() == true)
{
GameOver();
}
else if (apples.checkIFSnakeHeadEatApple( mySnake.getHeadPosition()) == true)
{
score += apples.eatAppleAtPostion(mySnake.getHeadPosition());
scoreLBL.Text = Convert.ToString(score);
if (apples.noMoreApples() == true)
{
EatenAllApple();
clock.Stop();
level++;
gotoNextLevel(level);
MessageBox.Show("Press the start button to go to Level " + level, "Congrats");
}
else
{
//Length the snake and continue with the Game
mySnake.extendBody();
}
}
}
Overal Board.cs
class Board
{
int maxRow = 10, maxCol = 20; //Max 10 rows, and 20 columns in the board
int squareSize = 30; //Each square is 30px by 30px
PictureBox[,] squares;
public Board(Form mainForm)
{
squares = new PictureBox[maxRow, maxCol];
for (int row = 0; row < maxRow; row++)
{
for (int col = 0; col < maxCol; col++)
{
squares[row, col] = new PictureBox();
squares[row, col].Location = new Point(col * squareSize, row * squareSize);
squares[row, col].Height = squareSize;
squares[row, col].Width = squareSize;
squares[row, col].SizeMode = PictureBoxSizeMode.StretchImage;
squares[row, col].BackColor = Color.Black;
squares[row, col].BorderStyle = BorderStyle.FixedSingle;
mainForm.Controls["boardPanel"].Controls.Add(squares[row, col]);
}
}
mainForm.Controls["controlPanel"].Location = new Point(mainForm.Controls["boardPanel"].Location.X, mainForm.Controls["boardPanel"].Location.Y + mainForm.Controls["boardPanel"].Height + 20);
}
//setter
public void setMaxColNo(int x)
{
maxCol = x;
}
public void setMaxRowNo(int x)
{
maxRow = x;
}
//getter
public int getMaxColNo()
{
return maxCol-1; //Last Column No is 19, not 20
}
public int getMaxRowNo()
{
return maxRow-1; //Last Row No is 9, not 10
}
public int getMinColNo()
{
return 0; // 0 is the smallest Col number of the board
}
public int getMinRowNo()
{
return 0; // 0 is the smallest Row number of the board
}
public void draw()
{
for (int row = 0; row < maxRow; row++)
{
for (int col = 0; col < maxCol; col++)
{
squares[row, col].Image = null ;
}
}
}
public void draw(Position p, Image pic)
{
squares[p.getRowNo(), p.getColNo()].Image = pic;
}
}
Rewards.cs(根据@AxelWass 的要求)
class Rewards
{
List<Position> appleList;
Board mainBoard;
public Rewards(int size, Board mainBoard)
{
this.mainBoard = mainBoard;
appleList = new List<Position>();
for (int i=0;i< size;i++)
{
int rowNo, colNo;
//Generate an apple at random position but not duplicated
do
{
//Generate a random number between 1 and MaxRowNo
rowNo = (new Random()).Next(1, mainBoard.getMaxRowNo()+1);
//Generate a random number between 1 and MaxColNo
colNo = (new Random()).Next(1, mainBoard.getMaxColNo()+1);
} while (isDuplicate(rowNo, colNo) == true);
appleList.Add(new Position(rowNo, colNo));
}
}
private Boolean isDuplicate(int row, int col)
{
Boolean result = false;
for (int i=0;i< appleList.Count;i++)
{
if (appleList[i].getRowNo() == row && appleList[i].getColNo() == col)
result = true;
}
return result;
}
public void draw()
{
for (int i = 0; i < appleList.Count; i++)
{
mainBoard.draw(appleList[i], Properties.Resources.apple);
}
}
public Boolean checkIFSnakeHeadEatApple(Position snakeHead)
{
Boolean result = false;
for (int i = 0; i < appleList.Count; i++)
{
if (snakeHead.getRowNo() == appleList[i].getRowNo() && snakeHead.getColNo() == appleList[i].getColNo())
result = true;
}
return result;
}
public Boolean checkIFSnakeEatApple(Position snakeHead)
{
Boolean result = false;
for (int i = 0; i < appleList.Count; i++)
{
if (snakeHead.getRowNo() == appleList[i].getRowNo() && snakeHead.getColNo() == appleList[i].getColNo())
result = true;
}
return result;
}
public int eatAppleAtPostion(Position p)
{
for (int i = 0; i < appleList.Count; i++)
{
if (p.getRowNo() == appleList[i].getRowNo() && p.getColNo() == appleList[i].getColNo())
appleList.RemoveAt(i);
//snakeEatApple();
}
return 50; //50 points per apple
}
public Boolean noMoreApples()
{
if (appleList.Count > 0)
return false;
else
return true;
}
/*public void snakeEatApple()
{
System.Media.SoundPlayer EatenApple = new System.Media.SoundPlayer(Properties.Resources.Eating_Apple);
EatenApple.Play();
}*/
}
【问题讨论】:
-
我认为您没有显示代码的相关部分。问题可能在 apples.draw() 内部。一种常见的设计模式是称为 Repository 的可能会对您有所帮助。您只能为所有苹果实例化一个 Image 并重用它。你能告诉我们苹果类里面的代码吗?谢谢
-
是的,当然...我会编辑我的问题
-
Properties.Resources.apple- 这会在每次调用时反序列化图像,尽量避免这种情况。 -
那么@Caramiriel 你有什么建议?
标签: c# visual-studio-2015 argumentexception