這兩天花了點時間寫了貪吃蛇這個小程式,現在將大體的設計流程說明一下,來源程式請在www.csdn.net下載,我的使用者名稱為andamajing。
簡單的分析一下,貪吃蛇從總體上說顯示和控制兩大部分,第一方面顯示部分包含表單的整體布局,遊戲活動部分的顯示,以及得分的顯示,遊戲協助和關於這個遊戲的說明;第二方面是控制部分,控制部分包含遊戲中蛇和食物的顏色設定,開始,暫停,停止等控制按鍵以及方向鍵的控制。
首先對於蛇,我們需要定義一個類,這個類包含蛇的組成單元及大小,蛇的顏色,蛇的長度和蛇的運動方向等基本欄位,蛇的移動,吃食物等基本方法,以及是否死亡等標識。具體定義如下:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Drawing;using System.Windows.Forms;using System.Collections;namespace SnakeGame{ class Snake { //蛇身單元 private Label bodyCeil; //蛇身單元大小 static private Size size=new Size(10,10); //蛇身顏色 public Color snakeColor; //蛇身鏈表 ArrayList snake = new ArrayList(); //蛇身長度 private int snakeLength=5; public int SnakeLength { get { return snake.Count; } } //蛇運動方向,初始向右 private Direction snakeDirection=Direction.Right; public Direction SnakeDirection { get { return snakeDirection; } set { snakeDirection=value; } } //食物是否吃完標誌 private bool flag = false; public bool Flag { get { return flag; } set { flag = value; } } //畫初始蛇體 private void DrawBeginSnake() { for (int i = 0; i < 5; i++) { bodyCeil = new Label(); bodyCeil.BackColor = snakeColor; bodyCeil.Size = size; bodyCeil.Location = new Point(40 - i * 10, 0); bodyCeil.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; snake.Add(bodyCeil); } } //帶參數的建構函式,可設定蛇身顏色 public Snake(Color newcolor) { snakeColor = newcolor; DrawBeginSnake(); } //返回蛇體 public ArrayList GetSnake() { return snake; } //是否有食物標誌 private bool hasFood = false; //定義蛇是否死亡標誌,true為死亡,false為沒死 private bool isDead = false; public bool IsDead { get { return isDead; } } //蛇移動 public void Move(System.Windows.Forms.Control control,Label food) { if (!hasFood) { control.Controls.Remove(control.GetChildAtPoint(((Label)snake[snake.Count-1]).Location)); snake.RemoveAt(snake.Count - 1); } Label snakeHead = new Label(); CopySnakeBodyCeil(snakeHead, (Label)snake[0]); switch (snakeDirection) { case Direction.Up: snakeHead.Top -= 10; if (snakeHead.Top < 0) isDead = true; break; case Direction.Down: snakeHead.Top += 10; if (snakeHead.Top > 270) isDead = true; break; case Direction.Left: snakeHead.Left-= 10; if (snakeHead.Left < 0) isDead = true; break; case Direction.Right: snakeHead.Left+= 10; if (snakeHead.Left > 340) isDead = true; break; } snake.Insert(0, snakeHead); if (hasFood) { hasFood = false; control.Controls.Remove(control.GetChildAtPoint(food.Location)); //control.Controls.Clear(); this.flag = true; } } //複製蛇單元 private void CopySnakeBodyCeil(Label to, Label from) { to.BackColor = from.BackColor; to.Size = from.Size; to.Location = from.Location; to.BorderStyle = from.BorderStyle; } //判斷是否有食物標誌 public void EatFood(Label _food) { switch (snakeDirection) { case Direction.Up: if (((Label)snake[0]).Left == _food.Left && ((Label)snake[0]).Top == _food.Top + 10) hasFood = true; else hasFood = false; break; case Direction.Down: if (((Label)snake[0]).Left == _food.Left && ((Label)snake[0]).Top == _food.Top - 10) hasFood = true; else hasFood = false; break; case Direction.Left: if (((Label)snake[0]).Left == _food.Left + 10 && ((Label)snake[0]).Top == _food.Top) hasFood = true; else hasFood = false; break; case Direction.Right: if (((Label)snake[0]).Left == _food.Left - 10 && ((Label)snake[0]).Top == _food.Top ) hasFood = true; else hasFood = false; break; } } }}
接下來就是食物的定義了,具體第一如下:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Windows.Forms;using System.Drawing;namespace SnakeGame{ class Food { //定義一個食物 private Label foodCeil=new Label(); public Label FoodCeil { get { return foodCeil; } set { foodCeil = value; } } //定義食物的顏色 private Color foodColor; public Color FoodColor { get { return foodColor; } } //定義食物位置 private Point foodLocation; public Point FoodLocation { get { return new Point(foodCeil.Top, foodCeil.Left); } } //定義食物的大小 private static Size foodSize = new Size(10, 10); //建構函式, public Food(Color color,Point point) { foodCeil.Size = foodSize; foodCeil.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; foodCeil.BackColor = color; foodCeil.Left = point.X; foodCeil.Top = point.Y; foodColor = color; } //複製食物單元 public void CopyFoodCeil(Label to, Label from) { to.BackColor = from.BackColor; to.Size = from.Size; to.Location = from.Location; to.BorderStyle = from.BorderStyle; } }}
上面兩個類定義了這個遊戲中的兩個對象,接下來就需要在主題的顯示介面中去控制蛇的運動,主題的介面如下所示:
啟動並執行介面如下所示:
遊戲結束的畫面如下:
設定顏色的表單顯示如下:
接下來說一下主程式中控製程序,在程式中控制功能表項和按鍵如何進行處理。
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using SnakeGame.Properties;namespace SnakeGame{ public partial class FormSnakeGame : Form { //定義一個蛇 private Snake mySnake; //定義一個食物 private Food myFood; //定義蛇顏色 private Color mySnakeColor; //定義食物顏色 private Color myFoodColor; //定義一個顏色設定視窗 顏色設定 gameColorSetting =new 顏色設定(); public FormSnakeGame() { InitializeComponent(); this.buttonStop.Enabled = false; ClearDirection(); this.低水平ToolStripMenuItem.Checked = true; this.panelGame.BackgroundImage = Resources.myblog; } private void 遊戲說明ToolStripMenuItem1_Click(object sender, EventArgs e) { 遊戲操作 gameOperationInformation = new 遊戲操作(); gameOperationInformation.Show(); } private void 關於ToolStripMenuItem_Click(object sender, EventArgs e) { 關於 gameAbout = new 關於(); gameAbout.Show(); } private void 退出ToolStripMenuItem_Click(object sender, EventArgs e) { this.Close(); } private void 顏色設定ToolStripMenuItem_Click(object sender, EventArgs e) { //gameColorSetting = new 顏色設定(); gameColorSetting.Show(); } //停止或暫停按鍵按下 private static int i = 0;//用於判斷顯示Stop還是顯示Continue private void buttonStop_Click(object sender, EventArgs e) { if (i++ % 2 == 0) { this.buttonStop.Text = "Continue"; this.timerSnakeSpeed.Enabled = false; } else { this.buttonStop.Text = "Stop"; this.timerSnakeSpeed.Enabled = true; } } //開始按鍵按下 private void buttonStart_Click(object sender, EventArgs e) { this.panelGame.BackgroundImage = null; this.buttonStart.Enabled = false; EnableDirection(); mySnakeColor = gameColorSetting.SetSnakeColor; myFoodColor = gameColorSetting.SetFoodColor; this.buttonStop.Enabled = true; mySnake = new Snake(mySnakeColor); foreach (Label lbl in mySnake.GetSnake()) { this.panelGame.Controls.Add(lbl); } myFood = new Food(myFoodColor,new Point(100,100)); this.panelGame.Controls.Add(myFood.FoodCeil); this.myFood.CopyFoodCeil(currentfood, this.myFood.FoodCeil); this.timerSnakeSpeed.Enabled = true;//啟動計時器 } //畫蛇函數 private void DrawSnake(Snake _newsnake) { foreach (Label lbl in _newsnake.GetSnake()) { this.panelGame.Controls.Add(lbl); } } //定義一個Label存放當前食物 Label currentfood = new Label(); //發放食物 private void PutFood() { Random randfood = new Random(); int newfoodx = randfood.Next(35); int newfoody = randfood.Next(28); Label newfood = new Label(); this.myFood.CopyFoodCeil(newfood, currentfood); newfood.Left = newfoodx*10; newfood.Top = newfoody*10; this.panelGame.Controls.Remove(this.myFood.FoodCeil); this.panelGame.Controls.Add(newfood); this.myFood.CopyFoodCeil(this.myFood.FoodCeil, newfood); this.myFood.CopyFoodCeil(currentfood, newfood); } //畫食物函數 private void DrawFood(Label newfood) { this.panelGame.Controls.Add(newfood); } //移除食物 private void RemoveFood(Label oldfood) { this.panelGame.Controls.Remove(oldfood); } //計時器函數 private void timerSnakeSpeed_Tick(object sender, EventArgs e) { mySnake.EatFood(this.myFood.FoodCeil); mySnake.Move(this.panelGame,this.myFood.FoodCeil); DrawSnake(mySnake); if (this.mySnake.IsDead) { this.buttonStart.Enabled = true; this.buttonStop.Enabled = false; this.timerSnakeSpeed.Enabled = false; ClearColor(); ClearDirection(); this.textBoxScore.Text = ""; this.panelGame.Controls.Clear(); this.panelGame.BackgroundImage = Resources.gameover1; } if (mySnake.Flag) { PutFood(); mySnake.Flag = false; } this.textBoxScore.Text = ((mySnake.SnakeLength - 5) * 10).ToString(); } //清除水平選擇標誌 private void ClearFlag() { this.低水平ToolStripMenuItem.Checked = false; this.普通水平ToolStripMenuItem.Checked = false; this.高水平ToolStripMenuItem.Checked = false; } //選擇普通水平 private void 普通水平ToolStripMenuItem_Click(object sender, EventArgs e) { ClearFlag(); this.普通水平ToolStripMenuItem.Checked = true ; this.timerSnakeSpeed.Interval = 300; } private void 高水平ToolStripMenuItem_Click(object sender, EventArgs e) { ClearFlag(); this.高水平ToolStripMenuItem.Checked = true; this.timerSnakeSpeed.Interval = 200; } private void 低水平ToolStripMenuItem_Click(object sender, EventArgs e) { ClearFlag(); this.低水平ToolStripMenuItem.Checked = true; this.timerSnakeSpeed.Interval = 400; } //按鍵處理常式 private void FormSnakeGame_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar == 'a' || e.KeyChar == 'A') { this.mySnake.SnakeDirection=(this.mySnake.SnakeDirection==Direction.Right?Direction.Right:Direction.Left); ClearColor(); this.buttonKeyA.BackColor = Color.Blue; } else if (e.KeyChar == 'd' || e.KeyChar == 'D') { this.mySnake.SnakeDirection = (this.mySnake.SnakeDirection == Direction.Left ? Direction.Left : Direction.Right); ClearColor(); this.buttonKeyD.BackColor = Color.Blue; } else if (e.KeyChar == 'w' || e.KeyChar == 'W') { this.mySnake.SnakeDirection = (this.mySnake.SnakeDirection == Direction.Down ? Direction.Down : Direction.Up); ClearColor(); this.buttonKeyW.BackColor = Color.Blue; } else if (e.KeyChar == 's' || e.KeyChar == 'S') { this.mySnake.SnakeDirection = (this.mySnake.SnakeDirection == Direction.Up ? Direction.Up : Direction.Down); ClearColor(); this.buttonKeyS.BackColor = Color.Blue; } else { e.Handled = true; } } //W鍵按下 private void buttonKeyW_Click(object sender, EventArgs e) { this.mySnake.SnakeDirection = (this.mySnake.SnakeDirection == Direction.Down ? Direction.Down : Direction.Up); ClearColor(); this.buttonKeyW.BackColor = Color.Blue; } //A鍵按下 private void buttonKeyA_Click(object sender, EventArgs e) { this.mySnake.SnakeDirection = (this.mySnake.SnakeDirection == Direction.Right ? Direction.Right : Direction.Left); ClearColor(); this.buttonKeyA.BackColor = Color.Blue; } //S鍵按下 private void buttonKeyS_Click(object sender, EventArgs e) { this.mySnake.SnakeDirection = (this.mySnake.SnakeDirection == Direction.Up ? Direction.Up : Direction.Down); ClearColor(); this.buttonKeyS.BackColor = Color.Blue; } //D鍵按下 private void buttonKeyD_Click(object sender, EventArgs e) { this.mySnake.SnakeDirection = (this.mySnake.SnakeDirection == Direction.Left ? Direction.Left : Direction.Right); ClearColor(); this.buttonKeyD.BackColor = Color.Blue; } //清除方向鍵背景顏色 private void ClearColor() { this.buttonKeyW.BackColor = System.Windows.Forms.Button.DefaultBackColor; this.buttonKeyA.BackColor = System.Windows.Forms.Button.DefaultBackColor; this.buttonKeyS.BackColor = System.Windows.Forms.Button.DefaultBackColor; this.buttonKeyD.BackColor = System.Windows.Forms.Button.DefaultBackColor; } //方向鍵不可用 private void ClearDirection() { this.buttonKeyA.Enabled = false; this.buttonKeyW.Enabled = false; this.buttonKeyD.Enabled = false; this.buttonKeyS.Enabled = false; } //方向鍵可用 private void EnableDirection() { this.buttonKeyA.Enabled = true; this.buttonKeyW.Enabled = true; this.buttonKeyD.Enabled = true; this.buttonKeyS.Enabled = true; } }}
上面簡單的介紹了一下貪吃蛇的編程,大家相互交流,呵呵....