一个C#控制台小游戏(源码解析)

   前几天我发布游戏exe文件,这几天整理了一下代码——源码下载,就马上来写博了。好了,开始正题了

   程序类图如下: 

 

Program:程序类——main方法

Game:游戏类——游戏运行、角色基本信息调用

From:地图类——描绘游戏边框、提示信息

Tank:坦克类——坦克绘制、行为、碰撞处理

EnemyTank:敌方坦克类——坦克绘制、行为、碰撞处理

Bullet:子弹类——子弹绘制、行为、碰撞处理

Point:位置结构——记录坦克、子弹位置

Direction:方向类——记录坦克、子弹方向

            当然这个游戏主要组成也是:地图,坦克绘制、行动、碰撞,子弹绘制、行动、碰撞,下面一一讲解:

     1.Map

 /// <summary>
        /// 绘制边框
        /// </summary>
        public void DrawBorder()
        {
            Console.ForegroundColor = ConsoleColor.Gray;
            Console.CursorVisible = false;
            Console.SetCursorPosition(Left, Top);

            Console.Write("┎" + new string('━', width) + "┒");
            for (int i = 0; i <= height; i++)
            {
                if (i != height)
                {
                    Console.SetCursorPosition(left, top + i + 1);
                    Console.Write("┃" + new string(' ', 2 * width) + "┃");
                }
                else
                {
                    Console.SetCursorPosition(left, top + i + 1);
                    Console.Write("┗" + new string('━', width) + "┛");
                }
            }

            Config.Config.func();
        }

  其中 Console.ForegroundColor——获取或设置当前控制台颜色
              Console.CursorVisible——用来指示光标是否可见
             Console.SetCursorPosition(, )——设置光标的位置
              (以上三个在后面绘制都要用到,用法我就不再讲解了)

看代码我可以知道者将获得一个框框的图案,这就是游戏的地图

2.获取键盘事件

         /// <summary>
         /// 获得键盘按键状态
      /// </summary>
        /// <returns></returns>
        public bool StartInput()
        {
            ConsoleKeyInfo key;
            while (true)
            {
                key = Console.ReadKey(true);
                if (!HandleInput(key))
                {
                    return false;
                }
            }
         
            return true;
        }

  这个方法在Game类中是打开即加载,他是我们控制坦克上下左右和发射子弹方法,其中 Console.ReadKey(true);可以获得按下的键盘,内容是不断循环的,其中HandleInput(key)方法是控制坦克行为的方法,没执行一次,坦克走一步或者发射子弹,当返回false就跳出改方法

3.物体之间碰撞的判断

 /// <summary>
       /// 判断是否碰到边框或者敌方坦克
       /// </summary>
       /// <param name="type"></param>
       /// <returns></returns>
        public int Collide(MoveType type)
        {
            int tan = 0;

            //左
            if (type == MoveType.Left)
            {
                    if ( x <= 1)
                    {
                        tan = x;
                    }
                    else
                    {
                        if (From.Map[x - 2, y-1] == 3 || From.Map[x - 2, y] == 3 || From.Map[x - 2, y+1] == 3)
                        {
                            tan = x;
                        }
                        else
                        {
                            x -= 1;
                            tan = x;
                        }
                       
                    }
            }

            //右
            if (type == MoveType.Right)
            {
                    if (x >= From.Width - width + 1)
                    {
                        tan = x;
                    }
                    else
                    {
                        if (From.Map[x + 2, y-1] == 3 || From.Map[x + 2, y] == 3 || From.Map[x + 2, y+1] == 3)
                        {
                            tan = x;
                        }
                        else
                        {
                            x += 1;
                            tan = x;
                        }
                       
                    }
            }
            //上
            if (type == MoveType.Up)
            {

                if (y <= 1)
                {
                    tan = y;
                }
                else
                {
                    if (From.Map[x - 1, y - 2] == 3 || From.Map[x, y - 2] == 3 || From.Map[x + 1, y - 2] == 3)
                    {
                        tan = y;
                    }
                    else
                    {
                        y -= 1;
                        tan = y;
                    }
                   
                }
            }
            //下
            if (type == MoveType.Down)
            {
                if ( y > From.Height - 3)
                    {
                        tan = y;
                    }
                    else
                    {
                        if (From.Map[x - 1, y + 2] == 3 || From.Map[x, y + 2] == 3 || From.Map[x + 1, y + 2] == 3)
                        {
                            tan = y;
                        }
                        else
                        {
                            y += 1;
                            tan = y;
                        }
                      
                    }
            }

            return tan;
        }

  物体之间的碰撞。比如坦克与敌方坦克相碰怎样判断不让他们相互挡住对方,还有子弹击中敌方坦克判断使其爆炸。这的确是个头疼的问题,但是如果你仔细注意了每一次坦克或者子弹的绘制,其中From。map[,]我赋值都是不同的,己方坦克赋值2、敌方坦克赋值3、子弹赋值1,然后清除轨迹后所有都赋值0,看到上面的判断条件,想必大家也是知道怎么控制他们碰撞的判断了吧

以上三个问题都是程序典型的问题。绘制,运行,碰撞,大家看懂一个其他自然都知道了,所以这里也不都全部拿出来了。当然还有一些大家看到时候要注意的地方:比如width,在绘制地图、坦克,还有他们移动,我用的都是用两个光标的位置,而长度都是用一个光标的位置。还有给From.Map[,]中的数组内位置添加值时候,要注意数组是以0开始的,而地图内容是从1开始的,所以他们每次添加值的时候我都要减1。

好了,文章就写到这了,代码全部开源了,如果哪位朋友感兴趣,可以自己修改代码(非常欢迎扩展这个小游戏)。还有之前zzd网友提出个意见敌方坦克随即出现的问题,我这边也忘改了(太懒了,不想再动了),如果又不懂细节的网友(有些问题不好说清),可以加qq群253674268,欢迎大家一起交流。

转载于:https://www.cnblogs.com/Dotaer/archive/2012/10/12/2719720.html

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是基于C#控制台应用的贪吃蛇小游戏的代码实现。 ```csharp using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleSnake { class Program { static void Main(string[] args) { Console.CursorVisible = false; //隐藏光标 Console.SetWindowSize(60, 30); //设置窗口大小 Console.SetBufferSize(60, 30); //设置缓冲区大小 //画边框 for (int i = 0; i < 60; i++) { Console.SetCursorPosition(i, 0); Console.Write("#"); Console.SetCursorPosition(i, 29); Console.Write("#"); } for (int i = 0; i < 30; i++) { Console.SetCursorPosition(0, i); Console.Write("#"); Console.SetCursorPosition(59, i); Console.Write("#"); } //初始化蛇 List<Point> snake = new List<Point>(); snake.Add(new Point(30, 15)); snake.Add(new Point(29, 15)); snake.Add(new Point(28, 15)); snake.Add(new Point(27, 15)); snake.Add(new Point(26, 15)); //初始化食物 Point food = new Point(RandomNumber(1, 58), RandomNumber(1, 28)); Console.SetCursorPosition(food.x, food.y); Console.Write("*"); //初始化方向 Direction direction = Direction.Right; //初始化分数 int score = 0; while (true) { //获取键盘输入 if (Console.KeyAvailable) { ConsoleKeyInfo key = Console.ReadKey(true); switch (key.Key) { case ConsoleKey.UpArrow: if (direction != Direction.Down) direction = Direction.Up; break; case ConsoleKey.DownArrow: if (direction != Direction.Up) direction = Direction.Down; break; case ConsoleKey.LeftArrow: if (direction != Direction.Right) direction = Direction.Left; break; case ConsoleKey.RightArrow: if (direction != Direction.Left) direction = Direction.Right; break; } } //移动蛇 Point head = snake[0]; Point newHead = new Point(head.x, head.y); switch (direction) { case Direction.Up: newHead.y--; break; case Direction.Down: newHead.y++; break; case Direction.Left: newHead.x--; break; case Direction.Right: newHead.x++; break; } snake.Insert(0, newHead); Console.SetCursorPosition(newHead.x, newHead.y); Console.Write("@"); if (newHead.x == food.x && newHead.y == food.y) //吃到食物 { food = new Point(RandomNumber(1, 58), RandomNumber(1, 28)); Console.SetCursorPosition(food.x, food.y); Console.Write("*"); score += 10; } else //没有吃到食物 { Point tail = snake[snake.Count - 1]; Console.SetCursorPosition(tail.x, tail.y); Console.Write(" "); snake.RemoveAt(snake.Count - 1); } //判断是否撞到边框或自己 if (newHead.x == 0 || newHead.x == 59 || newHead.y == 0 || newHead.y == 29) break; for (int i = 1; i < snake.Count; i++) { if (newHead.x == snake[i].x && newHead.y == snake[i].y) { Console.SetCursorPosition(0, 31); Console.Write("Game Over! Your score is: " + score); return; } } //延迟一段时间 System.Threading.Thread.Sleep(100); } } static int RandomNumber(int min, int max) //生成指定范围内的随机数 { Random random = new Random(); return random.Next(min, max + 1); } } enum Direction //方向枚举 { Up, Down, Left, Right } class Point //坐标类 { public int x; public int y; public Point(int x, int y) { this.x = x; this.y = y; } } } ``` 希望这个代码对你有帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值