练手项目,自己想出来的实现方法
直接上代码
public enum dir //方向枚举
{
moveUp,
moveDown,
moveLeft,
moveRight
}
public class DrawMap //在控制台画二维数组
{
//为什么要用静态变量才能打印出蛇? 因为静态变量是在实例化对象之前就有的,对象通过类方法对这个变
//量的操作会直接改变类里面此静态变量的值 跨类的数据数据互通是时声明为静态变量比较方便
//二维数组表示地图
public static string[,] map = new string[10, 10] {
{ "■","■","■","■","■","■","■","■","■","■" },
{ "■","□","□","□","□","□","□","□","□","■" },
{ "■","□","□","□","□","□","□","□","□","■" },
{ "■","□","□","□","□","□","□","□","□","■" },
{ "■","□","□","□","□","□","□","□","□","■" },
{ "■","□","□","□","□","□","□","□","□","■" },
{ "■","□","□","□","□","□","□","□","□","■" },
{ "■","□","□","□","□","□","□","□","□","■" },
{ "■","□","□","□","□","□","□","□","□","■" },
{ "■","■","■","■","■","■","■","■","■","■" },
};
public static void Draw() //画地图
{
for (int i = 0; i < map.GetLength(0); i++)
{
for (int j = 0; j < map.GetLength(1); j++)
{
Console.Write(map[i, j]);
}
Console.WriteLine();
}
}
}
public class Food
{
private int foodPos_x;
private int foodPos_y;
public static int[] foodPos = new int[2]; //食物的位置
public static bool hadFood = false; //判断地图是否有食物
Random r = new Random();
bool isSame; //判断食物生成的位置是否与蛇身体重合
private void GetRandomPos()
{
foodPos_x = r.Next(1, 8); //生成随机位置
foodPos_y = r.Next(1, 8);
foreach (var item in Snake.bodyList)
{
if (item[0] == foodPos_x && item[1] == foodPos_y) //食物与身体重合
{
isSame = true;
break;
}
else
{
isSame = false;
}
}
if (isSame)
{
GetRandomPos(); //递归 重新生成
}
}
public static void ClearFood() //清除食物
{
DrawMap.map[foodPos[0], foodPos[1]] = "□";
hadFood = false;
}
public void SetFood() //设置食物
{
if (!hadFood)
{
GetRandomPos();
foodPos[0] = foodPos_x;
foodPos[1] = foodPos_y;
DrawMap.map[foodPos[0], foodPos[1]] = "★";
hadFood = true;
}
}
}
public class Input //检测键盘输入
{
public static dir moveDir = dir.moveDown; //运动方向
public static bool isPlayingGame = true; //判断是否结束游戏
public static void GetKey() //获取键盘输入值并给运动方向传值
{
while (true)
{
char key = Console.ReadKey(true).KeyChar;
if (key == 'd')
{
if (moveDir != dir.moveLeft)
moveDir = dir.moveRight;
}
else if (key == 'a')
{
if (moveDir != dir.moveRight)
moveDir = dir.moveLeft;
}
else if (key == 'w')
{
if (moveDir != dir.moveDown)
moveDir = dir.moveUp;
}
else if (key == 's')
{
if (moveDir != dir.moveUp)
moveDir = dir.moveDown;
}
else
{
isPlayingGame = false;
}
}
}
}
public class Snake
{
public static List<int[]> bodyList = new List<int[]>(); //身体
private List<int[]> posList = new List<int[]>(); //记录身体的位置,便于改变身体
private int[] headNode; //头
private int[] tailNode; //尾
private int horizontalPos; //水平位置
private int verticalPos; //垂直位置
private dir moveDir; //运动方向
public static int scores; //吃食物获得分数
public Snake()
{
bodyList.Add(new int[] { 5, 4 }); //初始化蛇身体
bodyList.Add(new int[] { 4, 4 });
bodyList.Add(new int[] { 3, 4 });
foreach (var item in bodyList) //记录蛇身体位置
{
posList.Add(item);
}
headNode = bodyList[0];
tailNode = bodyList[bodyList.Count - 1];
verticalPos = headNode[0];
horizontalPos = headNode[1];
}
public void Move() //实现运动的方法是:移动头,把身体每个位置前移,尾删除。这样只需控制头的位置就可以实现蛇的移动
{
moveDir = Input.moveDir; //方向为默认向下
switch (moveDir) //根据移动方向移动头
{
case dir.moveUp:
verticalPos -= 1;
headNode = new int[] { verticalPos, horizontalPos };
break;
case dir.moveDown:
verticalPos += 1;
headNode = new int[] { verticalPos, horizontalPos };
break;
case dir.moveLeft:
horizontalPos -= 1;
headNode = new int[] { verticalPos, horizontalPos };
break;
case dir.moveRight:
horizontalPos += 1;
headNode = new int[] { verticalPos, horizontalPos };
break;
}
if (headNode[0] == 0 || headNode[0] == 9) //判断头是否接触边界
Input.isPlayingGame = false;
if (headNode[1] == 0 || headNode[1] == 9) //数组是引用类型,不能用List.Contains();
Input.isPlayingGame = false;
foreach (var item in bodyList) //判断头是否接触身体
{
if (headNode[0]==item[0]&&headNode[1]==item[1])
{
Input.isPlayingGame = false;
break;
}
}
if (!headNode.SequenceEqual(Food.foodPos)) //如果头没有碰到食物
{
bodyList[0] = headNode; //把头点赋值给身体的第一个点
int r = 0;
for (int i = 1; i < bodyList.Count; i++) //剩余身体前移
{
bodyList[i] = posList[r];
r++;
}
posList.Clear(); //清空位置信息
foreach (var item in bodyList) //重新记录位置信息
{
posList.Add(item);
int a = item[0];
int b = item[1];
DrawMap.map[a, b] = "■"; //修改地图
}
DrawMap.map[tailNode[0], tailNode[1]] = "□"; //删除尾部
tailNode = bodyList[bodyList.Count - 1]; //设置尾节点
}
else //头碰到食物
{
bodyList[0] = headNode;
Food.ClearFood(); //清除食物
scores += 1;
int r = 0;
for (int i = 1; i < bodyList.Count; i++)
{
bodyList[i] = posList[r];
r++;
}
bodyList.Add(posList[posList.Count - 1]);
posList.Clear();
foreach (var item in bodyList)
{
posList.Add(item);
int a = item[0];
int b = item[1];
DrawMap.map[a, b] = "■";
}
tailNode = bodyList[bodyList.Count - 1];
}
}
}
class Program
{
static void Main(string[] args)
{
Thread getKey = new Thread(Input.GetKey); //用多线程获取玩家输入
Snake snake = new Snake();
Food food = new Food();
getKey.Start();
getKey.IsBackground = true; //是后台线程:主进程结束,线程结束
while (Input.isPlayingGame) //进入游戏
{
food.SetFood(); //设置食物
snake.Move(); //移动蛇
DrawMap.Draw(); //把map画在控制台
Thread.Sleep(500);//主线程休眠0.5秒
Console.Clear(); //清空控制台
}
Console.WriteLine("GameEnd");
Console.WriteLine($"你的分数是{Snake.scores}");
Console.ReadKey();
}
}