C#核心实践小项目--贪吃蛇(自己实现)

发布时间:2024年01月12日

贪吃蛇

本篇文章是先不看老师教程的情况下,自己独立来完成的,顺便记录一下实现的过程。

项目展示

方向控制:WSAD

确定键:J

需求分析(UML类图)

UML类图是老师提供的,因为以我现在的能力还画不出逻辑这么清晰的UML类图!

补充知识点:

检测键盘是否激活

Console.KeyAvailable == true;

注意使用后会使程序变慢,具体为什么我还不得而知,后面慢慢的积累学习我想我会弄明白的。

开始前:

按照UML类图逐个去写逐个去实现(但是有些模块我没有用上)

主要精力是放在了功能实现上

下面是我实现的过程

一、万事开头难--游戏类

(我先确定了开始着手的地方--游戏类,因为它是所有类和方法的汇聚地)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
 
//游戏类
 
namespace 自个先写CSharp核心小项目_贪吃蛇_
{
    enum E_Scene
    {
        BeginID,
        GamingID,
        FinishID,
    }
 
    class Game
    {
        public static int x;
        public static int y;
        public static E_Scene scene = new E_Scene();
        Begin begin = new Begin();
        Finish finish = new Finish();
 
        public Game()
        {
            x = 100;
            y = 30;
            scene = E_Scene.BeginID;
        }
 
        //初始化控制台
        public void Consoles()
        {
            //隐藏光标
            Console.CursorVisible = false;
            //设置舞台大小
            Console.SetWindowSize(x, y);
            Console.SetBufferSize(x, y);
 
        }
 
        //游戏主循环
        public void MajorCycle()
        {
            while (true)
            {
                //思考一下,为什么把开始场景和结束场景的类申明放在外面,而游戏场景的类申明放循环里面
                //因为开始结束场景是一成不变的,只需申明一次就够用了
                //而游戏场景进入一次就会执行出结果出来,每次结果都将不一样,所以每次都得重新申明
                switch (scene)
                {
                    case E_Scene.BeginID:
                        Console.Clear();
                        begin.newers();
                        break;
                    case E_Scene.GamingID:
                        Console.Clear();
                        GameScene gameScene = new GameScene();
                        gameScene.newers();
                        break;
                    case E_Scene.FinishID:
                        Console.Clear();
                        finish.newers();
                        break;
                    default:
                        break;
                }
            }
        }
 
        //场景切换
        public void SceneMove()
        {
 
        }
 
    }
}

二、游戏帧更新接口

1.更新接口

2.开始和结束场景基类

开始场景类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
//开始场景
 
namespace 自个先写CSharp核心小项目_贪吃蛇_
{
    class Begin : BeginAndFinish
    {
        public Begin()
        {
            str = "贪吃蛇";
            str1 = "开始游戏";
            str2 = "结束游戏";
        }
 
        //重写更新方法
        public override void newers()
        {
            Console.SetCursorPosition(48, 10);
            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine(str);
            Console.SetCursorPosition(47, 13);
            Console.ForegroundColor = key == 1 ? ConsoleColor.Red : ConsoleColor.White;
            Console.WriteLine(str1);
            Console.SetCursorPosition(47, 15);
            Console.ForegroundColor = key == 2 ? ConsoleColor.Red : ConsoleColor.White;
            Console.WriteLine(str2);
 
            char c = Console.ReadKey(true).KeyChar;
            switch (c)
            {
                case 'W':
                case 'w':
                    key = 1;
                    break;
                case 'S':
                case 's':
                    key = 2;
                    break;
                case 'J':
                case 'j':
                    if (key == 2)
                    {
                        //关闭控制台
                        Environment.Exit(0);
                    }
                    Game.scene = (E_Scene)key;
                    break;
                default:
                    break;
            }
        }
    }
}
结束场景类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
//结束场景
 
namespace 自个先写CSharp核心小项目_贪吃蛇_
{
    class Finish : BeginAndFinish
    {
        string str0;
        public static int num;
 
        public Finish()
        {
            key = 0;
            str = "游戏结束";
            str0 = "本次游戏的长度为:";
            str1 = "回到开始界面";
            str2 = "结束游戏";
        }
 
        //重写更新方法
        public override void newers()
        {
            Console.SetCursorPosition(47, 10);
            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine(str);
            Console.SetCursorPosition(42, 12);
            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine(str0 + num);
            Console.SetCursorPosition(45, 15);
            Console.ForegroundColor = key == 0 ? ConsoleColor.Red : ConsoleColor.White;
            Console.WriteLine(str1);
            Console.SetCursorPosition(47, 17);
            Console.ForegroundColor = key == 2 ? ConsoleColor.Red : ConsoleColor.White;
            Console.WriteLine(str2);
 
            char c = Console.ReadKey(true).KeyChar;
            switch (c)
            {
                case 'W':
                case 'w':
                    key = 0;
                    break;
                case 'S':
                case 's':
                    key = 2;
                    break;
                case 'J':
                case 'j':
                    if (key == 2)
                    {
                        //关闭控制台
                        Environment.Exit(0);
                    }
                    Game.scene = (E_Scene)key;
                    break;
                default:
                    break;
            }
        }
 
    }
}

(这里面其实可以把这些方法提取到开始和结束场景基类里面的,但我懒,没有去整!!!)

3.游戏场景类

(第二个大类,游戏里的墙壁、食物、蛇、各种方法等等都汇聚在这个类中)

三、游戏场景中的各类

1.绘制接口

2.游戏对象类

(讲真的这个类没怎么用上,具体怎么用我还得看看老师是怎么用的)

3.位置结构体

(这个是完全没有用上!!)

4.地图墙壁类

5.食物类

6.蛇类--(最复杂的类)

蛇身体类--没用上

蛇类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
//蛇类
 
namespace 自个先写CSharp核心小项目_贪吃蛇_
{
    //移动方向枚举
    enum E_Move
    {
        Up,
        Down,
        Left,
        Right,
    }
 
    class Snake
    {
        string snakeHead = "●";
        string snakeBody = "◎";
        int x = 10;
        int y = 5;
        E_Move move = E_Move.Down;
        char c;
        Foods foods = new Foods();
        int bodyNum = 0;
        //标识符
        int[] num1 = new int[10000];
        int[] num2 = new int[10000];
        //打印出长度
        public string longs = "当前长度为:";
 
        //蛇绘制
        public void SnakePlan()
        {
            //打印长度
            Console.SetCursorPosition(2, 1);
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine(longs + bodyNum);
 
            Finish.num = bodyNum;
 
            //蛇头的绘制
            Console.SetCursorPosition(x, y);
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine(snakeHead);
 
            //蛇身的绘制
            for (int i = 0; i < bodyNum; i++)
            {
                Console.SetCursorPosition(num1[i], num2[i]);
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine(snakeBody);
            }
        }
 
        //蛇清除
        public void SnakeClear()
        {
            //打印长度清除
            Console.SetCursorPosition(2, 1);
            Console.WriteLine("               ");
            //蛇头的清除
            Console.SetCursorPosition(x, y);
            Console.WriteLine("  ");
 
            //蛇身的清除
            for (int i = 0; i < bodyNum; i++)
            {
                Console.SetCursorPosition(num1[i], num2[i]);
                Console.WriteLine("  ");
            }
        }
 
        //蛇转向
        public void SnakeTurn()
        {
            //老师漏讲的知识点,Console.KeyAvailable -- 检测键盘是否被激活
            if (Console.KeyAvailable == true)
            {
                c = Console.ReadKey(true).KeyChar;
                switch (c)
                {
                    case 'W':
                    case 'w':
                        if (move == E_Move.Down && bodyNum != 0)
                        {
                            move = E_Move.Down;
                        }
                        else
                        {
                            move = E_Move.Up;
                        }
                        break;
                    case 'S':
                    case 's':
                        if (move == E_Move.Up && bodyNum != 0)
                        {
                            move = E_Move.Up;
                        }
                        else
                        {
                            move = E_Move.Down;
                        }
                        break;
                    case 'A':
                    case 'a':
                        if (move == E_Move.Right && bodyNum != 0)
                        {
                            move = E_Move.Right;
                        }
                        else
                        {
                            move = E_Move.Left;
                        }
                        break;
                    case 'D':
                    case 'd':
                        if (move == E_Move.Left && bodyNum != 0)
                        {
                            move = E_Move.Left;
                        }
                        else
                        {
                            move = E_Move.Right;
                        }
                        break;
                    default:
                        break;
                }
            }
            
        } 
 
        //吃食物
 
        //死亡
 
        
 
 
        //蛇移动 -- (包含了蛇绘制、蛇转向、吃食物)
        public void SnakeMove()
        {
            if(foods.x == 0 || foods.y == 0)
            {
                foods.Plan();
            }
            SnakeTurn();
            switch (move)
            {
                case E_Move.Up:
                    SnakeClear();
                    y -= 1;
                    //判断是否死亡
                    //撞墙死亡
                    if (y == 0)
                    {
                        Game.scene = E_Scene.FinishID;
                        GameScene.bo = false;
                        break;
                    }
                    //撞身体死亡
                    for (int i = 0; i < bodyNum; i++)
                    {
                        if(num1[i] == x && num2[i] == y)
                        {
                            Game.scene = E_Scene.FinishID;
                            GameScene.bo = false;
                            break;
                        }
                    }
 
                    if (foods.x == x && foods.y == y)
                    {
                        foods.Plan();
                        //给个判断,让生成的food不会出现在有蛇身体的位置上
                        for (int i = 0; i < bodyNum; i++)
                        {
                            if (foods.x == num1[i] && foods.y == num2[i])
                            {
                                Console.SetCursorPosition(foods.x, foods.y);
                                Console.WriteLine("  ");
                                foods.Plan();
                                i = 0;
                            }
                        }
 
                        bodyNum += 1;
                        for (int i = bodyNum - 1; i > 0; i--)
                        {
                            num1[i] = num1[i - 1];
                            num2[i] = num2[i - 1];
                        }
                        num1[0] = x;
                        num2[0] = y + 1;
                    }
                    else
                    {
                        for (int i = bodyNum - 1; i > 0; i--)
                        {
                            num1[i] = num1[i - 1];
                            num2[i] = num2[i - 1];
                        }
                        num1[0] = x;
                        num2[0] = y + 1;
                    }
                    SnakePlan();
                    
                    break;
                case E_Move.Down:
                    SnakeClear();
                    y += 1;
                    //判断是否死亡
                    //撞墙死亡
                    if (y == 29)
                    {
                        Game.scene = E_Scene.FinishID;
                        GameScene.bo = false;
                        break;
                    }
                    //撞身体死亡
                    for (int i = 0; i < bodyNum; i++)
                    {
                        if (num1[i] == x && num2[i] == y)
                        {
                            Game.scene = E_Scene.FinishID;
                            GameScene.bo = false;
                            break;
                        }
                    }
 
                    if (foods.x == x && foods.y == y)
                    {
                        foods.Plan();
                        //给个判断,让生成的food不会出现在有蛇身体的位置上
                        for (int i = 0; i < bodyNum; i++)
                        {
                            if (foods.x == num1[i] && foods.y == num2[i])
                            {
                                Console.SetCursorPosition(foods.x, foods.y);
                                Console.WriteLine("  ");
                                foods.Plan();
                                i = 0;
                            }
                        }
 
                        bodyNum += 1;
                        for (int i = bodyNum - 1; i > 0; i--)
                        {
                            num1[i] = num1[i - 1];
                            num2[i] = num2[i - 1];
                        }
                        num1[0] = x;
                        num2[0] = y - 1;
                    }
                    else
                    {
                        for (int i = bodyNum - 1; i > 0; i--)
                        {
                            num1[i] = num1[i - 1];
                            num2[i] = num2[i - 1];
                        }
                        num1[0] = x;
                        num2[0] = y - 1;
                    }
                    SnakePlan();
                    break;
                case E_Move.Left:
                    SnakeClear();
                    x -= 2;
                    //判断是否死亡
                    //撞墙死亡
                    if (x == 0)
                    {
                        Game.scene = E_Scene.FinishID;
                        GameScene.bo = false;
                        break;
                    }
                    //撞身体死亡
                    for (int i = 0; i < bodyNum; i++)
                    {
                        if (num1[i] == x && num2[i] == y)
                        {
                            Game.scene = E_Scene.FinishID;
                            GameScene.bo = false;
                            break;
                        }
                    }
 
                    if (foods.x == x && foods.y == y)
                    {
                        foods.Plan();
                        //给个判断,让生成的food不会出现在有蛇身体的位置上
                        for (int i = 0; i < bodyNum; i++)
                        {
                            if (foods.x == num1[i] && foods.y == num2[i])
                            {
                                Console.SetCursorPosition(foods.x, foods.y);
                                Console.WriteLine("  ");
                                foods.Plan();
                                i = 0;
                            }
                        }
 
                        bodyNum += 1;
                        for (int i = bodyNum - 1; i > 0; i--)
                        {
                            num1[i] = num1[i - 1];
                            num2[i] = num2[i - 1];
                        }
                        num1[0] = x + 2;
                        num2[0] = y;
                    }
                    else
                    {
                        for (int i = bodyNum - 1; i > 0; i--)
                        {
                            num1[i] = num1[i - 1];
                            num2[i] = num2[i - 1];
                        }
                        num1[0] = x + 2;
                        num2[0] = y;
                    }
                    SnakePlan();
                    break;
                case E_Move.Right:
                    SnakeClear();
                    x += 2;
                    //判断是否死亡
                    //撞墙死亡
                    if (x == 98)
                    {
                        Game.scene = E_Scene.FinishID;
                        GameScene.bo = false;
                        break;
                    }
                    //撞身体死亡
                    for (int i = 0; i < bodyNum; i++)
                    {
                        if (num1[i] == x && num2[i] == y)
                        {
                            Game.scene = E_Scene.FinishID;
                            GameScene.bo = false;
                            break;
                        }
                    }
 
                    if (foods.x == x && foods.y == y)
                    {
                        foods.Plan();
                        //给个判断,让生成的food不会出现在有蛇身体的位置上
                        for (int i = 0; i < bodyNum; i++)
                        {
                            if (foods.x == num1[i] && foods.y == num2[i])
                            {
                                Console.SetCursorPosition(foods.x, foods.y);
                                Console.WriteLine("  ");
                                foods.Plan();
                                i = 0;
                            }
                        }
 
                        bodyNum += 1;
                        for (int i = bodyNum - 1; i > 0; i--)
                        {
                            num1[i] = num1[i - 1];
                            num2[i] = num2[i - 1];
                        }
                        num1[0] = x - 2;
                        num2[0] = y;
                    }
                    else
                    {
                        for (int i = bodyNum - 1; i > 0; i--)
                        {
                            num1[i] = num1[i - 1];
                            num2[i] = num2[i - 1];
                        }
                        num1[0] = x - 2;
                        num2[0] = y;
                    }
                    SnakePlan();
                    break;
                default:
                    break;
            }
        }
 
    }
}

至此所有功能都已实现!!!

实现视频展示

C#核心实践项目(自个先写)--贪吃蛇

全部代码文件:看资源

说一下:CSDN下载个资源还要VIP,真服了!

如果需要源码的可以私信滴滴我,无偿!

但是代码有些拙劣,不要建议。

总结一下下

代码有点屎山,but跑起来就好!!!

还是知识点运用的不够,很多没用上。

文章来源:https://blog.csdn.net/SunsetSunup/article/details/135499000
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。