C#入门之实践小项目——骑士营救公主

一、 前言

  C#入门专栏已经连续更新一周了,小O我呢,也已经发了7篇关于C#入门学习的知识博文,和博友们一起交流讨论C#的入门基础知识。所以,小O决定推出一个控制台小游戏《骑士营救公主》,帮助各位初入C#的博友综合基础知识,培养简单的项目制作的思维体系。希望大家可以通过这个简单的小游戏试炼一下自己的能力,同时,为大家的学习历程中添加一份成就感!


二、游戏说明

  本次试炼的是一个控制台小游戏,一共有三个界面:开始界面、游戏界面、结束界面。玩家可以通过WASD进行选项选择和人物移动,J键负责控制确定选项和攻击。
  以下为游戏演示视频:

《骑士营救公主》

三、需求分析

1.开始界面

  • 控制台输入
    • W键和S键进行上下选项选择
    • J键确定选项
  • 控制台输出
    • 游戏名称
    • 游戏选项
  • 控制台颜色变化
    • 停留选项字体变为红色

2.游戏界面

  • 控制台输入
    • WASD键控制玩家上下左右移动
    • J键开始战斗
  • 控制台输出
    • 红墙设计
    • boss,player设计
    • 战斗情况输出
    • 游戏结果情况
      • 玩家胜利,营救公主
      • 玩家失败,输出再接再厉
  • 回合制战斗
    • boss和player战斗值采取随机数
    • 循环进行

3.结束界面

  • 控制台输入
    • W键和S键进行上下选项选择
    • J键确定选项
  • 控制台输出
    • 返回主菜单
    • 再来一局
    • 退出游戏
  • 控制台颜色变化
    • 停留选项字体变为红色

四、程序设计

(1)控制台基础设置

  隐藏光标,设置控制台的基本参数。

       //隐藏光标
       Console.CursorVisible = false;
       //通过两个变量来存储 舞台的大小
       int w = 50;
       int h = 30;
       //设置舞台(控制台)的大小
       Console.SetWindowSize(w, h);
       Console.SetBufferSize(w, h);

(2)场景切换

  设计页面ID,通过swtich语句,进行页面切换,此处为游戏整体逻辑框架设计:

//当前所在场景的编号
int nowSceneID = 1;
//场景切换
switch(nowSceneID){
		//开始场景
		case 1:
		//游戏场景
		case 2:
		结束场景
		case 3:
}

(3)开始场景

  在开始场景,用户需要完成输入以及选择,所以开始页面需要用一个while循环包裹,然后进行逻辑处理。
  关于文字坐标的定位设置,可以根据自己对控制台尺寸设计进行相对应的调整。

        //设计标识 想要在while循环内部的switch逻辑执行时 希望退出外层while循环时
        // 改变标识即可
        bool isQuitWhile = false;
        // 显示 内容
        //先设置光标位置 再显示内容
        Console.SetCursorPosition(w / 2 - 4, 13);
        //根据当前选择的编号 来决定 是否变色
        Console.ForegroundColor = nowSelIndex == 0 ? ConsoleColor.Red : ConsoleColor.White;
        Console.Write("开始游戏");
        Console.SetCursorPosition(w / 2 - 4, 15);
        Console.ForegroundColor = nowSelIndex == 1 ? ConsoleColor.Red : ConsoleColor.White;
        Console.Write("退出游戏");
        // 检测 输入
        // 检测玩家 输入的一个键内容 并且不会再控制台上显示输入的内容
        char input = Console.ReadKey(true).KeyChar;
        switch (input)
        {
            case 'W':
            case 'w':
                --nowSelIndex;
                if (nowSelIndex < 0)
                {
                    nowSelIndex = 0;
                }
                break;
            case 'S':
            case 's':
                ++nowSelIndex;
                if (nowSelIndex > 1)
                {
                    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)
        {
            break;
        }
    }

   用户输入的检测的相关知识点在本专栏的控制台基础博文有详解介绍,不理解的友友可以阅读往期博文。

(4)游戏界面

1、红墙设计

  由于红墙需要完成横向和纵向铺满,而每次红墙的出现可以理解为,每隔2px绘制一个红墙,至于为什么是2px?因为小O在此处用的方块是2px的大小。由于红墙是反复出现,且已了解边框限制的长和宽,所以小O在这里使用的是for循环

    for (int i = 0; i < w; i += 2)
     {
         //上方墙
         Console.SetCursorPosition(i, 0);
         Console.Write("■");
      }
    for (int i = 0; i < w; i += 2)
     {
         //下方墙
         Console.SetCursorPosition(i, h-1);
         Console.Write("■");
      }
      

  通过对以上代码的对比分析,我们不难发现横向的红墙在for循环里只改变了纵轴的开始坐标,所以,我们可以进行合并,优化代码。

    for (int i = 0; i < w; i += 2)
    {
        //上方墙
        Console.SetCursorPosition(i, 0);
        Console.Write("■");
        //下方墙
        Console.SetCursorPosition(i, h - 1);
        Console.Write("■");
        //中间墙
        Console.SetCursorPosition(i, h - 6);
        Console.Write("■");
    }

  以下是红墙的完整代码:

    for (int i = 0; i < w; i += 2)
    {
        //上方墙
        Console.SetCursorPosition(i, 0);
        Console.Write("■");
        //下方墙
        Console.SetCursorPosition(i, h - 1);
        Console.Write("■");
        //中间墙
        Console.SetCursorPosition(i, h - 6);
        Console.Write("■");
    }
    //左边的墙
    for (int i = 0; i < h; i++)
    {
        //左边的墙
        Console.SetCursorPosition(0, i);
        Console.Write("■");
        //右边的墙
        Console.SetCursorPosition(w - 2, i);
        Console.Write("■");
    }
2、属性设计

  本次小游戏一共涉及到3个人物:boss、骑士、公主。三个人物涉及的属性基本相同,大致为icon、颜色、初始坐标等,boss和骑士需要设置攻击力和防御值,小O为了让游戏更有趣味性,决定让boss和骑士的攻击力为随机值,让玩家失败和胜利为等可能。

     #region  玩家属性相关
		int playerX = 4;
		int playerY = 5;
		int playerAtkMin = 8;
		int playerAtkMax = 12;
		int playerHp = 100;
		string playerIcon = "●";
		ConsoleColor playerColor = ConsoleColor.Yellow;
		//玩家输入的内容 外面申明 节约性能
		char playerInput;
	#endregion
	
	#region  boss属性相关
		int bossX = 24;
		int bossY = 15;
		int bossAtkMin = 7;
		int bossAtkMax = 13;
		int bossHp = 100;
		string bossIcon = "■";
		//申明一个 颜色变量
		ConsoleColor bossColor = ConsoleColor.Green;
	#endregion
		
	#region  公主相关
		int princessX = 24;
		int princessY = 5;
		string princessIcon = "★";
		ConsoleColor princessColor = ConsoleColor.Blue;
	#endregion
     
3、非战斗处理

  当骑士没有到达boss身边时,无法进行战斗,所以需要通过WASD键到达boss身边。
注意:骑士遇到boss时不能进行图形覆盖,应该设计为被阻挡住的状态,选择开始战斗。

        //擦除
        Console.SetCursorPosition(playerX, playerY);
        Console.Write("  ");
        //改位置
        switch (playerInput)
        {
            case 'W':
            case 'w':
                --playerY;
                if (playerY < 1)
                {
                    playerY = 1;
                }
                //位置如果和boss重合了 并且boss没有死
                else if (playerX == bossX && playerY == bossY && bossHp > 0)
                {
                    //拉回去
                    ++playerY;
                }
                else if (playerX == princessX && playerY == princessY && bossHp <= 0)
                {
                    //拉回去
                    ++playerY;
                }
                break;
            case 'A':
            case 'a':
                playerX -= 2;
                if (playerX < 2)
                {
                    playerX = 2;
                }
                else if (playerX == bossX && playerY == bossY && bossHp > 0)
                {
                    //拉回去
                    playerX += 2;
                }
                else if (playerX == princessX && playerY == princessY && bossHp <= 0)
                {
                    //拉回去
                    playerX += 2;
                }
                break;
            case 'S':
            case 's':
                ++playerY;
                if (playerY > h - 7)
                {
                    playerY = h - 7;
                }
                else if (playerX == bossX && playerY == bossY && bossHp > 0)
                {
                    //拉回去
                    --playerY;
                }
                else if (playerX == princessX && playerY == princessY && bossHp <= 0)
                {
                    //拉回去
                    --playerY;
                }
                break;
            case 'D':
            case 'd':
                playerX += 2;
                if (playerX > w - 4)
                {
                    playerX = w - 4;
                }
                else if (playerX == bossX && playerY == bossY && bossHp > 0)
                {
                    //拉回去
                    playerX -= 2;
                }
                else if (playerX == princessX && playerY == princessY && bossHp <= 0)
                {
                    //拉回去
                    playerX -= 2;
                }
                break;

4、战斗处理

  当玩家选择战斗时,需要显示每次的战斗状态,包括骑士和boss的攻击力以及血量
  骑士和boss战斗会出现两个情况,胜利和失败。胜利,将会显示营救公主以及公主的显示;失败,则会显示再接再厉直接跳入结束页面。

   if (isFight)
   {
       #region 7 玩家战斗相关
       //如果是战斗状态 你做什么
       //只会处理J键 
       if (playerInput == 'J' || playerInput == 'j')
       {
           //在这判断 玩家或者怪物 是否死亡 如果死亡了 继续之后的流程
           if (playerHp <= 0)
           {
               //游戏结束
               //输掉了 应该直接显示 我们的 游戏结束界面
               nowSceneID = 3;
               gameOverInfo = "游戏失败";
               break;
           }
           else if (bossHp <= 0)
           {
               //去营救公主
               //boss擦除
               Console.SetCursorPosition(bossX, bossY);
               Console.Write("  ");
               isFight = false;
           }
           else
           {
               //去处理按J键打架
               // 玩家打怪物
               Random r = new Random();
               //得到随机攻击了
               int atk = r.Next(playerAtkMin, playerAtkMax);
               //血量减对应的攻击力
               bossHp -= atk;
               //打印信息
               Console.ForegroundColor = ConsoleColor.Green;
               //先擦除这一行 上次显示的内容
               Console.SetCursorPosition(2, h - 4);
               Console.Write("                                           ");
               //再来写新的信息
               Console.SetCursorPosition(2, h - 4);
               Console.Write("你对boss造成了{0}点伤害,boss剩余血量为{1}", atk, bossHp);
               // 怪物打玩家
               if (bossHp > 0)
               {
                   //得到随机攻击了
                   atk = r.Next(bossAtkMin, bossAtkMax);
                   playerHp -= atk;

                   //打印信息
                   Console.ForegroundColor = ConsoleColor.Yellow;
                   //先擦除这一行 上次显示的内容
                   Console.SetCursorPosition(2, h - 3);
                   Console.Write("                                           ");
                   //再来写新的信息
                   //boss如果把玩家打死了 做什么
                   if (playerHp <= 0)
                   {
                       Console.SetCursorPosition(2, h - 3);
                       Console.Write("很遗憾,你未能通过boss的试炼,战败了");
                   }
                   else
                   {
                       Console.SetCursorPosition(2, h - 3);
                       Console.Write("boss对你造成了{0}点伤害,你的剩余血量为{1}", atk, playerHp);
                   }
               }
               else
               {
                   //擦除之前的战斗信息
                   Console.SetCursorPosition(2, h - 5);
                   Console.Write("                                           ");
                   Console.SetCursorPosition(2, h - 4);
                   Console.Write("                                           ");
                   Console.SetCursorPosition(2, h - 3);
                   Console.Write("                                           ");
                   //显示恭喜胜利的信息
                   Console.SetCursorPosition(2, h - 5);
                   Console.Write("你战胜了boss,快去营救公主");
                   Console.SetCursorPosition(2, h - 4);
                   Console.Write("前往公主身边按J键继续");
               }
           }
       }
       #endregion
   }

(5)结束界面

  结束界面,类比于开始界面,逻辑设计较为简单。

 #region 9 结束场景逻辑
     //标题的显示
     Console.SetCursorPosition(w / 2 - 4, 5);
     Console.ForegroundColor = ConsoleColor.White;
     Console.Write("GameOver");
     //可变内容的显示 根据失败或者 成功显示的内容不一样
     Console.SetCursorPosition(w / 2 - 4, 7);
     Console.ForegroundColor = ConsoleColor.Green;
     Console.Write(gameOverInfo);

     int nowSelEndIndex = 0;
     while (true)
     {
         bool isQuitEndWhile = false;

         Console.SetCursorPosition(w / 2 - 6, 9);
         Console.ForegroundColor = nowSelEndIndex == 0 ? ConsoleColor.Red : ConsoleColor.White;
         Console.Write("回到开始界面");
         Console.SetCursorPosition(w / 2 - 4, 11);
         Console.ForegroundColor = nowSelEndIndex == 1 ? ConsoleColor.Red : ConsoleColor.White;
         Console.Write("退出游戏");

         char input = Console.ReadKey(true).KeyChar;

         switch (input)
         {
             case 'W':
             case 'w':
                 --nowSelEndIndex;
                 if (nowSelEndIndex < 0)
                 {
                     nowSelEndIndex = 0;
                 }
                 break;
             case 'S':
             case 's':
                 ++nowSelEndIndex;
                 if (nowSelEndIndex > 1)
                 {
                     nowSelEndIndex = 1;
                 }
                 break;
             case 'J':
             case 'j':
                 if (nowSelEndIndex == 0)
                 {
                     nowSceneID = 1;
                     isQuitEndWhile = true;
                 }
                 else
                 {
                     Environment.Exit(0);
                 }
                 break;
         }

         //为了 从switch中跳出上一层的 while循环 加的标识
         if (isQuitEndWhile)
         {
             break;
         }
     }
 #endregion

(6)完整代码

  相信大家跟着小O的思路一步步分析下来,思路应该非常清晰了,以下是完整代码,仅供参考,欢迎大家自行优化:

using System;

namespace 入门实践
{
    class Program
    {
        static void Main(string[] args)
        {
            #region 1 控制台基础设置
            //隐藏光标
            Console.CursorVisible = false;
            //通过两个变量来存储 舞台的大小
            int w = 50;
            int h = 30;
            //设置舞台(控制台)的大小
            Console.SetWindowSize(w, h);
            Console.SetBufferSize(w, h);
            #endregion

            #region 2 多个场景
            //当前所在场景的编号
            int nowSceneID = 1;
            #region 9 结束场景相关
            //结束场景显示的 文字提示内容
            string gameOverInfo = "";
            #endregion
            while (true)
            {
                //不同的场景ID 进行不同的逻辑处理
                switch (nowSceneID)
                {
                    //开始场景
                    case 1:
                        Console.Clear();
                        #region 3 开始场景逻辑
                        Console.SetCursorPosition(w / 2 - 6, 8);
                        Console.Write("骑士营救公主");
                        //当前选项的编号
                        int nowSelIndex = 0;
                        //因为要输入 我们可以构造一个 开始界面自己的 死循环
                        //专门用来处理 开始场景相关的逻辑
                        while (true)
                        {
                            //用一个标识  来处理 想要在while循环内部的switch逻辑执行时 希望退出外层while循环时
                            // 改变标识即可
                            bool isQuitWhile = false;
                            // 显示 内容
                            //先设置光标位置 再显示内容
                            Console.SetCursorPosition(w / 2 - 4, 13);
                            //根据当前选择的编号 来决定 是否变色
                            Console.ForegroundColor = nowSelIndex == 0 ? ConsoleColor.Red : ConsoleColor.White;
                            Console.Write("开始游戏");
                            Console.SetCursorPosition(w / 2 - 4, 15);
                            Console.ForegroundColor = nowSelIndex == 1 ? ConsoleColor.Red : ConsoleColor.White;
                            Console.Write("退出游戏");
                            // 检测 输入
                            // 检测玩家 输入的一个键内容 并且不会再控制台上显示输入的内容
                            char input = Console.ReadKey(true).KeyChar;
                            switch (input)
                            {
                                case 'W':
                                case 'w':
                                    --nowSelIndex;
                                    if (nowSelIndex < 0)
                                    {
                                        nowSelIndex = 0;
                                    }
                                    break;
                                case 'S':
                                case 's':
                                    ++nowSelIndex;
                                    if (nowSelIndex > 1)
                                    {
                                        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)
                            {
                                break;
                            }
                        }
                        #endregion
                        break;
                    //游戏场景
                    case 2:
                        Console.Clear();
                        #region 4 不变的红墙
                        //设置颜色为红色
                        Console.ForegroundColor = ConsoleColor.Red;
                        //画墙
                        //上方墙
                        for (int i = 0; i < w; i += 2)
                        {
                            //上方墙
                            Console.SetCursorPosition(i, 0);
                            Console.Write("■");
                            //下方墙
                            Console.SetCursorPosition(i, h - 1);
                            Console.Write("■");
                            //中间墙
                            Console.SetCursorPosition(i, h - 6);
                            Console.Write("■");
                        }
                        //左边的墙
                        for (int i = 0; i < h; i++)
                        {
                            //左边的墙
                            Console.SetCursorPosition(0, i);
                            Console.Write("■");
                            //右边的墙
                            Console.SetCursorPosition(w - 2, i);
                            Console.Write("■");
                        }
                        #endregion

                        #region 5 boss属性相关
                        int bossX = 24;
                        int bossY = 15;
                        int bossAtkMin = 7;
                        int bossAtkMax = 13;
                        int bossHp = 100;
                        string bossIcon = "■";
                        //申明一个 颜色变量
                        ConsoleColor bossColor = ConsoleColor.Green;
                        #endregion

                        #region 6 玩家属性相关
                        int playerX = 4;
                        int playerY = 5;
                        int playerAtkMin = 8;
                        int playerAtkMax = 12;
                        int playerHp = 100;
                        string playerIcon = "●";
                        ConsoleColor playerColor = ConsoleColor.Yellow;
                        //玩家输入的内容 外面申明 节约性能
                        char playerInput;
                        #endregion

                        #region 8 公主相关
                        int princessX = 24;
                        int princessY = 5;
                        string princessIcon = "★";
                        ConsoleColor princessColor = ConsoleColor.Blue;
                        #endregion

                        #region 7 玩家战斗相关
                        //战斗状态
                        bool isFight = false;
                        //作用是 从while循环内部的switch 改变标识 用来跳出外层的while循环
                        bool isOver = false;
                        #endregion

                        //游戏场景的死循环 专门用来 检测 玩家输入相关循环
                        while (true)
                        {
                            #region 5 boss属性相关
                            //boss活着时才绘制
                            if (bossHp > 0)
                            {
                                //绘制boss图标
                                Console.SetCursorPosition(bossX, bossY);
                                Console.ForegroundColor = bossColor;
                                Console.Write(bossIcon);
                            }
                            #endregion
                            #region 8 公主相关
                            else
                            {
                                Console.SetCursorPosition(princessX, princessY);
                                Console.ForegroundColor = princessColor;
                                Console.Write(princessIcon);
                            }
                            #endregion
                            #region 6 玩家移动相关
                            //画出玩家
                            Console.SetCursorPosition(playerX, playerY);
                            Console.ForegroundColor = playerColor;
                            Console.Write(playerIcon);
                            //得到玩家输入
                            playerInput = Console.ReadKey(true).KeyChar;
                            #endregion

                            //战斗状态处理什么逻辑
                            if (isFight)
                            {
                                #region 7 玩家战斗相关
                                //如果是战斗状态 你做什么
                                //只会处理J键 
                                if (playerInput == 'J' || playerInput == 'j')
                                {
                                    //在这判断 玩家或者怪物 是否死亡 如果死亡了 继续之后的流程
                                    if (playerHp <= 0)
                                    {
                                        //游戏结束
                                        //输掉了 应该直接显示 我们的 游戏结束界面
                                        nowSceneID = 3;
                                        gameOverInfo = "游戏失败";
                                        break;
                                    }
                                    else if (bossHp <= 0)
                                    {
                                        //去营救公主
                                        //boss擦除
                                        Console.SetCursorPosition(bossX, bossY);
                                        Console.Write("  ");
                                        isFight = false;
                                    }
                                    else
                                    {
                                        //去处理按J键打架
                                        // 玩家打怪物
                                        Random r = new Random();
                                        //得到随机攻击了
                                        int atk = r.Next(playerAtkMin, playerAtkMax);
                                        //血量减对应的攻击力
                                        bossHp -= atk;
                                        //打印信息
                                        Console.ForegroundColor = ConsoleColor.Green;
                                        //先擦除这一行 上次显示的内容
                                        Console.SetCursorPosition(2, h - 4);
                                        Console.Write("                                           ");
                                        //再来写新的信息
                                        Console.SetCursorPosition(2, h - 4);
                                        Console.Write("你对boss造成了{0}点伤害,boss剩余血量为{1}", atk, bossHp);
                                        // 怪物打玩家
                                        if (bossHp > 0)
                                        {
                                            //得到随机攻击了
                                            atk = r.Next(bossAtkMin, bossAtkMax);
                                            playerHp -= atk;

                                            //打印信息
                                            Console.ForegroundColor = ConsoleColor.Yellow;
                                            //先擦除这一行 上次显示的内容
                                            Console.SetCursorPosition(2, h - 3);
                                            Console.Write("                                           ");
                                            //再来写新的信息
                                            //boss如果把玩家打死了 做什么
                                            if (playerHp <= 0)
                                            {
                                                Console.SetCursorPosition(2, h - 3);
                                                Console.Write("很遗憾,你未能通过boss的试炼,战败了");
                                            }
                                            else
                                            {
                                                Console.SetCursorPosition(2, h - 3);
                                                Console.Write("boss对你造成了{0}点伤害,你的剩余血量为{1}", atk, playerHp);
                                            }
                                        }
                                        else
                                        {
                                            //擦除之前的战斗信息
                                            Console.SetCursorPosition(2, h - 5);
                                            Console.Write("                                           ");
                                            Console.SetCursorPosition(2, h - 4);
                                            Console.Write("                                           ");
                                            Console.SetCursorPosition(2, h - 3);
                                            Console.Write("                                           ");
                                            //显示恭喜胜利的信息
                                            Console.SetCursorPosition(2, h - 5);
                                            Console.Write("你战胜了boss,快去营救公主");
                                            Console.SetCursorPosition(2, h - 4);
                                            Console.Write("前往公主身边按J键继续");
                                        }
                                    }
                                }
                                #endregion
                            }
                            //非战斗状态处理什么逻辑
                            else
                            {
                                #region 6 玩家移动相关
                                //擦除
                                Console.SetCursorPosition(playerX, playerY);
                                Console.Write("  ");
                                //改位置
                                switch (playerInput)
                                {
                                    case 'W':
                                    case 'w':
                                        --playerY;
                                        if (playerY < 1)
                                        {
                                            playerY = 1;
                                        }
                                        //位置如果和boss重合了 并且boss没有死
                                        else if (playerX == bossX && playerY == bossY && bossHp > 0)
                                        {
                                            //拉回去
                                            ++playerY;
                                        }
                                        else if (playerX == princessX && playerY == princessY && bossHp <= 0)
                                        {
                                            //拉回去
                                            ++playerY;
                                        }
                                        break;
                                    case 'A':
                                    case 'a':
                                        playerX -= 2;
                                        if (playerX < 2)
                                        {
                                            playerX = 2;
                                        }
                                        else if (playerX == bossX && playerY == bossY && bossHp > 0)
                                        {
                                            //拉回去
                                            playerX += 2;
                                        }
                                        else if (playerX == princessX && playerY == princessY && bossHp <= 0)
                                        {
                                            //拉回去
                                            playerX += 2;
                                        }
                                        break;
                                    case 'S':
                                    case 's':
                                        ++playerY;
                                        if (playerY > h - 7)
                                        {
                                            playerY = h - 7;
                                        }
                                        else if (playerX == bossX && playerY == bossY && bossHp > 0)
                                        {
                                            //拉回去
                                            --playerY;
                                        }
                                        else if (playerX == princessX && playerY == princessY && bossHp <= 0)
                                        {
                                            //拉回去
                                            --playerY;
                                        }
                                        break;
                                    case 'D':
                                    case 'd':
                                        playerX += 2;
                                        if (playerX > w - 4)
                                        {
                                            playerX = w - 4;
                                        }
                                        else if (playerX == bossX && playerY == bossY && bossHp > 0)
                                        {
                                            //拉回去
                                            playerX -= 2;
                                        }
                                        else if (playerX == princessX && playerY == princessY && bossHp <= 0)
                                        {
                                            //拉回去
                                            playerX -= 2;
                                        }
                                        break;
                                    case 'J':
                                    case 'j':
                                        #region 7 玩家战斗相关
                                        //开始战斗
                                        //要让玩家不能再移动
                                        //下方能够显示信息
                                        if ((playerX == bossX && playerY == bossY - 1 ||
                                            playerX == bossX && playerY == bossY + 1 ||
                                            playerX == bossX - 2 && playerY == bossY ||
                                            playerX == bossX + 2 && playerY == bossY) && bossHp > 0)
                                        {
                                            isFight = true;
                                            //可以开始战斗
                                            Console.SetCursorPosition(2, h - 5);
                                            Console.ForegroundColor = ConsoleColor.White;
                                            Console.Write("开始和Boss战斗了,按J键继续");
                                            Console.SetCursorPosition(2, h - 4);
                                            Console.Write("玩家当前血量为{0}", playerHp);
                                            Console.SetCursorPosition(2, h - 3);
                                            Console.Write("boss当前血量为{0}", bossHp);
                                        }
                                        #endregion
                                        #region 8 公主相关
                                        //判断是否在公主身边按J键
                                        else if ((playerX == princessX && playerY == princessY - 1 ||
                                            playerX == princessX && playerY == princessY + 1 ||
                                            playerX == princessX - 2 && playerY == princessY ||
                                            playerX == princessX + 2 && playerY == princessY) && bossHp <= 0)
                                        {
                                            //改变 场景ID
                                            nowSceneID = 3;
                                            gameOverInfo = "游戏通关";
                                            //跳出 游戏界面的while循环 回到主循环
                                            isOver = true;
                                        }
                                        #endregion
                                        break;
                                }
                                #endregion
                            }
                            #region 8 公主相关
                            //外层while循环逻辑
                            if (isOver)
                            {
                                //就是和while配对
                                break;
                            }
                            #endregion
                        }
                        break;
                    //结束场景
                    case 3:
                        Console.Clear();
                        #region 9 结束场景逻辑
                        //标题的显示
                        Console.SetCursorPosition(w / 2 - 4, 5);
                        Console.ForegroundColor = ConsoleColor.White;
                        Console.Write("GameOver");
                        //可变内容的显示 根据失败或者 成功显示的内容不一样
                        Console.SetCursorPosition(w / 2 - 4, 7);
                        Console.ForegroundColor = ConsoleColor.Green;
                        Console.Write(gameOverInfo);

                        int nowSelEndIndex = 0;
                        while (true)
                        {
                            bool isQuitEndWhile = false;

                            Console.SetCursorPosition(w / 2 - 6, 9);
                            Console.ForegroundColor = nowSelEndIndex == 0 ? ConsoleColor.Red : ConsoleColor.White;
                            Console.Write("回到开始界面");
                            Console.SetCursorPosition(w / 2 - 4, 11);
                            Console.ForegroundColor = nowSelEndIndex == 1 ? ConsoleColor.Red : ConsoleColor.White;
                            Console.Write("退出游戏");

                            char input = Console.ReadKey(true).KeyChar;

                            switch (input)
                            {
                                case 'W':
                                case 'w':
                                    --nowSelEndIndex;
                                    if (nowSelEndIndex < 0)
                                    {
                                        nowSelEndIndex = 0;
                                    }
                                    break;
                                case 'S':
                                case 's':
                                    ++nowSelEndIndex;
                                    if (nowSelEndIndex > 1)
                                    {
                                        nowSelEndIndex = 1;
                                    }
                                    break;
                                case 'J':
                                case 'j':
                                    if (nowSelEndIndex == 0)
                                    {
                                        nowSceneID = 1;
                                        isQuitEndWhile = true;
                                    }
                                    else
                                    {
                                        Environment.Exit(0);
                                    }
                                    break;
                            }

                            //为了 从switch中跳出上一层的 while循环 加的标识
                            if (isQuitEndWhile)
                            {
                                break;
                            }
                        }
                        #endregion
                        break;
                }
            }
            #endregion
        }
    }
}


五、小O总结

  对于跟着小O博客学习的友友们,这应该是写点第一个小游戏,虽然是控制台的小游戏,但是框架设计和思维引导是和一般项目分析步骤是一样的。《骑士营救公主》这个小游戏,代码量不高,对于第一次正式练手的小白们,有难度是正常的,可以多看看小O的思路讲解和需求分析,尝试完成复刻。如果有思路问题和代码疑问,欢迎和小O交流,也可以直接在评论区留言。
  由于这个作为入门小实践,小O没有使用方法和类进行代码优化,方便没有对象思维是小白们练手,大家可以自行优化,后续小O会在专栏中更新其他小实践,引导入门的友友完成简单练手和实践。
  本篇博文是C#入门的最后一篇博文,大家完成小实践后,小O会带领大家进入新的阶段——C#基础学习!大家尽情期待!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值