C#【进阶】俄罗斯方块

05-28 1315阅读

俄罗斯方块

文章目录

      • Test1_场景切换相关
        • BeginScene.cs
        • BegionOrEndScene.cs
        • EndScene.cs
        • Game.cs
        • GameScene.cs
        • ISceneUpdate.cs
        • Test2_绘制对象基类和枚举信息
          • DrawObject.cs
          • IDraw.cs
          • Position.cs
          • Test3_地图相关
            • Map.cs
            • Test4_坐标信息类
              • BlockInfo.cs
              • Test5_板砖工人类
                • BlockWorker.cs
                • Test6_输入模块
                  • InputThread.cs
                  • Program.cs

                    C#【进阶】俄罗斯方块

                    C#【进阶】俄罗斯方块

                    C#【进阶】俄罗斯方块

                    C#【进阶】俄罗斯方块

                    Test1_场景切换相关

                    BeginScene.cs
                    namespace CSharp俄罗斯方块
                    {
                        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
                    namespace CSharp俄罗斯方块
                    {
                        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  1)
                                        {
                                            nowSelIndex = 0;
                                        }
                                        break;
                                    case ConsoleKey.J:
                                        EnterJDoSomthing();
                                        break;
                                }
                            }
                        }
                    }
                    
                    EndScene.cs
                    namespace CSharp俄罗斯方块
                    {
                        internal class EndScene : BegionOrEndScene
                        {
                            public EndScene()
                            {
                                strTitle = "结束游戏";
                                strOne = "回到开始界面";
                            }
                            public override void EnterJDoSomthing()
                            {
                                if(nowSelIndex == 0)
                                {
                                    Game.ChangeScene(E_SceneType.Begin);
                                }
                                else
                                {
                                    Environment.Exit(0);
                                }
                            }
                        }
                    }
                    
                    Game.cs
                    namespace CSharp俄罗斯方块
                    {
                        enum E_SceneType
                        {
                            Begin,
                            Game,
                            End,
                        }
                        internal class Game
                        {
                            public const int w = 50;
                            public const int h = 35;
                            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;
                                }
                            }
                        }
                    }
                    
                    GameScene.cs
                    namespace CSharp俄罗斯方块
                    {
                        internal class GameScene : ISceneUpdate
                        {
                            Map map;
                            BlockWorker blockWorker;
                            //bool isRunning;
                            //新开线程
                            //Thread inputThread;
                            public GameScene()
                            {
                                map = new Map(this);
                                blockWorker = new BlockWorker();
                                InputThread.Instance.inputEvent += CheckInputThread;
                                //isRunning = true;
                                //inputThread = new Thread(CheckInputThread);
                                设置成后台线程(生命周期随主线程)
                                //inputThread.IsBackground = true;
                                开启线程
                                //inputThread.Start();
                            }
                            public void StopThread()
                            {
                                //isRunning = false;
                                //inputThread = null;
                                //移除输入事件监听
                                InputThread.Instance.inputEvent -= CheckInputThread;
                            }
                            private void CheckInputThread()
                            {
                                //while (isRunning)
                                //{
                                    //检测输入,防止输入卡程序
                                    if (Console.KeyAvailable)
                                    {
                                        //避免影响主线程,在输入后加锁
                                        lock (blockWorker)
                                        {
                                            switch (Console.ReadKey(true).Key)
                                            {
                                                case ConsoleKey.LeftArrow:
                                                    //判断变形
                                                    if (blockWorker.CanChange(E_Change_Type.Left, map))
                                                        blockWorker.Change(E_Change_Type.Left);
                                                    break;
                                                case ConsoleKey.RightArrow:
                                                    if (blockWorker.CanChange(E_Change_Type.Right, map))
                                                        blockWorker.Change(E_Change_Type.Right);
                                                    break;
                                                case ConsoleKey.A:
                                                    if (blockWorker.CanMoveR_L(E_Change_Type.Left, map))
                                                        blockWorker.MoveR_L(E_Change_Type.Left);
                                                    break;
                                                case ConsoleKey.D:
                                                    if (blockWorker.CanMoveR_L(E_Change_Type.Right, map))
                                                        blockWorker.MoveR_L(E_Change_Type.Right);
                                                    break;
                                                case ConsoleKey.S:
                                                    if (blockWorker.CanDown(map))
                                                        blockWorker.AutoMove();
                                                    break;
                                            }
                                        }
                                    }
                                //}
                            }
                            public void Update()
                            {
                                lock (blockWorker)
                                {
                                    map.Draw();
                                    blockWorker.Draw();
                                    if (blockWorker.CanDown(map))
                                        blockWorker.AutoMove();
                                }
                                //线程休眠减速
                                Thread.Sleep(100);
                            }
                        }
                    }
                    
                    ISceneUpdate.cs
                    namespace CSharp俄罗斯方块
                    {
                        /// 
                        /// 场景更新接口
                        /// 
                        internal interface ISceneUpdate
                        {
                            void Update();
                        }
                    }
                    

                    Test2_绘制对象基类和枚举信息

                    DrawObject.cs
                    namespace CSharp俄罗斯方块
                    {
                        /// 
                        /// 绘制类型
                        /// 
                        enum E_DrawType
                        {
                            /// 
                            /// 墙壁
                            /// 
                            Wall,
                            /// 
                            /// 正方形方块
                            /// 
                            Cube,
                            /// 
                            /// 直线
                            /// 
                            Line,
                            /// 
                            /// 坦克
                            /// 
                            Tank,
                            /// 
                            /// 左梯子
                            /// 
                            Left_Ladder,
                            /// 
                            /// 右梯子
                            /// 
                            Right_Ladder,
                            /// 
                            /// 左长梯子
                            /// 
                            Left_Long_ladder,
                            /// 
                            /// 右长梯子
                            /// 
                            Right_Long_ladder,
                        }
                        internal class DrawObject : IDraw
                        {
                            public Position pos;
                            public E_DrawType type;
                            public DrawObject(E_DrawType type)
                            {
                                this.type = type;
                            }
                            public DrawObject(E_DrawType type, int x, int y) : this(type)
                            {
                                pos = new Position(x, y);
                            }
                            public void Draw()
                            {
                                if (pos.y  
                    
                    IDraw.cs
                    namespace CSharp俄罗斯方块
                    {
                        internal interface IDraw
                        {
                            void Draw();
                        }
                    }
                    
                    Position.cs
                    namespace CSharp俄罗斯方块
                    {
                        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 left, Position right)
                            {
                                if (left.x == right.x && left.y == right.y) { return true; }
                                return false;
                            }
                            public static bool operator !=(Position left, Position right)
                            {
                                if (left.x == right.x && left.y == right.y) { return false; }
                                return true;
                            }
                            public static Position operator +(Position left, Position right)
                            {
                                return new Position(left.x + right.x, left.y + right.y);
                            }
                        }
                    }
                    

                    Test3_地图相关

                    Map.cs
                    namespace CSharp俄罗斯方块
                    {
                        internal class Map : IDraw
                        {
                            //固定墙壁
                            private List walls = new List();
                            //动态墙壁
                            public List dynamicWalls = new List();
                            private GameScene nowGameScene;
                            //为了外部能快速得到地图边界
                            //动态墙壁的宽容量,小方块横向个数
                            public int w;
                            public int h;
                            //记录每一行有多少个小方块的容器,索引就是行号
                            private int[] recordInfo;
                            public Map(GameScene scene)
                            {
                                nowGameScene = scene;
                                h = Game.h - 6;
                                recordInfo = new int[h];
                                w = 0;
                                //绘制横向墙壁
                                for (int i = 0; i  
                    

                    Test4_坐标信息类

                    C#【进阶】俄罗斯方块

                    C#【进阶】俄罗斯方块

                    BlockInfo.cs
                    namespace CSharp俄罗斯方块
                    {
                        internal class BlockInfo
                        {
                            private List list;
                            public BlockInfo(E_DrawType type)
                            {
                                list = new List();
                                switch (type)
                                {
                                    case E_DrawType.Cube:
                                        list.Add(new Position[3] { new Position(2, 0), new Position(0, 1), new Position(2, 1) });
                                        break;
                                    case E_DrawType.Line:
                                        list.Add([new Position(0, -1), new Position(0, 1), new Position(0, 2)]);
                                        list.Add([new Position(-4, 0), new Position(-2, 0), new Position(2, 0)]);
                                        list.Add([new Position(0, -2), new Position(0, -1), new Position(0, 1)]);
                                        list.Add([new Position(-2, 0), new Position(2, 0), new Position(4, 0)]);
                                        break;
                                    case E_DrawType.Tank:
                                        list.Add([new Position(-2, 0), new Position(2, 0), new Position(0, 1)]);
                                        list.Add([new Position(0, -1), new Position(-2, 0), new Position(0, 1)]);
                                        list.Add([new Position(0, -1), new Position(-2, 0), new Position(2, 0)]);
                                        list.Add([new Position(0,-1), new Position(2, 0), new Position(0, 1)]);
                                        break;
                                    case E_DrawType.Left_Ladder:
                                        list.Add([new Position(0, -1), new Position(2, 0), new Position(2, 1)]);
                                        list.Add([new Position(2, 0), new Position(-2, 1), new Position(0, 1)]);
                                        list.Add([new Position(-2, -1), new Position(-2, 0), new Position(0, 1)]);
                                        list.Add([new Position(0, -1), new Position(2, -1), new Position(-2, 0)]);
                                        break;
                                    case E_DrawType.Right_Ladder:
                                        list.Add([new Position(0, -1), new Position(-2, 0), new Position(-2, 1)]);
                                        list.Add([new Position(-2, -1), new Position(0, -1), new Position(2, 0)]);
                                        list.Add([new Position(2, -1), new Position(2, 0), new Position(0, 1)]);
                                        list.Add([new Position(-2, 0), new Position(0, 1), new Position(2, 1)]);
                                        break;
                                    case E_DrawType.Left_Long_ladder:
                                        list.Add([new Position(-2, -1), new Position(0, -1), new Position(0, 1)]);
                                        list.Add([new Position(2, 1), new Position(-2, 0), new Position(2, 0)]);
                                        list.Add([new Position(0, -1), new Position(0, 1), new Position(2, 1)]);
                                        list.Add([new Position(-2, 0), new Position(2, 0), new Position(-2, 1)]);
                                        break;
                                    case E_DrawType.Right_Long_ladder:
                                        list.Add([new Position(0, -1), new Position(2, -1), new Position(0, 1)]);
                                        list.Add([new Position(-2, 0), new Position(2, 1), new Position(2, 0)]);
                                        list.Add([new Position(0, -1), new Position(0, 1), new Position(-2, 1)]);
                                        list.Add([new Position(-2, 0), new Position(2, 0), new Position(-2, -1)]);
                                        break;
                                    default:
                                        break;
                                }
                            }
                            public Position[] this[int index]
                            {
                                get
                                {
                                    if (index = list.Count)
                                        return list[list.Count - 1];
                                    else
                                        return list[index];
                                    
                                }
                            }
                            public int Count { get => list.Count; }
                        }
                    }
                    

                    Test5_板砖工人类

                    BlockWorker.cs
                    namespace CSharp俄罗斯方块
                    {
                        enum E_Change_Type
                        {
                            Left,
                            Right,
                        }
                        internal class BlockWorker : IDraw
                        {
                            //方块们
                            private List blocks;
                            //用Dictionary方便查找
                            private Dictionary blockInfoDic;
                            //随机创建的方块具体形态信息
                            private BlockInfo nowBlockInfo;
                            //当前形态的索引
                            private int nowInfoIndex;
                            public BlockWorker()
                            {
                                blockInfoDic = new Dictionary()
                                {
                                    { E_DrawType.Cube,new BlockInfo(E_DrawType.Cube)},
                                    { E_DrawType.Line,new BlockInfo(E_DrawType.Line)},
                                    { E_DrawType.Tank,new BlockInfo(E_DrawType.Tank)},
                                    { E_DrawType.Left_Ladder,new BlockInfo(E_DrawType.Left_Ladder)},
                                    { E_DrawType.Right_Ladder,new BlockInfo(E_DrawType.Right_Ladder)},
                                    { E_DrawType.Left_Long_ladder,new BlockInfo(E_DrawType.Left_Long_ladder)},
                                    { E_DrawType.Right_Long_ladder,new BlockInfo(E_DrawType.Right_Long_ladder)},
                                };
                                RandomCreatBlock();
                            }
                            public void Draw()
                            {
                                for (int i = 0; i = nowBlockInfo.Count)
                                            nowInfoIndex = 0;
                                        break;
                                }
                                //得到索引,取出来
                                Position[] pos = nowBlockInfo[nowInfoIndex];
                                for (int i = 0; i = nowBlockInfo.Count)
                                            nowIndex = 0;
                                        break;
                                }
                                //临时索引信息判断是否和墙壁重合
                                Position[] nowPos = nowBlockInfo[nowIndex];
                                //判断是否超出地图边界
                                Position tempPos;
                                for (int i = 0; i = Game.w - 2 || tempPos.y >= map.h)
                                    {
                                        return false;
                                    }
                                }
                                //判断是否和其他方块重合
                                for (int i = 0; i = Game.w - 2)
                                        return false;
                                }
                                //动态方块重合
                                for (int i = 0; i = map.h)
                                    {
                                        //碰到地图,此时变成地图的一部分
                                        map.AddWalls(blocks);
                                        //创建新的随机方块
                                        RandomCreatBlock();
                                        return false;
                                    }
                                }
                                //动态方块
                                for (int i = 0; i  
                    

                    Test6_输入模块

                    InputThread.cs
                    namespace CSharp俄罗斯方块
                    {
                        internal class InputThread
                        {
                            //线程成员变量
                            Thread inputThread;
                            //输入检测事件
                            public event Action inputEvent;
                            private static InputThread instance = new InputThread();
                            public static InputThread Instance
                            {
                                get
                                {
                                    return instance;
                                }
                            }
                            private InputThread()
                            { 
                                inputThread = new Thread(InputCheck);
                                inputThread.IsBackground = true;
                                inputThread.Start();
                            }
                            private void InputCheck()
                            {
                                while (true)
                                {
                                    inputEvent?.Invoke();
                                }
                            }
                        }
                    }
                    

                    Program.cs

                    using CSharp俄罗斯方块;
                    Game game = new Game();
                    game.start();
                    
VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]