【C#项目实战】控制台游戏——勇士斗恶龙(1)


君兮_的个人主页

即使走的再远,也勿忘启程时的初心
C/C++ 游戏开发

Hello,米娜桑们,这里是君兮_,最近开始正式的步入学习游戏开发的正轨,想要通过写博客的方式来分享自己学到的知识和经验,这就是开设本专栏的目的。希望这些独立的C#小项目能对做游戏的你有所帮助,毕竟学会游戏开发的最好的上手方式就是自己做一款游戏!!

勇士救公主

前言

  • 本专栏主要是分享一些纯C#的项目开发流程,后面如有结合Unity开发的游戏会有专门的专栏,同时由于任何一个独立的项目都是非常复杂的,哪怕是简单的小项目做完整都至少需要4~500行代码,因此本专栏的独立项目多半会分不同的板块来分批次讲解,这样一是能拆分板块减小项目开发难度,二也能够便于大家理解方便大家跟着博客自己上手设计。
  • 在更新中的项目,会在更新之后的内容后把相关链接放在该博客的结尾,我也会在开设一个新项目时尽快更完方便大家查阅的!!
  • 同时在每个项目的开头,都会把本项目的流程图放在开头,方便大家检索,当然,我更加希望,大家在学习一段时间后,能不看我的讲解只看流程图就能把这个项目给实现了,能做到这样那么恭喜你真正入门了。

一.勇士救公主流程图

二.项目实现

1.游戏流程

  • 该游戏的大体流程是玩家通过打败恶龙来到公主身边拯救公主。如果挑战成功,救出公主,则游戏胜利,如果不幸被恶龙击败,则游戏结束。
  • 开始界面
  • 游戏界面
  • 营救公主
  • 游戏结束界面
  • 麻雀虽小,五脏俱全,游戏的制作正是要从这种简单的项目一步一步来的,废话不多说,开始我们的学习吧!!

2.项目解析

  • 该项目主要分为几块,场景设置,开始界面的设置和切换,游戏界面的地图的设计及角色的初始化,玩家的移动逻辑以及游戏的战斗逻辑,救出公主的逻辑,胜利或者失败后进入的结束界面的设置。
  • 今天,我们主要来讲初始的一些设置以及开始界面的布置。

3.初始的设置

  • 首先,我们需要先来完成一些基础的设置。
  • 由于我们是一个控制台窗口的小游戏,因此我们需要先设置一下控制台窗口以及缓冲区的大小
csharp 复制代码
  int w = 60;
  int h = 40;
  Console.SetWindowSize(w, h);//控制台窗口大小
  Console.SetBufferSize(w, h);//缓冲区大小
  • 其实这两个函数第一个传入的参数为设置的宽度,第二个传入的参数为设置的高度
  • 此时,在你的电脑上还有光标闪烁,我们需要把光标给隐去
csharp 复制代码
//隐藏光标
 Console.CursorVisible = false;//false为隐去,true为显示
  • 好了,做了以上的基本设置,我们来进行开始界面的设置

4.开始界面

  • 在开始之前,我们不妨想想,我们这个游戏有三个界面,我们要怎么实现不同界面的切换呢?
  • 在这里,我们可以考虑到用switch来进行分组,用不同的条件来区别不同的界面,然后在不同的case下实现不同界面的不同功能。这样在切换不同界面时,我们只需改变条件让程序进入不同case即可。
csharp 复制代码
int nowSceneID = 1;
//不同的场景进行不同的逻辑处理
switch (nowSceneID)
{
	//开始界面
    case 1:
        break;
     //游戏界面
    case 2:
        break;
     //结束界面
    case 3:
        break;
    default:
        break;
}
  • 这样,我们就能通过在代码中改变nowScene的值来切换不同的场景了
  • 同时,我们要注意,不能让游戏主动退出,而是通过玩家的输入才能退出,因此我们不妨将以上的逻辑放入一个死循环中,这样我们就能通过控制循环来控制游戏的退出了。
  • 下面我们就这case 1里实现我们开始界面的功能
  • 我们的开始界面,首先得有我们的游戏名称吧
csharp 复制代码
case 1:
  Console.Clear();//清屏
  Console.SetCursorPosition(w/2-5,10);//设置输入坐标
  Console.WriteLine("勇士斗恶龙");
  • 先介绍一下SetCursorPosition函数。我们的控制台坐标的坐标轴(0,0)在左上角,因此增加传入参数的大小输入位置是往右往下的,关于坐标的设置,相信聪明的你自己动手试一下就能明白其中的原理

  • 注意:如果你这里一直闪屏是由于你一直在循环清屏造成的,属于正常现象,不要慌,等下会解决的,我们继续

  • 好了,接下来是开始界面中最复杂的一段,我们怎么实现按W键和S键点亮"开始游戏"或"结束游戏",来提醒玩家目前的选项呢?

  • 这里我们来分析一下,其实逻辑是非常简单的,首先,当刚进入时,我们让程序进入让开始游戏亮,退出游戏不亮的场景,而玩家按下"S",就切换到"退出游戏"亮上,再按下"W"就切回"开始游戏"亮的情况。

  • 哎,是不是和刚才的场景切换逻辑有亿点点相像呢?没错,这是也可以通过while结合switch的方法实现!!

csharp 复制代码
 //当前选项的编号
 int nowSelIndex = 0;
 //因为要输入 我们可以构造一个开始界面的死循环
 //专门用来处理 开始场景相关的逻辑
 while (true)
 {
     
     //显示内容检测输入
     //设置光标位置,再显示内容
     Console.SetCursorPosition(w / 2 - 4, 12);
     //根据当前选择的编号来决定是否变色
     Console.ForegroundColor = nowSelIndex == 0 ? ConsoleColor.Red : ConsoleColor.White;//三目操作符结合设置字体颜色的函数
     Console.Write("开始游戏");
     Console.SetCursorPosition(w / 2 - 4, 14);
     Console.ForegroundColor = nowSelIndex == 1 ? ConsoleColor.Red : ConsoleColor.White;
     Console.Write("退出游戏");
     //检查玩家输入的键并且不会在控制台上显示输入内容
     char input = Console.ReadKey(true).KeyChar;
     switch (input)
     {
         case 'W':
         case 'w':
             nowSelIndex = 0;

             break;
         case 'S':
         case 's':
             nowSelIndex = 1;

             break;
      
     }

    

 }
  • 很简单的逻辑,通过 nowSelIndex的值进行标记,初始为0,如果按下"S"键就让nowSelIndex = 1,此时开始游戏为白,退出游戏为红,想再切换为开始游戏为红退出游戏为白就按下"W"键即可。
  • 这里是你需要注意的地方:
csharp 复制代码
  //检查玩家输入的键并且不会在控制台上显示输入内容
     char input = Console.ReadKey(true).KeyChar;
  • 当ReadKey括号中的值为true时,输入的值就不会显示在控制台上了,同时我们由于每次进入下一次循环中都会清屏也不会影响游戏的运行。这样就达到了我们的目的,我们来进行下一步。
  • 同时,我们实现"开始游戏"和"退出游戏"的标记提醒后,该进行选择了,这里我们就通过来按"J"来进行下一步,在"开始游戏"高亮时,按J切换到游戏场景,在退出游戏时高亮,按J就退出程序。
csharp 复制代码
 case 'j':
 case 'J':
     if(nowSelIndex == 0)
     {
         //1.改变场景ID,进入游戏场景
         nowSceneID = 2;
         //2.要退出内层循环while
         isQuitWhile = true;
     }
     else
     {
         //关闭控制台
         Environment.Exit(0);
     }
     break;
   if (isQuitWhile == true)
    break;
  • 这里我们定义了一个bool类型的isQuitWhile来实现切换场景的目的,由于我们这里的break都是switch都是里的,只能退出switch,因此需要通过这个bool类型的变量达到退出内层循环进入外层的switch里重新选择的目的,而由于此时我们改变了 nowSceneID的值,自然就可以切换进入游戏场景了。

5.该模块源码

  • 由于上面的讲述是分步拆分的,下面为大家提供该部分的源码来帮助大家理解该部分的内容
csharp 复制代码
namespace 勇士斗恶龙
{
    class Program
    {
        static void Main(string[] args)
        {
            int w = 60;
            int h = 40;
            Console.SetWindowSize(w, h);
            Console.SetBufferSize(w, h);
            //隐藏光标
            Console.CursorVisible = false;
            int nowSceneID = 1;
            while (true)
            {
                //不同的场景进行不同的逻辑处理

                switch (nowSceneID)
                {
                    case 1:
                        Console.Clear();
                       
                        Console.SetCursorPosition(w / 2 - 5, 10);
                        Console.WriteLine("勇士斗恶龙");
                        //当前选项的编号
                        int nowSelIndex = 0;
                        //因为要输入 我们可以构造一个开始界面的死循环
                        //专门用来处理 开始场景相关的逻辑
                        while (true)
                        {
                            //用一个标识用来退出此循环
                            bool isQuitWhile = false;
                            //显示内容检测输入
                            //设置光标位置,再显示内容
                            Console.SetCursorPosition(w / 2 - 4, 12);
                            //根据当前选择的编号来决定是否变色
                            Console.ForegroundColor = nowSelIndex == 0 ? ConsoleColor.Red : ConsoleColor.White;
                            Console.Write("开始游戏");
                            Console.SetCursorPosition(w / 2 - 4, 14);
                            Console.ForegroundColor = nowSelIndex == 1 ? ConsoleColor.Red : ConsoleColor.White;
                            Console.Write("退出游戏");
                            //检查玩家输入的键并且不会在控制台上显示输入内容
                            char input = Console.ReadKey(true).KeyChar;
                            switch (input)
                            {
                                case 'W':
                                case 'w':
                                    nowSelIndex = 0;

                                    break;
                                case 'S':
                                case 's':
                                    nowSelIndex = 1;

                                    break;
                                case 'j':
                                case 'J':
                                    if (nowSelIndex == 0)
                                    {
                                        //1.改变场景ID
                                        nowSceneID = 2;
                                        //2.要退出内层循环while
                                        isQuitWhile = true;
                                    }
                                    else
                                    {
                                        //关闭控制台
                                        Environment.Exit(0);
                                    }
                                    break;
                            }

                            if (isQuitWhile == true)
                                break;

                        }
                        
                        break;
                    case 2:
                        break;
                    case 3:
                        break;
                    default:
                        break;
                }
            }
        }
    }
}

总结

  • 今天的内容到这里就结束了,总的来说这部分的内容还是比较简单的,不妨跟着博主自己动手尝试一下,毕竟很多问题只有自己动手试过了才能发现,如果你在实现过程中遇到任何问题,欢迎在评论区指出或者私信我!!
  • 后面的内容很快更新,感兴趣不妨关注一下错过后面的内容哦!!(小小预告一下,接下来就开始我们游戏界面的内容啦,这一块才是真正的重头戏)

新人博主创作不易,如果感觉文章内容对你有所帮助的话不妨三连一下再走呗。你们的支持就是我更新的动力!!!
**(可莉请求你们三连支持一下博主!!!点击下方评论点赞收藏帮帮可莉吧)**

相关推荐
奋斗的小花生1 小时前
c++ 多态性
开发语言·c++
魔道不误砍柴功1 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
闲晨1 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
老猿讲编程1 小时前
一个例子来说明Ada语言的实时性支持
开发语言·ada
Chrikk2 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*2 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue2 小时前
go语言连续监控事件并回调处理
开发语言·后端·golang
杜杜的man2 小时前
【go从零单排】go语言中的指针
开发语言·后端·golang
萧鼎4 小时前
Python并发编程库:Asyncio的异步编程实战
开发语言·数据库·python·异步
学地理的小胖砸4 小时前
【一些关于Python的信息和帮助】
开发语言·python