namespace Snake
{
public partial class Form1 : Form
{
Label[] Snake_Body = new Label[500];//巨蟒身体数组,由label实例(标签)构成
Label food = new Label(); //食物
string Keyname = "stop"; //按键状态
int x, y,b=0;
int Snake_Long = 0, Snake_Tail_x, Snake_Tail_y;
Random R = new Random();//随机数
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Makefood();//创建食物
for (int i = 0; i < 5; i++)
{
Label Snaker = new Label();//创造五个初始巨蟒身体实例
Snaker.Height = 10;
Snaker.Width = 10;
Snaker.Top = 300;
Snaker.Left = 150 - i * 10;
Snaker.BackColor = Color.DeepPink;
Snaker.Text = " ";
Snaker.Tag = i;
Snake_Body[i] = Snaker;
this.Controls.Add(Snaker);
}
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Start();
}
private void START_Click(object sender, EventArgs e)
{
Keyname = "start";//开始游戏
}
private void STOP_Click(object sender, EventArgs e)
{
Keyname = "stop";//暂停游戏
}
private void button1_Click(object sender, EventArgs e)//上
{
Keyname = "up";//上
}
private void LEFT_Click(object sender, EventArgs e)
{
Keyname = "left";//左
}
private void RIGHT_Click(object sender, EventArgs e)
{
Keyname = "right";//右
}
private void DOWN_Click(object sender, EventArgs e)
{
Keyname = "down";//下
}
private void timer1_Tick(object sender, EventArgs e)
{
b++;//目前不知道为啥定时器每到时间会进入两次,此处b使每到时间执执行一次
if (b == 10)
b = 0;
if (b % 2 == 1)
{
;
}
else
{
x = Snake_Body[0].Left;
y = Snake_Body[0].Top;
if (Keyname == "start")
{
Snake_Body[0].Left += 10;
}
if (Keyname == "up")
{
Snake_Body[0].Top -= 10;
}
if (Keyname == "down")
{
Snake_Body[0].Top += 10;
}
if (Keyname == "left")
{
Snake_Body[0].Left -= 10;
}
if (Keyname == "right")
{
Snake_Body[0].Left += 10;
}
if (Snake_Body[0].Left >= 450)
{
Snake_Body[0].Left = 0;
}
if (Snake_Body[0].Left < 0)
{
Snake_Body[0].Left = 450;
}
if (Snake_Body[0].Top >= 480)
{
Snake_Body[0].Top = 0;
}
if (Snake_Body[0].Top < 0)
{
Snake_Body[0].Top = 480;
}
if (Keyname != "stop")
{
Snake_Move();
}
if (Snake_Body[0].Left == food.Left && Snake_Body[0].Top == food.Top)//巨蟒吃到食物
{
food.Top = R.Next(0, 47) * 10;
food.Left = R.Next(0, 44) * 10;
Label Snaker = new Label();
Snaker.Height = 10;
Snaker.Width = 10;
Snaker.Top = Snake_Tail_y;
Snaker.Left = Snake_Tail_x;
Snaker.BackColor = Color.DeepPink;
Snaker.Text = " ";
Snaker.Tag = Snake_Long + 1;
Snake_Body[Snake_Long + 1] = Snaker;
this.Controls.Add(Snaker);
}
}
}
public void Snake_Move()//巨蟒移动
{
int i;
Snake_Long = 0;
for (i = 1; Snake_Body[i]!= null; i++)
{
Snake_Long++;
}
textBox2.Text = Convert.ToString(Snake_Long-4);//分数显示
timer1.Interval = (int)(200 - Snake_Long * 10)+1;//随巨蟒长度增加,移动速度加快
Snake_Tail_x = Snake_Body[Snake_Long].Left;
Snake_Tail_y = Snake_Body[Snake_Long].Top;
for (i = Snake_Long; i > 1; i--)
{
Snake_Body[i].Left = Snake_Body[i - 1].Left;
Snake_Body[i].Top = Snake_Body[i - 1].Top;
}
Snake_Body[1].Left = x;
Snake_Body[1].Top = y;
}
public void Makefood()//创造食物实例
{
food.Width = 10;
food.Height = 10;
food.Top = R.Next(0,47) * 10;//食物y位置0-470
food.Left = R.Next(0,44) * 10;//食物x位置0-470
food.Text = " ";
food.BackColor = Color.DarkSlateBlue;
this.Controls.Add(food);
}
}
}
1.timer1_Tick会进入两次是因为你在设计器里双击生成了timer1_Tick事件,那么事件+=的代码是在designer.cs里的
你在load里又手动+=了一次,事件函数绑定了2次
2.timer1.Interval的修改可以在每次吃到东西之后,而不是每次移动一格都去修改它,同理,分数之类的也不需要每个周期都计算
3.你可以使用list来存label,而不要用数组,数组是定长的。就算要维护一个Snake_Long,你把它定义成全局变量,在吃到东西的时候++就行了,每次循环去求它实在没必要
4.报错是报什么错,先分析报错可能原因,然后断点跟,看到底哪一步出错,再对应的改
- 装箱在值类型向引用类型转换时发生,在堆中分配。
- 拆箱在引用类型向值类型转换时发生。
以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:
根据代码,积分指的是巨蟒长度减去4,也就是巨蟒身体数组中非空元素个数减去4。当巨蟒长度小于等于4时,积分为负数或0,不会报错;当巨蟒长度大于4时,积分会大于等于1,直到达到17时会报错。这是因为在计时器事件中,当巨蟒吃到食物时会新建一个巨蟒身体实例并添加到巨蟒身体数组中,但数组的长度只有500,当长度已经达到500时再添加新的实例就会导致数组越界异常。解决方法是在添加新的实例之前先判断数组长度是否已经达到了499,如果是则不再添加新的实例。修改代码如下:
if (Snake_Body[0].Left == food.Left && Snake_Body[0].Top == food.Top)//巨蟒吃到食物
{
food.Top = R.Next(0, 47) * 10;
food.Left = R.Next(0, 44) * 10;
if (Snake_Long < 495) // 添加新的实例前先判断数组长度是否已经达到了499
{
Label Snaker = new Label();
Snaker.Height = 10;
Snaker.Width = 10;
Snaker.Top = Snake_Tail_y;
Snaker.Left = Snake_Tail_x;
Snaker.BackColor = Color.DeepPink;
Snaker.Text = " ";
Snaker.Tag = Snake_Long + 1;
Snake_Body[Snake_Long + 1] = Snaker;
this.Controls.Add(Snaker);
}
}