前言:项目视频展示
飞行棋
一、项目概述
本项目是一个基于C#控制台开发的飞行棋游戏,实现了完整的游戏流程和丰富的游戏功能。游戏支持双人对战(玩家vs电脑),包含多种特殊格子效果,提供了良好的用户交互体验。
二、项目结构
1、核心架构
项目采用场景管理模式,分为三个主要场景
(1)开始场景:游戏主菜单界面
(2)游戏场景:核心游戏玩法界面
(3)结束场景:游戏结果显示界面

2、技术特点
(1)纯控制台界面实现
(2)面向对象编程思想
(3)模块化设计结构
(4)完整的游戏状态管理
三、核心功能模块
1. 场景管理系统
enum E_SceneType
{
Begin, // 开始场景
Game, // 游戏场景
End, // 结束场景
}



2. 游戏地图系统
(1)地图生成:随机生成80个格子
(2)格子类型:
普通格子(85%概率)
炸弹格子(5%概率)- 倒退5格
暂停格子(5%概率)- 暂停一回合
时空隧道(5%概率)- 随机效果


3. 玩家系统
(1)双玩家支持(玩家和电脑)
(2)玩家状态管理(位置、暂停状态)
(3)可视化表示(不同符号和颜色)
四、游戏规则
1、基本规则
(1)玩家和电脑轮流掷骰子前进
(2)先到达终点的玩家获胜
(3)遇到特殊格子触发相应效果
2、特殊格子效果
(1)炸弹格子:后退5格
(2)暂停格子:暂停一回合
(3)时空隧道:
30%概率:后退5格
30%概率:暂停一回合
40%概率:与对方交换位置
五、界面设计
1、控制台界面布局
(1)游戏区域:顶部主要显示区域
(2)信息区域:底部状态提示区域
(3)围墙装饰:红色方块边界

2、视觉元素
玩家:★(青色)
电脑:▲(洋红色)
重合:◎(深绿色)
格子类型使用不同颜色区分

六、核心算法
1、地图生成思想
// 智能路径生成,自动转向
if (indexX == 10)
{
y += 1;
++indexY;
if (indexY == 2)
{
indexX = 0;
indexY = 0;
stepNum = -stepNum; // 反向移动
}
}
2、游戏逻辑流程
(1)初始化游戏场景
(2)绘制地图和玩家
(3)轮流执行玩家回合
(4)检测游戏结束条件
(5)返回相应场景
七、总结
本项目展示了一个完整的C#控制台游戏开发案例,涵盖了游戏开发的多个重要方面:场景管理、对象设计、算法实现、用户交互等。代码结构清晰,功能完整,具有良好的可读性和可扩展性,适合作为学习C#游戏开发的参考项目。
八、附录源代码
using System;
namespace 测试
{
class Program
{
static void Main(string[] args)
{
#region 1 控制台初始化
int w = 50;
int h = 30;
ConsoleInit(w, h);
#endregion
#region 2 场景选择相关
E_SceneType nowSceneType = E_SceneType.Begin;
while (true)
{
switch (nowSceneType)
{
case E_SceneType.Begin:
Console.Clear();
BeginOrEndScene(w, h, ref nowSceneType);
break;
case E_SceneType.Game:
Console.Clear();
GameScene(w, h, ref nowSceneType);
break;
case E_SceneType.End:
Console.Clear();
BeginOrEndScene(w, h, ref nowSceneType);
break;
default:
break;
}
}
#endregion
}
#region 1 控制台初始化
static void ConsoleInit(int w, int h)
{
Console.CursorVisible = false;
Console.SetWindowSize(w, h);
Console.SetBufferSize(w, h);
}
#endregion
#region 3 开始场景逻辑 + 8 结束场景逻辑
static void BeginOrEndScene(int w, int h, ref E_SceneType nowSceneType)
{
Console.ForegroundColor = ConsoleColor.Blue;
Console.SetCursorPosition(nowSceneType == E_SceneType.Begin ? w / 2 - 9 : w / 2 - 4, 8);
Console.Write(nowSceneType == E_SceneType.Begin ? "软件黑马王子飞行棋" : "游戏结束");
int nowSelIndex = 0;
bool isQuitBegin = false;
while (true)
{
Console.SetCursorPosition(nowSceneType == E_SceneType.Begin ? w / 2 - 4 : w / 2 - 5, 13);
Console.ForegroundColor = nowSelIndex == 0 ? ConsoleColor.Red : ConsoleColor.White;
Console.Write(nowSceneType == E_SceneType.Begin ? "开始游戏" : "回到主菜单");
Console.SetCursorPosition(w / 2 - 4, 15);
Console.ForegroundColor = nowSelIndex == 1 ? ConsoleColor.Red : ConsoleColor.White;
Console.Write("退出游戏");
switch (Console.ReadKey(true).Key)
{
case ConsoleKey.W:
--nowSelIndex;
if (nowSelIndex < 0)
{
nowSelIndex = 0;
}
break;
case ConsoleKey.S:
++nowSelIndex;
if (nowSelIndex > 1)
{
nowSelIndex = 1;
}
break;
case ConsoleKey.J:
if (nowSelIndex == 0)
{
nowSceneType = nowSceneType == E_SceneType.Begin ? E_SceneType.Game : E_SceneType.Begin;
isQuitBegin = true;
}
else
{
Environment.Exit(0);
}
break;
}
if (isQuitBegin)
{
break;
}
}
}
#endregion
#region 游戏场景逻辑
static void GameScene(int w, int h, ref E_SceneType nowSceneType)
{
DrawWall(w, h);
Map map = new Map(14, 3, 80);
map.Draw();
Player player = new Player(0, E_PlayerType.Player);
Player computer = new Player(0, E_PlayerType.Computer);
DrawPlayer(player, computer, map);
bool isGameOver = false;
while (true)
{
if (PlayerRandoMove(w, h, ref player, ref computer, map, ref nowSceneType))
{
break;
}
if (PlayerRandoMove(w, h, ref computer, ref player, map, ref nowSceneType))
{
break;
}
}
}
static bool PlayerRandoMove(int w, int h, ref Player p, ref Player otherP, Map map, ref E_SceneType nowSceneType)
{
Console.ReadKey(true);
bool isGameOver = RandomMove(w, h, ref p, ref otherP, map);
map.Draw();
DrawPlayer(p, otherP, map);
if (isGameOver)
{
Console.ReadKey(true);
nowSceneType = E_SceneType.End;
}
return isGameOver;
}
#endregion
#region 4 绘制不变内容(红墙 提示等等)
static void DrawWall(int w, int h)
{
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("■");
Console.SetCursorPosition(i, h - 11);
Console.Write("■");
}
for (int i = 0; i < h; i++)
{
Console.SetCursorPosition(0, i);
Console.Write("■");
Console.SetCursorPosition(w - 2, i);
Console.Write("■");
}
Console.ForegroundColor = ConsoleColor.White;
Console.SetCursorPosition(2, h - 10);
Console.Write("□:普通格子");
Console.ForegroundColor = ConsoleColor.Blue;
Console.SetCursorPosition(2, h - 9);
Console.Write("‖:暂停,一回合不懂");
Console.ForegroundColor = ConsoleColor.Red;
Console.SetCursorPosition(26, h - 9);
Console.Write("●:炸弹,倒退5格");
Console.ForegroundColor = ConsoleColor.Yellow;
Console.SetCursorPosition(2, h - 8);
Console.Write("¤:时空隧道,随机倒退,暂停,换位置");
Console.ForegroundColor = ConsoleColor.Cyan;
Console.SetCursorPosition(2, h - 7);
Console.Write("★:玩家");
Console.ForegroundColor = ConsoleColor.Magenta;
Console.SetCursorPosition(12, h - 7);
Console.Write("▲:电脑");
Console.ForegroundColor = ConsoleColor.DarkGreen;
Console.SetCursorPosition(22, h - 7);
Console.Write("◎:玩家和电脑重合");
Console.ForegroundColor = ConsoleColor.White;
Console.SetCursorPosition(2, h - 5);
Console.Write("按任意键开始扔色子");
}
#endregion
#region 7 绘制玩家
static void DrawPlayer(Player player, Player computer, Map map)
{
if (player.nowIndex == computer.nowIndex)
{
Grid grid = map.grids[player.nowIndex];
Console.SetCursorPosition(grid.pos.x, grid.pos.y);
Console.ForegroundColor = ConsoleColor.DarkGreen;
Console.Write("◎");
}
else
{
player.Draw(map);
computer.Draw(map);
}
}
#endregion
#region 8 扔色子 函数
static void ClearInfo(int h)
{
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 - 2);
Console.Write(" ");
}
static bool RandomMove(int w, int h, ref Player p, ref Player otherP, Map map)
{
ClearInfo(h);
Console.ForegroundColor = p.type == E_PlayerType.Player ? ConsoleColor.Cyan : ConsoleColor.Magenta;
if (p.isPause)
{
Console.SetCursorPosition(2, h - 5);
Console.Write("处于暂停状态,{0}需要暂停一回合", p.type == E_PlayerType.Player ? "你" : "电脑");
Console.SetCursorPosition(2, h - 4);
Console.Write("请按任意键,让{0}开始扔色子", p.type == E_PlayerType.Player ? "电脑" : "你");
p.isPause = false;
return false;
}
Random r = new Random();
int randomNum = r.Next(1, 7);
p.nowIndex += randomNum;
Console.SetCursorPosition(2, h - 5);
Console.Write("{0}扔出的点数为:{1}", p.type == E_PlayerType.Player ? "你" : "电脑", randomNum);
if (p.nowIndex >= map.grids.Length - 1)
{
p.nowIndex = map.grids.Length - 1;
Console.SetCursorPosition(2, h - 4);
if (p.type == E_PlayerType.Player)
{
Console.Write("恭喜你,你率先到达了终点");
}
else
{
Console.Write("很遗憾,电脑率到达了终点");
}
Console.SetCursorPosition(2, h - 3);
Console.Write("请按任意键结束游戏");
return true;
}
else
{
Grid grid = map.grids[p.nowIndex];
switch (grid.type)
{
case E_Grid_Type.Normal:
Console.SetCursorPosition(2, h - 4);
Console.Write("{0}到了一个安全位置", p.type == E_PlayerType.Player ? "你" : "电脑");
Console.SetCursorPosition(2, h - 3);
Console.Write("请按任意键,让{0}开始扔色子", p.type == E_PlayerType.Player ? "电脑" : "你");
break;
case E_Grid_Type.Boom:
p.nowIndex -= 5;
if (p.nowIndex < 0)
{
p.nowIndex = 0;
}
Console.SetCursorPosition(2, h - 4);
Console.Write("{0}踩到了炸弹,退后5格", p.type == E_PlayerType.Player ? "你" : "电脑");
Console.SetCursorPosition(2, h - 3);
Console.Write("请按任意键,让{0}开始扔色子", p.type == E_PlayerType.Player ? "电脑" : "你");
break;
case E_Grid_Type.Pause:
p.isPause = true;
Console.SetCursorPosition(2, h - 4);
Console.Write("{0}到达了暂停点,你需要暂停一回合", p.type == E_PlayerType.Player ? "你" : "电脑");
Console.SetCursorPosition(2, h - 3);
Console.Write("请按任意键,让{0}开始扔色子", p.type == E_PlayerType.Player ? "电脑" : "你");
break;
case E_Grid_Type.Tunnel:
Console.SetCursorPosition(2, h - 4);
Console.Write("{0}踩到了时空隧道", p.type == E_PlayerType.Player ? "你" : "电脑");
randomNum = r.Next(1, 91);
if (randomNum <= 30)
{
p.nowIndex -= 5;
if (p.nowIndex < 0)
{
p.nowIndex = 0;
}
Console.SetCursorPosition(2, h - 3);
Console.Write("触发倒退5格");
}
else if (randomNum <= 60)
{
p.isPause = true;
Console.SetCursorPosition(2, h - 3);
Console.Write("触发暂停一回合");
}
else
{
int temp = p.nowIndex;
p.nowIndex = otherP.nowIndex;
otherP.nowIndex = temp;
Console.SetCursorPosition(2, h - 3);
Console.Write("惊喜,惊喜,双方交换位置");
}
Console.SetCursorPosition(2, h - 2);
Console.Write("请按任意键,让{0}开始扔色子", p.type == E_PlayerType.Player ? "电脑" : "你");
break;
}
}
return false;
}
#endregion
}
#region 2 场景选择相关
enum E_SceneType
{
Begin,
Game,
End,
}
#endregion
#region 5 格子结构体和格子枚举
enum E_Grid_Type
{
Normal,
Boom,
Pause,
Tunnel,
}
struct Vector2
{
public int x;
public int y;
public Vector2(int x, int y)
{
this.x = x;
this.y = y;
}
}
struct Grid
{
public E_Grid_Type type;
public Vector2 pos;
public Grid(int x, int y, E_Grid_Type type)
{
pos.x = x;
pos.y = y;
this.type = type;
}
public void Draw()
{
Console.SetCursorPosition(pos.x, pos.y);
switch (type)
{
case E_Grid_Type.Normal:
Console.ForegroundColor = ConsoleColor.White;
Console.Write("□");
break;
case E_Grid_Type.Boom:
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("●");
break;
case E_Grid_Type.Pause:
Console.ForegroundColor = ConsoleColor.Blue;
Console.Write("‖");
break;
case E_Grid_Type.Tunnel:
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write("¤");
break;
}
}
}
#endregion
#region 6 地图结构体
struct Map
{
public Grid[] grids;
public Map(int x, int y, int num)
{
grids = new Grid[num];
int indexX = 0;
int indexY = 0;
int stepNum = 2;
Random r = new Random();
int randomNum;
for (int i = 0; i < num; i++)
{
randomNum = r.Next(0, 101);
if (randomNum < 85 || i == 0 || i == num - 1)
{
grids[i].type = E_Grid_Type.Normal;
}
else if (randomNum >= 85 && randomNum < 90)
{
grids[i].type = E_Grid_Type.Boom;
}
else if (randomNum >= 90 && randomNum < 95)
{
grids[i].type = E_Grid_Type.Pause;
}
else
{
grids[i].type = E_Grid_Type.Tunnel;
}
grids[i].pos = new Vector2(x, y);
if (indexX == 10)
{
y += 1;
++indexY;
if (indexY == 2)
{
indexX = 0;
indexY = 0;
stepNum = -stepNum;
}
}
else
{
x += stepNum;
++indexX;
}
}
}
public void Draw()
{
for (int i = 0; i < grids.Length; i++)
{
grids[i].Draw();
}
}
}
#endregion
#region 7 玩家枚举和玩家结构体
enum E_PlayerType
{
Player,
Computer,
}
struct Player
{
public E_PlayerType type;
public int nowIndex;
public bool isPause;
public Player(int index, E_PlayerType type)
{
nowIndex = index;
this.type = type;
isPause = false;
}
public void Draw(Map mapInfo)
{
Grid grid = mapInfo.grids[nowIndex];
Console.SetCursorPosition(grid.pos.x, grid.pos.y);
switch (type)
{
case E_PlayerType.Player:
Console.ForegroundColor = ConsoleColor.Cyan;
Console.Write("★");
break;
case E_PlayerType.Computer:
Console.ForegroundColor = ConsoleColor.Magenta;
Console.Write("▲");
break;
}
}
}
#endregion
}

4万+

被折叠的 条评论
为什么被折叠?



