先看一下游戏规则
这就是游戏规则,大家可以顺着思路往下看,注释很清晰,(小声说话:不写注释是流氓)
先上一张游戏成功截图
设计界面截图(拖了一个imagelist控件,存放了三张图片,一张为红色人物图片,一张为绿色人物图片,一张为两个人物在一起显示的图)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace 飞行棋
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
///
/// 本项目用到的全局变量
///
// 游戏区域
Panel GameMap = new Panel();
// 游戏地图数组
int[] MapList = new int[390];
// 存放地图图片数组
PictureBox[] Mapimg = new PictureBox[390];
PictureBox[] ImageList = new PictureBox[390];
// 每个格子大小
const int MapSize = 30;
// 路的数组
int[] roed = new int[102];
// 随机数对象
Random ran = new Random();
// 人物1的名字
TextBox oneText=new TextBox ();
// 人物2的名字
TextBox twoText = new TextBox();
///
/// 游戏全部道具的数组
///
/// 香蕉皮=back,时空=forword,陷阱=stop,
/// 星星=star,互换位置=huhuan,闪电=gun
int[] back = { 7, 27, 42, 62, 73, 96 };
int[] forword = { 10, 25, 33, 65, 80, 88 };
int[] stop = { 3, 20, 35, 50, 60, 70, 90 };
int[] star = { 5, 28, 45, 71, 85 };
int[] huhuan = { 4, 55, 75, 99 };
int[] gun = { 11, 32, 66, 83 };
// 人物1
Panel person1 = new Panel();
// 人物2
Panel person2 = new Panel();
// 游戏过程记录
RichTextBox Gamejilu = new RichTextBox();
// 骰子
PictureBox shaizi = new PictureBox();
Button namebtn = new Button();
// 窗体加载事件
private void Form1_Load(object sender, EventArgs e)
{
// 主窗体设置
this.Size = new Size(1250,600);
this.FormBorderStyle = FormBorderStyle.FixedSingle;
this.Location = new Point(Screen.PrimaryScreen.Bounds.Width/2-this.Width/2,Screen.PrimaryScreen.Bounds.Height/2-this.Height/2);
this.BackColor = Color.AntiqueWhite;
// 游戏区域大小设置
GameMap.Size = new Size(30*MapSize,13*MapSize);
GameMap.Location = new Point(20,120);
this.Controls.Add(GameMap);
GameMaps();
// 人物背景容器
person1.Size = new Size(80, 80);
person1.BackgroundImage = Image.FromFile("../../img/select_circle.png");
person1.BackgroundImageLayout = ImageLayout.Stretch;
person1.Location = new Point(20,GameMap.Top-90);
this.Controls.Add(person1);
person2.Size = new Size(80, 80);
person2.BackgroundImage = Image.FromFile("../../img/select_circle.png");
person2.BackgroundImageLayout = ImageLayout.Stretch;
person2.Location = new Point(130, GameMap.Top - 90);
this.Controls.Add(person2);
// 人物姓名文本框
oneText.Size = new Size(80,25);
oneText.Location = new Point(20, GameMap.Top - 115);
this.Controls.Add(oneText);
twoText.Size = new Size(80, 25);
twoText.Location = new Point(130, GameMap.Top - 115);
this.Controls.Add(twoText);
// 确定名字按钮
namebtn.Size = new Size(50, 50);
namebtn.Text = "确认姓名";
namebtn.Click += Namebtn_Click;
namebtn.Location = new Point(230, GameMap.Top - 80);
this.Controls.Add(namebtn);
// 添加在容器中的图片
PictureBox picture1 = new PictureBox();
picture1.Size = new Size(60,60);
picture1.Location = new Point(10,10);
picture1.Image = Image.FromFile("../../img/red.png");
picture1.SizeMode = PictureBoxSizeMode.StretchImage;
person1.Controls.Add(picture1);
PictureBox picture2 = new PictureBox();
picture2.Size = new Size(60, 60);
picture2.Location = new Point(10, 10);
picture2.Image = Image.FromFile("../../img/green.png");
picture2.SizeMode = PictureBoxSizeMode.StretchImage;
person2.Controls.Add(picture2);
// 游戏过程文本框设置
Gamejilu.Location = new Point(GameMap.Width+GameMap.Left+10,20);
Gamejilu.Size = new Size(280,500);
Gamejilu.ReadOnly = true;
Gamejilu.Cursor = Cursors.Arrow;
Gamejilu.BorderStyle = BorderStyle.None;
Gamejilu.TabIndex = 1000;
this.Controls.Add(Gamejilu);
// 骰子
shaizi.Size = new Size(100,100);
shaizi.Image = Image.FromFile("../../img/roll.png");
shaizi.SizeMode = PictureBoxSizeMode.StretchImage;
shaizi.Location = new Point(GameMap.Width-80,10);
shaizi.Click += Shaizi_Click;
this.Controls.Add(shaizi);
}
//
private void Namebtn_Click(object sender, EventArgs e)
{
oneText.ReadOnly = true;
twoText.ReadOnly=true;
namebtn.Enabled = false;
GameName[0] = "红方"+oneText.Text;
GameName[1] = "绿方"+twoText.Text;
}
// 判断是红色方还是绿色方
bool[] isPerson = new bool[2]{ true,false};
// 判断暂停的数组
bool[] iszanting = new bool[2] {false,false };
// 记录骰子数
int[] startNum = new int[2];
// 判断是否是比谁先走的掷骰子环节
bool oneplay = true;
// 记录红色方绿色方的位置
int[] PerLocation = new int[2] { -1,- 1 };
// 记录之前的位置
int[] beforeLoca = new int[2] { -1, -1 };
// 存储两 个角色的名字
string[] GameName = new string[2];
///
/// 用来接收游戏过程消息的方法
///
/// 发送的消息文本
private void Message(string str)
{
MessageBox.Show(str);
Gamejilu.AppendText(str+"\r\n");
}
// 游戏开始的点数,判断谁先走
private void Startdice()
{
// 第一次红色方先开始摇
if (isPerson[0])
{
startNum[0]=ran.Next(1,7);
Message(string.Format("{0}摇^|{1}|^点",GameName[0],startNum[0]));
// 红色方摇完后改为false,下次不进这个If
isPerson[0] = !isPerson[0];
}
else
{
// 第二次进这个else ,此时isPerson[0]为false,变为true
isPerson[0] = !isPerson[0];
}
// 第一次isperson[1]为false不进,第二次就变成了true
if (isPerson[1])
{
startNum[1] = ran.Next(1,7);
Message(string.Format("{0}摇出^|{1}|^点",GameName[1],startNum[1]));
// 第二次将isperson[1]变为false
isPerson[1] = !isPerson[1];
}
else
{
// 第一次将isperson[1]改为true
isPerson[1] = !isPerson[1];
}
}
// 单击掷骰子
private void Shaizi_Click(object sender, EventArgs e)
{
if (GameName[0] != null && GameName[1]!=null)
{
Startdice();
StartGame();
}
else
{
MessageBox.Show("请输入红绿方姓名,方可继续游戏");
}
}
// 判断谁先走
private void foregone()
{
if (isPerson[0] && !isPerson[1] && startNum[0] != 0 || startNum[1]!=0)
{
if (startNum[0]==startNum[1])
{
Message("两人点数相同请重新开始摇骰子!");
startNum[0] = 0;
startNum[1] = 0;
}
else
{
oneplay = false;
if (startNum[0]>startNum[1])
{
Message(string.Format("{0}点数大,{0}先行",GameName[0]));
isPerson[0] = true;
isPerson[1] = false;
}
else if(startNum[1]>startNum[0])
{
Message(string.Format("{0}点数大,{0}先行", GameName[1]));
isPerson[1] = true;
isPerson[0] = false;
}
}
}
}
private void StartGame()
{
if (oneplay)
{
foregone();
if (isPerson[0]&&!isPerson[1])
{
Message("请红色方摇骰子");
}
else if (isPerson[1]&&!isPerson[0])
{
Message("请绿色方摇骰子");
}
}
else
{
// 上一步isperson[0]=true,[1]是false,随机完数后变为相反,所以是红色
if (!isPerson[0] && isPerson[1])
{
GameCourse(0);
}
else if(isPerson[0] && !isPerson[1])
{
GameCourse(1);
}
}
}
///
/// 游戏过程(游戏主要逻辑)
///
/// 索引值,0相对应的红色方,1相对应的绿色方
private void GameCourse(int PlayIndex)
{
// -1为初始位置,证明未出门(未出门时)
if (PerLocation[PlayIndex]==-1)
{
switch (startNum[PlayIndex])
{
case 2:
case 4:
Message(string.Format("您摇的点数为{0},可以到起点开始游戏",startNum[PlayIndex]));
beforeLoca[PlayIndex] = 0;
PerLocation[PlayIndex] = 0;
if (PerLocation[0] == PerLocation[1])
{
Mapimg[roed[PerLocation[PlayIndex]]].Image = imageList1.Images[2];
}
else
{
Mapimg[roed[PerLocation[PlayIndex]]].Image = imageList1.Images[PlayIndex];
}
break;
case 6:
beforeLoca[PlayIndex] = PerLocation[PlayIndex];
beforeLoca[PlayIndex] = 0;
PerLocation[PlayIndex] = 0;
Message(string.Format("您摇的点数为{0},可以到起点开始游戏,并且可以在摇一次", startNum[PlayIndex]));
isPerson[PlayIndex] = true;
isPerson[1 - PlayIndex] = false;
break;
default:
Message(string.Format("人物: {0}您摇的点数为{1}不满足到起点的条件哦,下一局{2}开始掷骰子", GameName[PlayIndex], startNum[PlayIndex], GameName[1 - PlayIndex]));
break;
}
// 来到起点之后清空人物大头像
if (PerLocation[0]!=-1)
{
person1.Controls.Clear();
}
if (PerLocation[1]!=-1)
{
person2.Controls.Clear();
}
}
// 出门后
else
{
// 先记录之前自己的位置
beforeLoca[PlayIndex] = PerLocation[PlayIndex];
// 再记录现在自己的位置
PerLocation[PlayIndex] += startNum[PlayIndex];
Message(string.Format("{0}移动{1}步", GameName[PlayIndex], startNum[PlayIndex]));
if (PerLocation[PlayIndex] >= 101)
{
PerLocation[PlayIndex] = 101;
shaizi.Click -= Shaizi_Click;
Message(string.Format("恭喜【{0}】到达终点,鞭炮齐响,锣鼓喧天", GameName[PlayIndex]));
RefreshImg(PlayIndex);
return;
}
// 调用图片刷新方法将之前的位置变为初始时的位置
RefreshImg(PlayIndex);
// 踩到对方时的操作
if (PerLocation[PlayIndex]==PerLocation[1-PlayIndex])
{
Message(string.Format("{0}真牛,成功的把{1}踩回了起点",GameName[PlayIndex],GameName[1 - PlayIndex]));
PerLocation[1 - PlayIndex] = 0;
beforeLoca[PlayIndex] = PerLocation[1 - PlayIndex];
Mapimg[roed[PerLocation[PlayIndex]]].Image = imageList1.Images[PlayIndex];
Mapimg[roed[PerLocation[1 - PlayIndex]]].Image = imageList1.Images[1 - PlayIndex];
Message(string.Format("请{0}开始摇骰子",GameName[1-PlayIndex]));
}
switch (MapList[roed[PerLocation[PlayIndex]]])
{
case 1: // 路
Message("没有障碍物,畅通");
break;
case 2: // 香蕉皮
Message(string.Format("真好{0},踩中香蕉皮倒退6步",GameName[PlayIndex]));
beforeLoca[PlayIndex]=PerLocation[PlayIndex];
PerLocation[PlayIndex] -= 6;
RefreshImg(PlayIndex);
break;
case 3: // 时空传送
Message(string.Format("真好{0},时空传送,前进6步", GameName[PlayIndex]));
beforeLoca[PlayIndex] = PerLocation[PlayIndex];
PerLocation[PlayIndex] += 6;
RefreshImg(PlayIndex);
break;
case 4: //陷阱
Message(string.Format("{0}真牛踩到陷阱了,暂停一回合", GameName[PlayIndex]));
/* 如果红色(0)踩中陷阱,则暂停判断(iszanting)变为false,绿色(1)变为true,这一轮不会进下面暂停判断条件,因为改变的是(1的值),此时进入判断的为红色(0)的值,为false,不满足条件,然后到绿色摇色子阶段,会改变红色摇色子的顺序的(isPerson为true),和自身的摇色子顺序的值(为false),然后到下面的判断时,参数playindex为绿色(1)了,上一步红色踩陷阱时:绿色的暂停判断(iszanting)就已经改变为true,红色变为false,条件满足,执行下面语句块,改变绿色的摇色子顺序(为true),让下一轮继续为绿色摇,红色则改为(false)*/
iszanting[1 - PlayIndex] = true;
iszanting[PlayIndex] = false;
break;
case 5: // 星星
Message(string.Format("{0}真牛踩到星星了,可以再玩一回合",GameName[PlayIndex]));
isPerson[PlayIndex] = true;
isPerson[1 - PlayIndex] = false;
break;
case 6: // 交换
Message(string.Format("恭喜{0}踩到一夜暴富,请根据提示选择",GameName[PlayIndex]));
DialogResult mes= MessageBox.Show("你好啊幸运儿,你可以选择与对方互换位置","幸运儿",MessageBoxButtons.YesNo);
if (mes==DialogResult.Yes)
{
if (PerLocation[1-PlayIndex]!=-1)
{
Message(string.Format("你选择了与{0}交换位置", GameName[1 - PlayIndex]));
int temp = PerLocation[PlayIndex];
PerLocation[PlayIndex] = PerLocation[1 - PlayIndex];
PerLocation[1 - PlayIndex] = temp;
beforeLoca[PlayIndex] = PerLocation[PlayIndex];
beforeLoca[1 - PlayIndex] = PerLocation[1 - PlayIndex];
Mapimg[roed[PerLocation[PlayIndex]]].Image = imageList1.Images[PlayIndex];
Mapimg[roed[PerLocation[1 - PlayIndex]]].Image = imageList1.Images[1 - PlayIndex];
}
else
{
Message("真残忍,对方还没出门呢!");
}
}
else
{
Message(string.Format("你取消了与{0}更换位置的操作", GameName[1 - PlayIndex]));
}
break;
case 7: // 闪电
Message(string.Format("恭喜{0}闪电,请根据提示选择", GameName[PlayIndex]));
DialogResult mes1 = MessageBox.Show("你可以选择是否召唤闪电劈对方", "闪电", MessageBoxButtons.YesNo);
if (mes1 == DialogResult.Yes) {
Message(string.Format("残忍的你选择了用闪电劈{0}", GameName[1 - PlayIndex]));
beforeLoca[1 - PlayIndex] = PerLocation[1 - PlayIndex];
PerLocation[1 - PlayIndex] -= 6;
RefreshImg(1-PlayIndex);
}
break;
default:
break;
}
// 暂停的判断
if (iszanting[PlayIndex]&&!iszanting[1-PlayIndex])
{
isPerson[PlayIndex] = true;
isPerson[1 - PlayIndex] = false;
iszanting[PlayIndex] = false;
iszanting[1 - PlayIndex] = false;
}
}
}
///
/// 图片刷新方法
///
/// 传入要进行操作的人
private void RefreshImg(int Playindex)
{
// 移动后双方在同一位置
if (PerLocation[Playindex]==PerLocation[1-Playindex])
{
// 换为两个飞机的图片
Mapimg[roed[PerLocation[Playindex]]].Image = imageList1.Images[2];
}
else
{
// 没在同一位置,更新移动后的位置图片
Mapimg[roed[PerLocation[Playindex]]].Image = imageList1.Images[Playindex];
}
/*在起点的时候两人在一个位置,下一次某一个人走的时候显示上一个人的图像
用记录之前位置的数组判断,先得满足两个在起点(0)同时满足之前的位置不为-1,
同时满足另一个人还在起点(0)*/
if (beforeLoca[0] == beforeLoca[1] && beforeLoca[0] != -1 && beforeLoca[1] != -1 && PerLocation[1 - Playindex] == 0)
{
// 设置移动的人的前一个位置起点(0),为另一个人的头像
Mapimg[roed[beforeLoca[Playindex]]].Image = imageList1.Images[1-Playindex];
// 然后设置移动的人的新的位置
Mapimg[roed[PerLocation[Playindex]]].Image = imageList1.Images[Playindex];
}
// 移动后两人不在同一位置
else
{
// 判断之前自己的位置在地图数组中是什么就改回什么
switch (MapList[roed[beforeLoca[Playindex]]])
{
case 0:
Mapimg[roed[beforeLoca[Playindex]]].Image = Image.FromFile("../../img/iron.png");
break;
case 1:
Mapimg[roed[beforeLoca[Playindex]]].Image = Image.FromFile("../../img/grass.png");
break;
case 2:
Mapimg[roed[beforeLoca[Playindex]]].Image = Image.FromFile("../../img/xj.jpg");
break;
case 3:
Mapimg[roed[beforeLoca[Playindex]]].Image = Image.FromFile("../../img/sk.jpg");
break;
case 4:
Mapimg[roed[beforeLoca[Playindex]]].Image = Image.FromFile("../../img/xianjing.jpg");
break;
case 5:
Mapimg[roed[beforeLoca[Playindex]]].Image = Image.FromFile("../../img/xx.jpg");
break;
case 6:
Mapimg[roed[beforeLoca[Playindex]]].Image = Image.FromFile("../../img/jh.jpg");
break;
case 7:
Mapimg[roed[beforeLoca[Playindex]]].Image = Image.FromFile("../../img/252.png");
break;
case 10:
Mapimg[roed[beforeLoca[Playindex]]].Image = Image.FromFile("../../img/325.png");
break;
case 11:
Mapimg[roed[beforeLoca[Playindex]]].Image = Image.FromFile("../../img/base.png");
break;
}
}
}
///
/// 游戏地图创建
///
private void GameMaps()
{
Roed();
// 把路相对应的位置给地图数组添加
for (int i = 0; i < roed.Length; i++)
{
MapList[roed[i]] = 1;
}
MapList[roed[0]] = 10; // 起点
MapList[roed[roed.Length-1]] = 11; // 终点
Stageproperty();
// 循环遍历地图数组,用switch判断这个位置为什么东西
for (int i = 0; i < Mapimg.Length; i++)
{
// 每循环一个数组成员创建张地图图片代表
Mapimg[i] = new PictureBox();
Mapimg[i].Size = new Size(MapSize,MapSize);
Mapimg[i].BackgroundImageLayout = ImageLayout.Stretch;
Mapimg[i].SizeMode = PictureBoxSizeMode.StretchImage;
switch (MapList[i])
{
case 0:
Mapimg[i].BackgroundImage = Image.FromFile("../../img/iron.png");
break;
case 1:
Mapimg[i].BackgroundImage = Image.FromFile("../../img/grass.png");
break;
case 2:
Mapimg[i].BackgroundImage = Image.FromFile("../../img/xj.jpg");
break;
case 3:
Mapimg[i].BackgroundImage = Image.FromFile("../../img/sk.jpg");
break;
case 4:
Mapimg[i].BackgroundImage = Image.FromFile("../../img/xianjing.jpg");
break;
case 5:
Mapimg[i].BackgroundImage = Image.FromFile("../../img/xx.jpg");
break;
case 6:
Mapimg[i].BackgroundImage = Image.FromFile("../../img/jh.jpg");
break;
case 7:
Mapimg[i].BackgroundImage = Image.FromFile("../../img/252.png");
break;
case 10:
Mapimg[i].BackgroundImage = Image.FromFile("../../img/325.png");
break;
case 11:
Mapimg[i].BackgroundImage = Image.FromFile("../../img/base.png");
break;
}
// 设置每张图片的位置,
Mapimg[i].Location = new Point(i%30*MapSize,i/30*MapSize);
GameMap.Controls.Add(Mapimg[i]);
}
}
///
/// 路的创建
///
private void Roed()
{
// 第一行向右直到索引为29的第三十个成员
for (int i = 0; i < 30; i++)
{
roed[i] = i;
}
// 然后开始往下五行,第二行的最后一个索引为30-1+30=59
//roed[i-1]拿到上一步的结果加上一整行的个数30个,得到下一行的结果
for (int i = 30; i <= 35; i++)
{
roed[i] = roed[i - 1] + 30;
}
// 走够五行后开始,从第五行的最后一个向左走,索引一直减小1
for (int i = 36; i < 65; i++)
{
roed[i] = roed[i - 1] - 1;
}
for (int i = 65; i <= 70; i++)
{
roed[i] = roed[i - 1] + 30;
}
for (int i = 71; i < 100; i++)
{
roed[i] = roed[i - 1] + 1;
}
for (int i = 100; i < 102; i++)
{
roed[i] = roed[i - 1] - 30;
}
}
///
/// 道具的创建
///
private void Stageproperty()
{
// 香蕉皮退格
for (int i = 0; i < back.Length; i++)
{
MapList[roed[back[i]]] = 2;
}
// 时空前进
for (int i = 0; i < forword.Length; i++)
{
MapList[roed[forword[i]]] = 3;
}
// 暂停回合
for (int i = 0; i < stop.Length; i++)
{
MapList[roed[stop[i]]] = 4;
}
// 增加回合
for (int i = 0; i < star.Length; i++)
{
MapList[roed[forword[i]]] = 5;
}
// 选择互换位置
for (int i = 0; i < huhuan.Length; i++)
{
MapList[roed[huhuan[i]]] = 6;
}
// 打回原点
for (int i = 0; i < gun.Length; i++)
{
MapList[roed[gun[i]]] = 7;
}
}
}
}