------- Windows Phone 7手机开发、.Net培训、期待与您交流! -------
游戏说明:
有一个100格的棋盘(当然也可以自定义200甚至300格),玩家A和玩家B互掷骰子,根据骰子的点数决定前进多少格,最先到达终点的玩家赢。
棋盘上的关卡分为5种:普通(□),幸运轮盘 (◎),地雷(☆),暂停(〓),时空隧道(卐)。
如果“踩”到地雷,玩家倒退6格;
如果到达“幸运轮盘”,玩家可以选择:1.和另一个玩家交换位置,2.前进10格;
如果到达“时空隧道”,玩家一次性前进20格;
如果到达“暂停”,玩家停止掷骰子一次。
游戏的实现(文字)
游戏开始。提示玩家分别输入姓名,姓名不能为空,并且玩家们的姓名不能重名。
关卡的初始化。地图中每一格代表什么关卡,各种不同的关卡在地图中的哪些位置,用什么表示,需要对其进行设置。这里用int数组表示地图,每个元素值是0-5的数字,每个数字代表不同的关卡,绘制地图时,根据元素值判断应输出什么关卡符号。关卡中最多的是普通关卡,所以先将所有格默认为代表普通的0;其他关卡在地图中的位置不只一个,所以分别用数组表示,元素的值就是该关卡在地图中的位置的下标,用循环依次对地图初始化。
绘制地图。地图初始化后,地图数组中的每一个元素的值就确定了,也就是代表什么关卡确定了。根据对元素值进行判断,在屏幕上输出代表的关卡符号,比如幸运轮盘是符号◎、地雷是符号☆。
游戏开始。此时,玩家按任意键掷骰子,根据点数(0-6)决定前进的格数,遇到关卡做相应处理。掷骰子,其实就是更新玩家的位置下标,然后在地图的对应下标的位置输出。
游戏的实现(代码)
首先定义几个数组:
int[] map=newint[100]; //棋盘,默认初始化所有元素为0,map[0]代表第1格,map[1]代表第2格,……map[n]代表n+1格
string[]names=new string[2]; //玩家姓名,names[0]存储玩家A的姓名, names[1]存储玩家B的姓名
int[] playerPos={0,0} //玩家当前位置,初始化玩家A和B都在第1格
说明:
这里定义map长度为100,表示棋盘有100格,每个元素的值代表一个关卡。
map的元素值分别代表 1:幸运轮盘 (◎), 2:地雷(☆), 3:暂停(〓),4:时空隧道(卐),0:普通(□)。
我们接着定义关卡在地图中的位置,对每个关卡定义一个int数组,元素值就是该关卡在地图map中的下标,如下:
//用于存储地图中关卡的下标
int[] luckTurn = { 6, 23, 40, 55, 69, 83, 98 }; //幸运轮盘 1
int[] landMine = { 5, 13, 17, 33, 38, 50, 64, 80, 94 };//地雷2
int[] pause = { 9, 27, 60, 93 }; //暂停的坐标 3
int[] timeTunnel = { 20, 25, 45, 63, 72, 88, 90 }; //时空隧道4
这时就可以初始化地图了,关键代码如下:
//初始化“幸运轮盘”在地图中的位置 for (int i = 0; i < luckTurn.Length; i++) { //pos是luckTurn数组的第i个元素的值 int pos = luckTurn[i]; //pos表示该关卡在map中的位置,所以赋值1 map[pos] = 1; } //初始化“地雷”在地图中的位置 for (int i = 0; i < landMine.Length; i++) { int pos = landMine[i]; map[pos] = 2; } ……
其他关卡代码类似,不一一给出。
绘制地图:
初始化地图后,接下来就该绘制地图了。根据map的下标,判断A和B当前的位置。如果A在当前的位置,打印A;如果B在当前位置,打印B,如果A和B都在当前位置,打印“<>”。A或B都不在当前位置,根据元素值,判断是什么关卡,然后返回符号。代码如下:
/// <summary> /// 根据地图的下标,得到应当打印的关卡字符 /// </summary> /// <param name="pos"></param> static string GetMapString(int pos) { //在数组关卡符号表示 // 1:表幸运轮盘 ◎ // 2:地雷 ☆ // 3:暂停 〓 // 4:时空隧道 卐 // 0:普通 □ string result = ""; if (playerPos[0] == pos && playerPos[1] == pos) //玩家A和玩家B都在当前位置 { Console.ForegroundColor = ConsoleColor.Yellow; //设置控制台的前景色 result = "<>"; } else if (playerPos[0] == pos) //玩家A在当前位置 { Console.ForegroundColor = ConsoleColor.Yellow; result = "A"; } else if (playerPos[1] == pos) //玩家B在当前位置 { Console.ForegroundColor = ConsoleColor.Yellow; result = "B"; } else { switch (map[pos]) { case 0: Console.ForegroundColor = ConsoleColor.White; result = "□"; break; case 1: Console.ForegroundColor = ConsoleColor.Green; result = "◎"; break; case 2: Console.ForegroundColor = ConsoleColor.Red; result = "☆"; break; case 3: Console.ForegroundColor = ConsoleColor.Blue; result = "〓"; break; case 4: Console.ForegroundColor = ConsoleColor.DarkRed; result = "卐"; break; } } return result; }
这段代码可以重用,因此写成函数的形式,100格地图需要打印3行2列,绘制完成后的效果如下:
地图绘制完成,接下来游戏开始,玩家A和玩家B互掷骰子,只要其中一个玩家的位置下标>99,就结束游戏。
利用Rand类的成员方法产生1-6的随机数
Randomr=new Random();
intstep =r.Next(1,7); //r.Next(m,n) 产生一个大于等于m,小于n的随机数
玩家根据骰子数,位置将发生变化。每次玩家的位置发生变化,都要判断是否pos>99或者是否pos<0。如果pos>99,将其位置设为99,表示到达了终点,游戏结束。
playerPos[0] += step; //玩家A的坐标发生了改变,一旦发生了改变,就要判断是否>=99或者是否<0 if (playerPos[0] > 99) { playerPos[0] = 99; //如果超出了棋盘,位置玩家位置在终点 }
然后重绘棋盘,调用DrawMap()方法。
重复以上步骤,直至游戏结束。
完整代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace _01骑士飞行棋 { class Program { //1:地雷,2:暂停,3:幸运轮盘,4:时空隧道 //在map数组中存储我们游戏地图的各个关卡 //数组下标为0的元素对应地图上的第1格,数组下标为1的元素对应第2格...数组下标为n的元素对应第n+1格 //在数组中用 1:表幸运轮盘 ◎ // 2:地雷☆ // 3:暂停〓 // 4:时空隧道卐 // 0:普通 □ static int[] map = new int[100]; static int[] playerPos = { 0, 0 }; //存储玩家的位置,playerPos[0]代表玩家A的位置,playerPos[1]代表玩家B的位置 static void Main(string[] args) { string[] names = new string[2]; //存放玩家姓名的数组,names[0]存放玩家A的姓名,names[1]存放玩家B的姓名 Random r = new Random(); //实例化一个随机数 int step = 0; //存储掷的骰子数 ShowUI(); //显示游戏开始 //提示玩家A输入姓名,非空 Console.WriteLine("请输入玩家A的姓名?"); names[0] = Console.ReadLine(); while (names[0].Length <= 0) { Console.WriteLine("玩家A的姓名不能为空!"); names[0] = Console.ReadLine(); } //提示输入玩家B的姓名,非空且不能和玩家A重名 Console.WriteLine("请输入玩家B的姓名?"); names[1] = Console.ReadLine(); while (names[1].Length <= 0 || names[1] == names[0]) { if (names[1].Length <= 0) { Console.WriteLine("玩家B的姓名不能为空!"); } else if (names[1] == names[0]) { Console.WriteLine("玩家B的姓名不能和玩家A相同!"); } names[1] = Console.ReadLine(); } Console.Clear(); //清屏,相当于“cls”命令 //对战开始 ShowUI(); Console.WriteLine("对战开始!"); Console.WriteLine("{0} 用 A 表示", names[0]); Console.WriteLine("{0} 用 B 表示", names[1]); Console.WriteLine("如果AB在一个位置,用<>表示。"); InitialMap(); //初始化地图 DrawMap(); //绘制地图 Console.WriteLine("游戏开始......"); while (playerPos[0] < 99 && playerPos[1] < 99) { #region 玩家A开始掷骰子 Console.WriteLine("玩家{0}按任意键开始掷骰子...",names[0]); Console.ReadKey(true); //Console.ReadKey(true)表示不在屏幕上显示输入的字符,默认在屏幕上显示输入的字符 step = r.Next(1, 7); Console.WriteLine("玩家{0}掷出了{1}", names[0], step.ToString()); Console.WriteLine("按任意键开始行动......"); Console.ReadKey(true); playerPos[0] += step; //玩家A的坐标发生了改变,一旦发生了改变,就要判断是否>=99或者是否<0 if (playerPos[0] > 99) { playerPos[0] = 99; //如果超出了棋盘,位置玩家位置在终点 } //重绘地图前,清下屏幕 Console.Clear(); //重绘地图 DrawMap(); #endregion #region 玩家B开始掷骰子 #endregion } Console.ReadKey(); } //游戏开始界面 static void ShowUI() { Console.WriteLine("******************************************"); Console.WriteLine("* *"); Console.WriteLine("* 骑 士 飞 行 棋 *"); Console.WriteLine("* *"); Console.WriteLine("******************************************"); } //初始化游戏关卡 static void InitialMap() { //用于存储地图中关卡的下标 int[] luckTurn = { 6, 23, 40, 55, 69, 83, 98 }; //幸运轮盘 1 int[] landMine = { 5, 13, 17, 33, 38, 50, 64, 80, 94 }; //地雷 2 int[] pause = { 9, 27, 60, 93 }; //暂停的坐标 3 int[] timeTunnel = { 20, 25, 45, 63, 72, 88, 90 }; //时空隧道 4 //初始化“幸运轮盘”在地图中的位置 for (int i = 0; i < luckTurn.Length; i++) { //pos是luckTurn数组的第i个元素的值 int pos = luckTurn[i]; //pos表示该关卡在map中的位置,所以赋值1 map[pos] = 1; } //初始化“地雷”在地图中的位置 for (int i = 0; i < landMine.Length; i++) { int pos = landMine[i]; map[pos] = 2; } //初始化“暂停”在地图中的位置 for (int i = 0; i < pause.Length; i++) { int pos = pause[i]; map[pos] = 3; } //初始化“时空隧道”在地图中的位置 for (int i = 0; i < timeTunnel.Length; i++) { int pos = timeTunnel[i]; map[pos] = 4; } } //绘制地图 static void DrawMap() { Console.WriteLine("图例: ◎:幸运轮盘 ☆:地雷 〓:暂停 卐:时空隧道"); //画地图的第一行,绘制下标从0-29的地图 for (int i = 0; i <= 29; i++) { Console.Write(GetMapString(i)); } //第一行地图打印完毕,输出一个换行 Console.WriteLine(); //画第2列地图 for (int i = 30; i <= 34; i++) { //画28个空格 for (int space = 0; space < 29; space++) { //此处打印2个空格,才相当于一个全角字符 Console.Write(" "); } //打印列 Console.WriteLine(GetMapString(i)); } //画第2行地图 for (int i = 64; i >= 35; i--) { Console.Write(GetMapString(i)); } //画完第二行地图,输出一个换行 Console.WriteLine(); //画第2列地图 for (int i = 65; i <= 69; i++) { Console.WriteLine(GetMapString(i)); } //画第3行地图 for (int i = 70; i <= 99; i++) { Console.Write(GetMapString(i)); } //画完第3行地图,输出换行 Console.WriteLine(); } /// <summary> /// 根据地图的下标,得到应当打印的关卡字符 /// </summary> /// <param name="pos"></param> static string GetMapString(int pos) { //在数组关卡符号表示 // 1:表幸运轮盘 ◎ // 2:地雷 ☆ // 3:暂停 〓 // 4:时空隧道 卐 // 0:普通 □ string result = ""; if (playerPos[0] == pos && playerPos[1] == pos) //玩家A和玩家B都在当前位置 { Console.ForegroundColor = ConsoleColor.Yellow; //设置控制台下的前景色 result = "<>"; } else if (playerPos[0] == pos) //玩家A在当前位置 { Console.ForegroundColor = ConsoleColor.Yellow; result = "A"; } else if (playerPos[1] == pos) //玩家B在当前位置 { Console.ForegroundColor = ConsoleColor.Yellow; result = "B"; } else { switch (map[pos]) { case 0: Console.ForegroundColor = ConsoleColor.White; result = "□"; break; case 1: Console.ForegroundColor = ConsoleColor.Green; result = "◎"; break; case 2: Console.ForegroundColor = ConsoleColor.Red; result = "☆"; break; case 3: Console.ForegroundColor = ConsoleColor.Blue; result = "〓"; break; case 4: Console.ForegroundColor = ConsoleColor.DarkRed; result = "卐"; break; } } return result; } } }
未完待续,后续需完善玩家到达关卡后的处理。
------- Windows Phone 7手机开发、.Net培训、期待与您交流! -------