C#贪吃蛇

发布于:2024-05-10 ⋅ 阅读:(26) ⋅ 点赞:(0)

C#贪吃蛇

image-20240509004231468
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Program.cs

using 贪吃蛇.Text1;

Game game = new Game();
game.start();

Text1

Game.cs
using 贪吃蛇.Text2;

namespace 贪吃蛇.Text1
{
    enum E_SceneType
    {
        Begin,
        Game,
        End,
    }
    internal class Game
    {
        public const int w = 80;
        public const int h = 20;

        public static ISceneUpdate nowScene;

        public Game()
        {
            Console.CursorVisible = false;
            Console.SetWindowSize(w, h);
            Console.SetBufferSize(w, h);

            ChangeScene(E_SceneType.Begin);
        }

        public void start()
        {
            while (true)
            {
                if (nowScene != null)
                {
                    nowScene.Update();
                }
            }
        }

        public static  void ChangeScene(E_SceneType type)
        {
            Console.Clear();
            switch (type)
            {
                case E_SceneType.Begin:
                    nowScene = new BeginScene();
                    break;
                case E_SceneType.Game:
                    nowScene = new GameScene();
                    break;
                case E_SceneType.End:
                    nowScene = new EndScene();
                    break;
            }
        }
    }
}
ISceneUpdate.cs
namespace 贪吃蛇.Text1
{
    /// <summary>
    /// 场景更新接口
    /// </summary>
    internal interface ISceneUpdate
    {
        void Update();
    }
}

Text2

BeginScene.cs
using 贪吃蛇.Text1;

namespace 贪吃蛇.Text2
{
    internal class BeginScene : BegionOrEndScene
    {
        public BeginScene()
        {
            strTitle = "贪吃蛇";
            strOne = "开始游戏";
        }
        public override void EnterJDoSomthing()
        {
            if (nowSelIndex == 0)
            {
                Game.ChangeScene(E_SceneType.Game);
            }
            else
            {
                Environment.Exit(0);
            }
        }
    }
}
BegionOrEndScene.cs
using 贪吃蛇.Text1;

namespace 贪吃蛇.Text2
{
    abstract internal class BegionOrEndScene : ISceneUpdate
    {
        protected int nowSelIndex = 0;
        protected string strTitle;
        protected string strOne;

        public abstract void EnterJDoSomthing();
        public void Update()
        {
            Console.ForegroundColor = ConsoleColor.White;
            Console.SetCursorPosition(Game.w / 2 - strTitle.Length, 5);
            Console.Write(strTitle);

            Console.SetCursorPosition(Game.w / 2 - strOne.Length, 8);
            Console.ForegroundColor = nowSelIndex == 0 ? ConsoleColor.Red : ConsoleColor.White;
            Console.Write(strOne);

            Console.SetCursorPosition(Game.w / 2 - 4, 10);
            Console.ForegroundColor = nowSelIndex == 1 ? ConsoleColor.Red : ConsoleColor.White;
            Console.Write("结束游戏");

            switch(Console.ReadKey(true).Key)
            {
                case ConsoleKey.W:
                    nowSelIndex--;
                    if (nowSelIndex < 0)
                    {
                        nowSelIndex = 1;
                    }
                    break;
                case ConsoleKey.S:
                    nowSelIndex++;
                    if (nowSelIndex > 1)
                    {
                        nowSelIndex = 0;
                    }
                    break;
                case ConsoleKey.J:
                    EnterJDoSomthing();
                    break;
            }
        }
    }
}
EndScene.cs
using 贪吃蛇.Text1;

namespace 贪吃蛇.Text2
{
    internal class EndScene : BegionOrEndScene
    {
        public EndScene()
        {
            strTitle = "结束游戏";
            strOne = "回到开始界面";
        }
        public override void EnterJDoSomthing()
        {
            if(nowSelIndex == 0)
            {
                Game.ChangeScene(E_SceneType.Begin);
            }
            else
            {
                Environment.Exit(0);
            }
        }
    }
}
GameScene.cs
using 贪吃蛇.Text1;
using 贪吃蛇.Text4;
using 贪吃蛇.Text5;
using 贪吃蛇.Text6;

namespace 贪吃蛇.Text2
{
    internal class GameScene : ISceneUpdate
    {
        Map map;
        Snake snake;
        Food food;

        int updateIndex = 0;
        public GameScene()
        {
            map = new Map();
            snake = new Snake(40,10);
            food = new Food(snake);
        }
        public void Update()
        {
            if (updateIndex % 4444 == 0)
            {
                map.Draw();
                food.Draw();
                snake.Move();
                snake.Draw();

                if (snake.CheckEnd(map))
                {
                    Game.ChangeScene(E_SceneType.End);
                }
                //蛇吃食物
                snake.CheckEatFood(food);

                updateIndex = 0;
            }
            updateIndex++;
            //Console.KeyAvailable判断键盘有没有输入,如果有为ture
            if (Console.KeyAvailable)
            {
                switch (Console.ReadKey(true).Key)
                {
                    case ConsoleKey.W:
                        snake.ChangeDir(E_MoveDir.up);
                        break;
                    case ConsoleKey.S:
                        snake.ChangeDir(E_MoveDir.down);
                        break;
                    case ConsoleKey.A:
                        snake.ChangeDir(E_MoveDir.left);
                        break;
                    case ConsoleKey.D:
                        snake.ChangeDir(E_MoveDir.right);
                        break;
                }
            }
        }
    }
}

Text3

GameObject.cs
namespace 贪吃蛇.Text3
{
    abstract internal class GameObject : IDraw
    {
        public Position pos;
        public abstract void Draw();
    }
}
IDraw.cs
namespace 贪吃蛇.Text3
{
    internal interface IDraw
    {
        void Draw();
    }
}
Position.cs
namespace 贪吃蛇.Text3
{
    internal struct Position
    {
        public int x; public int y;
        public Position(int x, int y)
        {
            this.x = x;
            this.y = y;
        }

        public static bool operator ==(Position p1, Position p2)
        {
            if (p1.x == p2.x && p1.y == p2.y)
            {
                return true;
            }
            return false;
        }
        public static bool operator !=(Position p1, Position p2)
        {
            if (p1.x == p2.x && p1.y == p2.y)
            {
                return false;
            }
            return true;
        }
    }
}

Text4

Food.cs
using 贪吃蛇.Text1;
using 贪吃蛇.Text3;
using 贪吃蛇.Text6;

namespace 贪吃蛇.Text4
{
    internal class Food : GameObject
    {
        public Food(Snake snake)
        {
            RandomPos(snake);
        }
        public override void Draw()
        {
            Console.SetCursorPosition(pos.x,pos.y);
            Console.ForegroundColor = ConsoleColor.Cyan;
            Console.Write("◆");
        }
        //随机食物位置
        public void RandomPos(Snake snake)
        {
            //得到蛇位置信息
            Random random = new Random();
            int x = random.Next(2, Game.w / 2 - 1) * 2;
            int y = random.Next(1, Game.h - 2);
            pos = new Position(x,y);
            if (snake.CheckFoodPos(pos))
            {
                //再随机
                RandomPos(snake);
            }
        }
    }
}
SnakeBody.cs
using 贪吃蛇.Text3;

namespace 贪吃蛇.Text4
{
    enum E_SnakeBody_Type
    {
        Head,
        Body,
    }
    internal class SnakeBody : GameObject
    {
        private E_SnakeBody_Type type;

        public SnakeBody(E_SnakeBody_Type type,int x,int y)
        {
            this.type = type;
            pos = new Position(x,y);
        }
        public override void Draw()
        {
            Console.SetCursorPosition(pos.x, pos.y);
            Console.ForegroundColor = type == E_SnakeBody_Type.Head ? ConsoleColor.Yellow : ConsoleColor.Green;
            Console.Write(type == E_SnakeBody_Type.Head ? "●" : "⊙");
        }
    }
}
Wall.cs
using 贪吃蛇.Text3;

namespace 贪吃蛇.Text4
{
    internal class Wall : GameObject
    {
        public Wall(int x, int y)
        {
            pos = new Position(x, y);
        }
        public override void Draw()
        {
            Console.SetCursorPosition(pos.x, pos.y);
            Console.ForegroundColor = ConsoleColor.Red;
            Console.Write("■");
        }
    }
}

Text5

Map.cs
using 贪吃蛇.Text1;
using 贪吃蛇.Text3;
using 贪吃蛇.Text4;

namespace 贪吃蛇.Text5
{
    internal class Map : IDraw
    {
        public Wall[] Walls;
        public Map()
        {
            Walls = new Wall[Game.w + (Game.h - 3) * 2];
            int index = 0;
            for (int i = 0; i < Game.w; i += 2)
            {
                Walls[index] = new Wall(i, 0);
                index++;
            }
            for (int i = 0; i < Game.w; i += 2)
            {
                Walls[index] = new Wall(i, Game.h - 2);
                index++;
            }
            for (int i = 1; i < Game.h - 2; i++)
            {
                Walls[index] = new Wall(0, i);
                index++;
            }
            for (int i = 1; i < Game.h - 2; i++)
            {
                Walls[index] = new Wall(Game.w - 2, i);
                index++;
            }
        }

        public void Draw()
        {
            for (int i = 0; i < Walls.Length; i++)
            {
                Walls[i].Draw();
            }
        }
    }
}

Text6

Snake.cs
using 贪吃蛇.Text3;
using 贪吃蛇.Text4;
using 贪吃蛇.Text5;

namespace 贪吃蛇.Text6
{
    enum E_MoveDir
    {
        up,
        down,
        left,
        right,
    }
    internal class Snake : IDraw
    {
        SnakeBody[] bodys;
        //记录蛇长度
        int nowNum;
        //当前移动方向
        E_MoveDir moveDir;
        public Snake(int x, int y)
        {
            bodys = new SnakeBody[100];
            bodys[0] = new SnakeBody(E_SnakeBody_Type.Head, x, y);
            nowNum = 1;
            moveDir = E_MoveDir.right;
        }
        public void Draw()
        {
            for (int i = 0; i < nowNum; i++)
            {
                bodys[i].Draw();
            }
        }

        public void Move()
        {
            //移动前擦除最后一个位置
            SnakeBody lastBody = bodys[nowNum - 1];
            Console.SetCursorPosition(lastBody.pos.x, lastBody.pos.y);
            Console.Write("  ");

            //蛇头移动前,从蛇尾开始位置依次向前替代
            for (int i = nowNum - 1; i > 0; i--)
            {
                bodys[i].pos = bodys[i - 1].pos;
            }

            switch (moveDir)
            {
                case E_MoveDir.up:
                    --bodys[0].pos.y;
                    break;
                case E_MoveDir.down:
                    ++bodys[0].pos.y;
                    break;
                case E_MoveDir.left:
                    bodys[0].pos.x -= 2;
                    break;
                case E_MoveDir.right:
                    bodys[0].pos.x += 2;
                    break;
            }
        }

        public void ChangeDir(E_MoveDir dir)
        {
            if (dir == moveDir || nowNum > 1 && (
                moveDir == E_MoveDir.left && dir == E_MoveDir.right ||
                moveDir == E_MoveDir.right && dir == E_MoveDir.left ||
                moveDir == E_MoveDir.up && dir == E_MoveDir.down ||
                moveDir == E_MoveDir.down && dir == E_MoveDir.up))
            {
                return;
            }
            moveDir = dir;
        }

        public bool CheckEnd(Map map)
        {
            for (int i = 0; i < map.Walls.Length; i++)
            {
                if (bodys[0].pos == map.Walls[i].pos)
                {
                    return true;
                }
            }
            for (int i = 1; i < nowNum; i++)
            {
                if (bodys[0].pos == bodys[i].pos)
                {
                    return true;
                }
            }
            return false;
        }

        public bool CheckFoodPos(Position p)
        {
            for (int i = 0; i < nowNum; i++)
            {
                if (bodys[i].pos == p)
                {
                    return true;
                }
            }
            return false;
        }
        public void CheckEatFood(Food food)
        {
            if (bodys[0].pos == food.pos)
            {
                //吃到食物再随机
                food.RandomPos(this);

                //长身体
                AddBody();
            }
        }

        private void AddBody()
        {
            SnakeBody frontBody = bodys[nowNum - 1];
            bodys[nowNum] = new SnakeBody(E_SnakeBody_Type.Body, frontBody.pos.x, frontBody.pos.y);
            nowNum++;
        }
    }
}

网站公告

今日签到

点亮在社区的每一天
去签到