c#控制台实现贪吃蛇
一、 思路
没开发前觉得挺难,一步步做下来后就不觉得难了,当然,只是粗略的实现,速度,地图自定义等都可以再继续优化,代码规划也不好。
贪吃蛇包含:墙,食物,蛇。
墙:初始后固定动,直接按横0纵0,高宽自定打印字符即可。
食物:x,y生成在墙内。
蛇:会动,实际会动的只有蛇头和蛇尾,蛇身每个字符都会经过蛇头的位置,故不需要重新绘制,直接尾-1,头+1;
动的速度,使用睡眠控制即可;
方向:通过方向键获取控制;
吃食物:当蛇头每次睡眠后碰撞检测到的是食物,则多记录一个蛇身位,跳过一次尾巴清除即可。
二、代码实现
1、默认地图(将墙的xy标记为1,非墙标记0)
1 /// <summary> 2 /// 默认地图 3 /// </summary> 4 int[,] getDefaultMap() 5 { 6 int topMax = 30; 7 int leftMax = 100; 8 9 int[,] mapDot = new int[topMax, leftMax]; 10 11 for (int i = 0; i < topMax; i++) 12 { 13 for (int j = 0; j < leftMax; j++) 14 { 15 if (i % (topMax - 1) == 0 || j % (leftMax - 1) == 0) 16 mapDot[i, j] = 1; 17 else 18 mapDot[i, j] = 0; 19 } 20 } 21 22 return mapDot; 23 }
2、生成食物(随机生成地图范围内的x,y)
1 /// <summary> 2 /// 生成食物 3 /// </summary> 4 void generateFood(int topMax, int leftMax) 5 { 6 foodt = new Random().Next(1, topMax - 2); 7 foodl = new Random().Next(1, leftMax - 2); 8 9 Console.ForegroundColor = ConsoleColor.Blue; 10 Console.SetCursorPosition(foodl, foodt); 11 Console.Write("@");//□ 12 Console.ResetColor(); 13 }
3、游戏开始(根据1步骤返回的点,绘制图案,并生成食物,启动蛇)
1 /// <summary> 2 /// 画地图 3 /// </summary> 4 void drawMap() 5 { 6 var mapDots = getDefaultMap(); 7 8 var topMax = mapDots.GetLength(0); 9 var leftMax = mapDots.GetLength(1); 10 11 for (int i = 0; i < topMax; i++) 12 { 13 for (int j = 0; j < leftMax; j++) 14 { 15 if (mapDots[i, j] == 0) continue; 16 17 Console.ForegroundColor = ConsoleColor.Yellow; 18 Console.SetCursorPosition(j, i); 19 Console.Write("#");//□ 20 Console.ResetColor(); 21 22 } 23 } 24 25 //生成食物 26 generateFood(topMax, leftMax); 27 28 //开启蛇跑 29 Task.Run(() => 30 { 31 SnakeGo(topMax / 2, leftMax / 2, topMax, leftMax); 32 }); 33 34 35 }
4、蛇启动后(速度控制,识别撞墙、吃到食物,移动蛇身,增加蛇节点)
1 /// <summary> 2 /// 贪吃蛇开跑 3 /// </summary> 4 void SnakeGo(int x, int y, int maxX, int maxY) 5 { 6 int lastlyx = x; 7 int lastlyy = y; 8 9 snakeDots.Add(new int[] { x, y }); 10 11 while (true) 12 { 13 lastlyx = snakeDots[0][0]; 14 lastlyy = snakeDots[0][1]; 15 16 //第一个点 17 switch (currentDirction) 18 { 19 case "d": 20 ++x; 21 break; 22 case "u": 23 --x; 24 break; 25 case "l": 26 --y; 27 break; 28 case "r": 29 ++y; 30 break; 31 } 32 33 //吃到自己 34 if (snakeDots.Where(o => o[0] == x && o[1] == y).Any()) 35 { 36 Console.SetCursorPosition(maxY / 2, maxX / 2); 37 Console.Write("GMAE OVER"); 38 break; 39 } 40 41 //绘制下一图像 42 Console.SetCursorPosition(y, x); 43 Console.Write("*"); 44 snakeDots.Add(new int[] { x, y }); 45 46 //清掉最后面的图像 47 Console.SetCursorPosition(snakeDots[0][1] + 1, snakeDots[0][0]); 48 Console.Write('\u0008'); 49 Console.Write(" "); 50 snakeDots.RemoveAt(0); 51 52 Thread.Sleep(50); 53 54 //撞到墙壁 55 if (x > maxX - 2 || y > maxY - 2 || x < 1 || y < 1) 56 { 57 Console.SetCursorPosition(maxY / 2, maxX / 2); 58 Console.Write("GMAE OVER"); 59 break; 60 } 61 62 //吃到食物 63 if (x == foodt && y == foodl) 64 { 65 snakeDots.Add(new int[] { foodt, foodl }); 66 if (snakeDots.Count >= 15) 67 { 68 Console.SetCursorPosition(maxY / 2, maxX / 2); 69 Console.Write("GOOD PLAYER"); 70 break; 71 } 72 //重新生成食物 73 generateFood(maxX, maxY); 74 } 75 } 76 }
5、方向控制(初始地图,控制台,全局变量设定)
1 /// <summary> 2 /// 光标不可见 3 /// </summary> 4 Console.CursorVisible = false; 5 /// <summary> 6 /// 初始方向向下 7 /// </summary> 8 string currentDirction = "d"; 9 /// <summary> 10 /// 保存食物坐标 11 /// </summary> 12 int foodt, foodl = 0; 13 /// <summary> 14 /// 保存蛇的节点 15 /// </summary> 16 List<int[]> snakeDots = new System.Collections.Generic.List<int[]>(); 17 //清屏幕 18 Console.Clear(); 19 /// <summary> 20 /// 画地图 21 /// </summary> 22 drawMap(); 23 24 //方向输入控制 25 while (true) 26 { 27 switch (Console.ReadKey().Key) 28 { 29 case ConsoleKey.UpArrow: 30 if (currentDirction != "d") 31 currentDirction = "u"; 32 break; 33 case ConsoleKey.DownArrow: 34 if (currentDirction != "u") 35 currentDirction = "d"; 36 break; 37 case ConsoleKey.LeftArrow: 38 if (currentDirction != "r") 39 currentDirction = "l"; 40 break; 41 case ConsoleKey.RightArrow: 42 if (currentDirction != "l") 43 currentDirction = "r"; 44 break; 45 default: 46 break; 47 } 48 }
三、效果图