您的位置:首页 > 编程语言 > C#

初学C#:贪吃蛇

2016-08-18 21:19 134 查看
最近准备开始学学C#,因为有着C和C++的基础,C#语法和面对对象方面我就大概浏览了一下,然后就开始看窗体部分。书上的窗体部分只讲了控件。。。。于是准备从小游戏写起练习一下

昨天按着网上的代码抄了一遍= =!终于搞懂了这个游戏。今天下午又看了一个代码,于是乎准备自己写啦。

好了,下面说我写的代码

首先先说界面!



添加的控件有两个label(一个也是够的),一个pictureBox,两个button控件。

每个小方格大小为15*15,共有30*30个方格。

于是开始设计窗体和控件的大小和位置

private void Form1_Load(object sender, EventArgs e)
{
// 设计pictureBox1
pictureBox1.Size = new Size(450, 450);
pictureBox1.BackColor = Color.Red;
pictureBox1.Location = new Point(0, 0);
//设计窗体
this.ClientSize = new Size(600, 450);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.FormBorderStyle = FormBorderStyle.FixedDialog;  // 锁定窗体大小
this.KeyPreview = true;   //接收键盘消息
//设计label
label1.Location = new Point(500, 100);
label2.Location = new Point(550, 100);
label2.Text = " ";
//设计button
button1.Location = new Point(475, 200);
button2.Location = new Point(475, 300);
button1.Size = button2.Size = new Size(100, 50);
button1.Text = "开始";
button2.Text = "新的游戏";
//  计时器
timer1.Enabled = true;
timer1.Stop();
sign = 0;
}


昨天看的网上的代码,直接在窗体上画蛇和食物,运行的时候窗体会一闪一闪的。这次用了pictureBox来画图,终于不再闪了。

运行的时候在pictureBox里画30*30个小方格、蛇、食物,一会再贴代码。

根据分析,我写(抄)了三个对象,蛇,食物,”游戏”。

先说蛇这个对象,它的属性有什么? 长度,身体每个点的位置(用list储存),速度
4000
,行进方向,头部的位置,就这些喽。

蛇的身体的点的范围是(0-30,0-30)

首先我们先把蛇的行进方向枚举出来,就是这样

enum SnakeDirection
{
Up, Down, Left, Right
}


然后对象蛇的代码:

class Snake
{
private int length = 0;   //长度
private List<Point> bodisLocation; //身体
private int speed;                //速度
private SnakeDirection snakeDirection = SnakeDirection.Right; //方向
private Point HeadPoint;          //头部

//构造函数,参数为速度,初始长度为5,方向为右
public Snake(int speed)
{
bodisLocation = new List<Point>();
this.speed = speed;
this.length = 5;
for (int i = 4; i >= 0; i--)
{
Point pp = new Point(i, 0);
bodisLocation.Add(pp);
}
HeadPoint = new Point(4, 0);
}

//方法,向 行进方向 行进一步
public void SnakeRun()
{
int size = bodisLocation.Count;
for (int i = size - 1; i > 0; i--)// 行进一个单位后,除头部外,每节身体的位置是未行进前该节身体的前一节的位置
{
bodisLocation[i] = bodisLocation[i - 1];
}
Point head = bodisLocation[0];
switch (snakeDirection)//根据行进方向得到新的头部的位置
{
case SnakeDirection.Down:
head = new Point(head.X, head.Y + 1);
break;
case SnakeDirection.Up:
head = new Point(head.X, head.Y - 1);
break;
case SnakeDirection.Right:
head = new Point(head.X + 1, head.Y);
break;
case SnakeDirection.Left:
head = new Point(head.X - 1, head.Y);
break;
}
bodisLocation[0] = head; //更新头部
length = bodisLocation.Count;  //更新长度
HeadPoint = bodisLocation[0];
}

//属性
public SnakeDirection SnakeDirection  //方向
{
get { return snakeDirection; }
set { snakeDirection = value; }
}
public int Speed  //速度
{
get { return speed; }
set { speed = value; }
}
public int Length  // 长度
{
get { return length; }
set { length = value; }
}
public List<Point> BodisLocation  //身体
{
get { return bodisLocation; }
set { bodisLocation = value; }
}
public Point Head  //头部
{
get { return HeadPoint; }
}

}


然后是食物这个对象,就一个属性,位置,不说了

class Food
{
private Point Position;
public Food()
{
Position = new Point(0, 0);
}
public Point location
{
get { return Position; }
set { Position = value; }
}
}


然后是 “游戏这个对象”

每一个”游戏”的实例代表一局新的游戏,它就只有两个属性,蛇和食物

然后说它的方法

蛇吃掉食物后,肯定要更新一个新的食物,所以写了CreateFood方法,当然判断蛇能不能吃到食物我也写了一个方法。接下来,写一个判断有木有Game Over的方法。就这样了。

class OneGame
{
public Snake snake;
public Food food;
public OneGame()
{
snake = new Snake(150); // 蛇的初始速度定为150
food = new Food();
CreateFood();
}
//方法,制造一个食物
public void CreateFood()
{
Random r = new Random();
int sign = 0;
while(sign==0) //  直到 食物的位置不在蛇身体位置上 结束循环
{
food.location = new Point(r.Next(30), r.Next(30));
foreach(Point pp in snake.BodisLocation)
{
if(food.location==pp)
break;
}
sign = 1;
}
}
//方法,蛇吃食物
public void EatFood()
{
if(snake.BodisLocation[0]==food.location)
{
snake.BodisLocation.Add(food.location);  // 把食物的位置添加进身体里就行
CreateFood();
}
}
//方法,判断是否Game Over;
public bool IsGameOver()
{
for (int i = 1; i < snake.BodisLocation.Count; i++) //遍历身体,如果头部和身体的位置相同,则游戏结束
if (snake.BodisLocation[0] == snake.BodisLocation[i])
return true;
Point pp = snake.Head;
if (pp.X < 0 || pp.X >= 30 || pp.Y < 0 || pp.Y >= 30) // 超出边界则游戏结束
return true;
return false;
}
}


好了,三个对象全部搞定之后,就开始写游戏进行时的部分了

绘图部分全部写在了pictureBox的paint方法里

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
int i, j;
Graphics g = e.Graphics;
SolidBrush mybrush = new SolidBrush(Color.Yellow);
for (i = 0; i < 30; i++)   // 画出背景
for (j = 0; j < 30; j++)
{
Point Start = new Point(i * 15, j * 15);
Size size = new Size(15, 15);
g.FillEllipse(mybrush, new Rectangle(Start, size));
}
foreach(Point pp in myGame.snake.BodisLocation) // 画出蛇
{
i = pp.X;
j = pp.Y;
mybrush = new SolidBrush(Color.Black);
Point Start = new Point(i * 15, j * 15);
Size size = new Size(15, 15);
g.FillEllipse(mybrush, new Rectangle(Start, size));
}
mybrush = new SolidBrush(Color.White); //画出食物
i = myGame.food.location.X;
j = myGame.food.location.Y;
mybrush = new SolidBrush(Color.White);
Point sstart = new Point(i * 15, j * 15);
Size ssize = new Size(15, 15);
g.FillEllipse(mybrush, new Rectangle(sstart, ssize));
}


游戏进行时,计时器根据蛇的速度来发送Tick事件,

在每次Tick事件中,

蛇行进一步,然后判断是否Game OVer,判断是否吃到食物,更新分数,接着pictureBox重绘

private void timer1_Tick(object sender, EventArgs e)
{
myGame.snake.Speed =200- myGame.snake.Length*2;//根据长度增加速度
timer1.Interval = myGame.snake.Speed;
myGame.snake.SnakeRun();    // 蛇行进一步
if(myGame.IsGameOver())   //判断是否game over
{
timer1.Stop();
MessageBox.Show("Game Over!");
myGame = new OneGame();
button1.Text = "开始";
sign = 0;
}
myGame.EatFood();  // 能否吃到食物
label2.Text = myGame.snake.Length.ToString(); /更新分数
pictureBox1.Invalidate();  // pictureBox重绘
}


接着写响应键盘事件,原来写的是方向键来控制方向,结果按下方向键之后,根本不响应,焦点在两个button控件间切来切去,只好换成了wasd= =!

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.
c85b
KeyCode == Keys.W && myGame.snake.SnakeDirection != SnakeDirection.Down)
myGame.snake.SnakeDirection = SnakeDirection.Up;
else if (e.KeyCode == Keys.S && myGame.snake.SnakeDirection != SnakeDirection.Up)
myGame.snake.SnakeDirection = SnakeDirection.Down;
else if (e.KeyCode == Keys.A && myGame.snake.SnakeDirection != SnakeDirection.Right)
myGame.snake.SnakeDirection = SnakeDirection.Left;
else if (e.KeyCode == Keys.D && myGame.snake.SnakeDirection != SnakeDirection.Left)
myGame.snake.SnakeDirection = SnakeDirection.Right;

}


剩下两个button的点击事件我就不说了,直接上代码

private void button1_Click(object sender, EventArgs e)// 开始 and 暂停 按钮
{
if (sign == 0)  //  按下了 开始
{
sign = 1;
timer1.Start();
button1.Text = "暂停";
}
else             //   按下了 暂停
{
sign = 0;
timer1.Stop();
button1.Text = "开始";
}
}
private void button2_Click(object sender, EventArgs e) //按下  新游戏  按钮
{
timer1.Stop();           //计时器停止
myGame = new OneGame();  // 重新
sign = 0;
button1.Text = "开始";
pictureBox1.Invalidate();
}


然后就没了。。。表达能力不强,只能写到这里了。刚开始学,肯定有不足的地方或者Bug,欢迎指正= =

欢迎加我QQ一起学习1594205849
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: