どんなに遠くへ行っても、旅を始めた初心を忘れないでください
C/C++ ゲーム開発
こんにちは、ミナさん、Junxi_ です。最近、本格的にゲーム開発を学び始めました。ブログを書くことで学んだ知識や経験を共有したいと思います。これがこのコラムの目的です。これらの独立した C# 小さなプロジェクトが、ゲームを作成している皆さんのお役に立てれば幸いです。結局のところ、ゲーム開発を学ぶ最良の方法は、自分でゲームを作ることです。!
ドラゴンクエスト
序文
- 今日は、引き続き、ドラゴンクエストの 3 番目で最後の部分、ドラゴンを倒して姫を救出するロジックと、それに関連するエンディング インターフェイスのロジックについて話します。
- まずはゲームの全体的なフローチャートをここに載せておきます。
ドラゴンを倒した後
- ドラゴンの試練に失敗してゲーム画面に出入りしたプレイヤーと、姫の救出に成功して一緒にゲームに出入りしたプレイヤーについてお話していきます まず、姫の救出方法について話しましょう。
プリンセスを救出する
- 戦士が十分な勇気と幸運でドラゴンを倒すことができれば、私たちはプリンセスを救出しに行くことができます。まず、ここで条件があります。BOSS の HP が 0 にならないと、プリンセスはゲームに登場できません。はい、BOSSのHPが0になった場合のみ、ゲーム画面上に姫の位置をマークすることができますが、同時にドラゴンを倒したので、それを表すアイコンはもう表示しないようにする必要があります。 BOSS は画面上に表示され続けます。これらは、前の章で説明しましたゲーム ロジックで使用されていますが、前章の焦点はプレイヤーの移動と戦闘ロジックであったため、詳細には触れませんでした。コードのこの部分を通じてそれを実行します。
//hp>0时,boss活着才绘制
if (bossHp > 0)
{
Console.SetCursorPosition(bossX, bossY);
Console.ForegroundColor = bossColor;
Console.Write(bossIcon);
}
#region 6 公主显示
//公主显示
else
{
Console.SetCursorPosition(princessX,princessY);
Console.ForegroundColor = princessColor;
Console.Write(princessIcon);
}
#endregion
//擦除BOSS
else if(bossHp<=0)
{
//去营救公主
//boss擦除
Console.SetCursorPosition(bossX, bossY);
Console.Write(" ");
isFight = false;
continue;
}
- プリンセスの初期化に関しては、プリンセスの位置、プリンセスのアイコン、アイコンの色を設定するだけなので、ここでは詳しく説明しません。なお、これは分割の説明を目的としたもので、実際にはまとまったコードではありませんが、この部分の内容が誰でも理解できるように、最後に完全なソースコードを公開します。
お姫様を救出する方法
- 私たちは小さなコンソール ゲームです。同時に、ここでは大きなゲームのフレームワークについて説明しているだけなので、すべてがシンプルに保たれています。ここで、プリンセスのところに来て、J キーを押してプリンセスを救出します (もちろん救出です)ここのお姫様の位置もデザインできます もっと複雑です たとえば、お姫様の位置はランダムな数値にすることができます お姫様を救出するたびに、別の場所に移動します 救出が成功したとみなされるのは 3 回だけです など場所は自由にカスタマイズ可能(特に条件はありません)
case 'j':
case 'J':
//判断是否在公主身边
else if (((playerX == princessX && playerY == princessY - 1) || (playerX == princessX && playerY == princessY + 1) ||
(playerX == princessX - 2 && princessY == playerY) || (playerX == princessX + 2 && playerY == princessY)) && bossHp <= 0)
{
nowSceneID = 3;//修改场景选择ID进入退出界面
nowEndIndex = "恭喜你救出公主";//这个提示语在之后结束界面会用到
//跳出while循环,回到主循环
isOver = true;
}
break;
}
if (isOver)
{
//此时的break与while配对
break;
}
- これは while ループ内にあるため、シーン選択の switch ステートメントに再度入る必要があるため、ループを終了してシーンを再選択するのを支援するために isOver が定義されています。
ゲーム終了インターフェイス
- ゲーム終了画面に入るときは 2 つの状況があります。1 つ目は、王女が救出されたことです。2 つ目は、戦士がドラゴンを倒すことができなかったということです。この時点で、ゲーム終了にも入る必要があります。インターフェース。
//在这判断玩家或者怪物是否死亡,如果死了,继续后面的流程
if(playerHp<=0)
{
//游戏结束
//游戏结束画面
isOver = true;
nowSceneID = 3;
nowEndIndex = "很遗憾你被恶龙击败了";
endSay = 1;
break;
}
- 説明すると、ここの nowEndIndex と endSay には、上記の王女の救出が成功した後の nowEndIndex もあります。その時の定義は「王女の救出おめでとうございます。」でした。終了インターフェイスに入るときに、プレイヤーにプロンプトを表示する必要があります。失敗したか失敗したか 王女の救出に成功した これは、プレイヤーにゲーム結果を思い出させるためにエンドインターフェイスに印刷された別の文です 同時に、これら 2 つのプロンプトの単語数は異なります。これら 2 つの段落を中央に表示できるようにするために、endSay を定義し、その値を使用してテキストをどこに印刷する必要があるかを決定します。
- その他、終了インターフェイスと開始インターフェイスは非常に似ているので、関連するコードを直接見てみましょう。
case 3:
Console.Clear();
int nowEndSelIndex = 0;
while (true)
{
bool EndQuitWhile = false;
Console.SetCursorPosition(w / 2 - 4, 5);
Console.ForegroundColor = ConsoleColor.White;
Console.Write("GameOver");
if(endSay==1)
Console.SetCursorPosition(w / 2 - 8,7);
else
Console.SetCursorPosition(w / 2 - 6,7);
Console.ForegroundColor = ConsoleColor.DarkRed;
Console.Write(nowEndIndex);
Console.ForegroundColor=nowEndSelIndex==0?ConsoleColor.Red:ConsoleColor.White;
Console.SetCursorPosition(w / 2 - 4, 10);
Console.Write("继续游戏");
Console.ForegroundColor = nowEndSelIndex == 0 ? ConsoleColor.White : ConsoleColor.Red;
Console.SetCursorPosition(w / 2 - 4, 12);
Console.Write("退出游戏");
char endInput=Console.ReadKey(true).KeyChar;
switch (endInput)
{
case 'w':
case 'W':
Console.Clear();
nowEndSelIndex = 0;
break;
case 's':
case 'S':
Console.Clear();
nowEndSelIndex = 1;
break;
case 'j':
case 'J':
if (nowEndSelIndex == 1)
Environment.Exit(0);
else
{
nowSceneID = 1;
EndQuitWhile = true;
}
break;
}
if(EndQuitWhile)
{
break;
}
}
break;
}
- プレイヤーがゲームを終了してハイライト表示するときに「J」キーを押すと、ゲームを直接終了します。プレイヤーがゲームを続行したい場合は、ゲームシーンをゲーム開始インターフェイスに切り替える必要があるため、ここで EndQuitwhile を実行します。ゲームシーンの切り替えループに入り、残りについては開始インターフェイスとまったく同じであるため、詳細は説明しません。
ゲーム全体のソースコード
- この小さなコンソール ゲームについてはこれで十分です。ここでは、チェックして試してみるのに便利なように、ゲームのソース コードとスクリーンショットを提供します。
using System;
using System.Diagnostics;
using System.Runtime.Intrinsics.X86;
namespace 王子救公主
{
class Program
{
static void Main(string[] args)
{
//隐藏光标
Console.CursorVisible = false;
//设置舞台的大小
int w = 60;
int h = 40;
Console.SetWindowSize(w,h);
Console.SetBufferSize(w,h);
//当前场景的编号
int nowSceneID = 1;
string nowEndIndex ="";
int endSay = 0;
while (true)
{
//不同的场景进行不同的逻辑处理
switch (nowSceneID)
{
case 1:
Console.Clear();
#region 1 开始界面
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;
}
#endregion
break;
case 2:
Console.Clear();
#region 2 红墙
Console.ForegroundColor = ConsoleColor.Red;
//画墙
//设为红色
int i = 0;
//横墙
for(i = 0; i < w;i+=2)
{
Console.SetCursorPosition(i, 0);
Console.Write('■');
Console.SetCursorPosition(i, h-1);
Console.Write('■');
Console.SetCursorPosition(i, h-9);
Console.Write('■');
}
//竖墙
int j = 0;
for (j = 0; j <h; j++)
{
Console.SetCursorPosition(0, j);
Console.Write('■');
Console.SetCursorPosition(w-2,j);
Console.Write('■');
}
#endregion
#region
#region 3 Boss属性相关
int bossX = 24;
int bossY = 15;
int bossAtkMin = 7;
int bossAtkMax = 13;
int bossHp = 100;
string bossIcon = "●";
//申明一个颜色变量
ConsoleColor bossColor = ConsoleColor.Red;
#endregion
#region 4 玩家属性相关
int playerX = 4;
int playerY = 5;
int playerAtkMin = 7;
int playerAtkMax = 13;
int playerHp = 100;
string playerIcon = "●";
ConsoleColor playerColor = ConsoleColor.Green;
//公主相关
int princessX = 24;
int princessY = 5;
string princessIcon = "▲";
ConsoleColor princessColor = ConsoleColor.Blue;
char playerInput;
#endregion
#region 5 玩家战斗相关
bool isFight = false;
//游戏结束
bool isOver=false;
#endregion
//游戏场景的死循环 专门用来 检测玩家的输入相关的循环
while (true)
{
//画出玩家
Console.SetCursorPosition(playerX, playerY);
Console.ForegroundColor= playerColor;
Console.Write(playerIcon);
//不停的输入wasd键 都可以控制它移动
//hp>0时,boss活着才绘制
if (bossHp > 0)
{
Console.SetCursorPosition(bossX, bossY);
Console.ForegroundColor = bossColor;
Console.Write(bossIcon);
}
#region 6 公主显示
//公主显示
else
{
Console.SetCursorPosition(princessX, princessY);
Console.ForegroundColor = princessColor;
Console.Write(princessIcon);
}
#endregion
Console.SetCursorPosition(playerX, playerY);
Console.ForegroundColor= playerColor;
Console.Write(playerIcon);
//玩家输入
playerInput = Console.ReadKey(true).KeyChar;
if(isFight)
{
//如果是战斗状态
//只会处理j键
if(playerInput=='j'||playerInput=='J')
{
//在这判断玩家或者怪物是否死亡,如果死了,继续后面的流程
if(playerHp<=0)
{
//游戏结束
//游戏结束画面
isOver = true;
nowSceneID = 3;
nowEndIndex = "很遗憾你被恶龙击败了";
endSay = 1;
break;
}
else if(bossHp<=0)
{
//去营救公主
//boss擦除
Console.SetCursorPosition(bossX, bossY);
Console.Write(" ");
isFight = false;
continue;
}
//玩家打怪物
Random r= new Random();
int atk = r.Next(playerAtkMin,playerAtkMax);
bossHp -= atk;
Console.ForegroundColor=ConsoleColor.Green;
Console.SetCursorPosition(2, h - 7);
Console.Write(" ");
if (bossHp <= 0)
{
//擦除
Console.SetCursorPosition(2, h - 6);
Console.Write(" ");
Console.SetCursorPosition(2, h - 7);
Console.Write(" ");
Console.SetCursorPosition(2, h - 8);
Console.Write(" ");
Console.SetCursorPosition(2, h - 8);
Console.Write("你发动了致命一击造成了{0},恭喜你击败了恶龙", atk);
Console.ForegroundColor = ConsoleColor.Red;
Console.SetCursorPosition(2, h - 7);
Console.Write("快去营救公主!!!,按J键继续");
}
else
{
Console.SetCursorPosition(2, h - 7);
Console.Write("勇士对恶龙造成了{0}点伤害,此时恶龙还有{1}血", atk, bossHp);
//怪兽打玩家
atk = r.Next(bossAtkMin, bossAtkMax);
playerHp -= atk;
Console.ForegroundColor = ConsoleColor.Red;
Console.SetCursorPosition(2, h - 6);
Console.Write(" ");
//Boss打死玩家
if(playerHp<=0)
{
Console.SetCursorPosition(2, h - 6);
Console.Write("很遗憾,你未能战胜恶龙");
}
else
{
Console.SetCursorPosition(2, h - 6);
Console.Write("恶龙对勇士造成了{0}点伤害,此时你还有{1}血", atk, playerHp);
}
}
}
}
else
{
#region 6 玩家移动相关
//擦除
Console.SetCursorPosition(playerX, playerY);
Console.Write(" ");
switch (playerInput)
{
//贯穿
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 'w':
case 'W':
playerY--;
if (playerY < 1)
playerY++;
else if (playerX == bossX && playerY == bossY && bossHp > 0)
playerY++;
else if (playerX == princessX && princessY == playerY && bossHp <= 0)
playerY++;
break;
case 's':
case 'S':
playerY++;
if (playerY > h - 10)
playerY--;
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 -= 2;
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':
//开始战斗
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 - 8);
Console.ForegroundColor = ConsoleColor.White;
Console.Write("你开始和恶龙战斗了,按J键继续");
}
//判断是否在公主身边
else if (((playerX == princessX && playerY == princessY - 1) || (playerX == princessX && playerY == princessY + 1) ||
(playerX == princessX - 2 && princessY == playerY) || (playerX == princessX + 2 && playerY == princessY)) && bossHp <= 0)
{
nowSceneID = 3;
nowEndIndex = "恭喜你救出公主";
//跳出while循环,回到主循环
isOver = true;
}
break;
}
}
if (isOver)
{
//此时的break与while配对
break;
}
}
break;
case 3:
Console.Clear();
int nowEndSelIndex = 0;
while (true)
{
bool EndQuitWhile = false;
Console.SetCursorPosition(w / 2 - 4, 5);
Console.ForegroundColor = ConsoleColor.White;
Console.Write("GameOver");
if(endSay==1)
Console.SetCursorPosition(w / 2 - 8,7);
else
Console.SetCursorPosition(w / 2 - 6,7);
Console.ForegroundColor = ConsoleColor.DarkRed;
Console.Write(nowEndIndex);
Console.ForegroundColor=nowEndSelIndex==0?ConsoleColor.Red:ConsoleColor.White;
Console.SetCursorPosition(w / 2 - 4, 10);
Console.Write("继续游戏");
Console.ForegroundColor = nowEndSelIndex == 0 ? ConsoleColor.White : ConsoleColor.Red;
Console.SetCursorPosition(w / 2 - 4, 12);
Console.Write("退出游戏");
char endInput=Console.ReadKey(true).KeyChar;
switch (endInput)
{
case 'w':
case 'W':
Console.Clear();
nowEndSelIndex = 0;
break;
case 's':
case 'S':
Console.Clear();
nowEndSelIndex = 1;
break;
case 'j':
case 'J':
if (nowEndSelIndex == 1)
Environment.Exit(0);
else
{
nowSceneID = 1;
EndQuitWhile = true;
}
break;
}
if(EndQuitWhile)
{
break;
}
}
break;
}
}
}
}
#endregion
}
#endregion
要約する
- さて、最初の C# 実践ゲームはこれで終わりですが、今後も他のゲームの指導内容を更新していきますので、お楽しみに!!
- 前回の内容が見つからないように、前回の教えへのリンクを貼っておきます
【C#プロジェクト実戦】コンソールゲーム ドラゴンクエスト(2) - ゲームシーンの設定とプレイヤーの戦闘ロジック
【C#プロジェクト実戦】コンソールゲーム ドラゴンクエスト(1)——ゲームの初期設定と開始インターフェース
新しいブロガーが作成するのは簡単ではありませんが、記事の内容が役に立ったと感じたら、終了する前に 3 回続けて読んだほうがよいでしょう。皆様の応援が更新の励みになります!!!
**(Keli はブロガーを 3 回連続でサポートするようお願いしています!!! 以下のコメントをクリックして「いいね」を押し、Keli を支援するために集めてください)**