C# 实现文字版角色扮演游戏:英雄养成与战斗
2.1 项目概览
2.1.1 功能简介
本教程将引导你使用 C# 构建一个纯文字界面的角色扮演游戏(RPG)。玩家需先通过账户密码验证登录,成功后可从预定义英雄列表中选取一位进行扮演。每位英雄拥有名称、背景描述、攻击、防御及等级等属性。游戏的核心交互包括购买装备提升战力,以及挑战怪物获取金币和经验值。
说明
- 角色扮演(RPG)是一种玩家在虚构世界中扮演特定角色,并根据角色属性(如力量、智力)和游戏规则推进剧情的游戏类型。
- 文字界面游戏指所有交互均通过文本呈现,不涉及图形或音频元素。
2.1.2 模块划分
项目整体分为四个核心模块:
- 用户登录:验证用户输入的账号和密码。
- 角色选择:允许用户从列表中挑选英雄,并展示其详细信息。
- 装备购买:玩家可花费金币购买武器或防具,装备后影响英雄的攻击和防御属性。
- 战斗升级:玩家操控英雄与怪物战斗,胜利后获得金币和经验,累积经验可提升英雄等级。
2.1.3 业务逻辑流程
游戏的执行流程如下:
- 登录验证:通过循环结构不断提示输入,直到账号和密码匹配正确为止。
- 选择英雄:展示所有可选英雄,用户选择后显示其基础属性。
- 新手村菜单:进入主循环,玩家可选择"商店"(购买装备)或"出村"(进行战斗)。
- 装备购买:列出可购装备列表,根据用户选择进行购买和装备。
- 战斗循环:与怪物进行回合制对抗,直至怪物生命值归零,然后结算奖励。
- 游戏延续:询问用户是否继续,输入 'Y' 则返回新手村,输入 'N' 则结束游戏。
2.1.4 技术要点
- 方法:将不同功能模块化,封装在独立方法中,提升代码可读性与可维护性。
- 结构体:使用结构体(
struct)来定义英雄、装备和怪物等实体,以组合多个属性。 - 数组:利用结构体数组批量存储和管理多个实体数据。
- 流程控制:综合运用顺序、选择(
if/switch)和循环(do-while)结构实现游戏逻辑。 - 运算表达式:进行计算,例如伤害值 = 英雄攻击力 + 装备攻击力 - 怪物防御力。
2.1.5 课时计划
项目计划总课时为 12 节,分配如下:
| 序号 | 任务 | 课时 |
|---|---|---|
| 1 | 项目分析、数据模型与程序结构设计 | 2 |
| 2 | 结构体定义与程序框架搭建 | 2 |
| 3 | 登录模块讲解与实现 | 1 |
| 4 | 英雄选择模块设计讲解 | 1 |
| 5 | 英雄选择模块编码实现 | 2 |
| 6 | 购买装备模块设计讲解 | 1 |
| 7 | 购买装备模块编码实现 | 1 |
| 8 | 战斗模块设计讲解 | 1 |
| 9 | 战斗模块编码实现 | 1 |
2.2 数据模型与程序结构
2.2.1 数据模型设计
项目需定义三个核心结构体:
1. 怪物结构体 (Monster)
怪物作为战斗对手,需包含以下属性:
| 成员 | 类型 | 说明 |
|---|---|---|
| Name | string | 名称 |
| Attack | int | 攻击力 |
| Defense | int | 防御力 |
| Life | int | 生命值 |
| KillMoney | int | 击杀奖励金币 |
| KillExp | int | 击杀奖励经验 |
public struct Monster
{
public string Name;
public int Attack;
public int Defense;
public int Life;
public int KillMoney;
public int KillExp;
}
2. 装备结构体 (Equipment)
装备用于提升英雄属性,设计如下:
| 成员 | 类型 | 说明 |
|---|---|---|
| Name | string | 名称 |
| Attack | int | 攻击力加成 |
| Defense | int | 防御力加成 |
| Price | int | 购买价格 |
public struct Equipment
{
public string Name;
public int Price;
public int AttackBonus;
public int DefenseBonus;
}
3. 英雄结构体 (Character)
英雄是玩家操控的核心角色,结构如下:
| 成员 | 类型 | 说明 |
|---|---|---|
| Name | string | 名称 |
| Description | string | 背景简介 |
| Attack | int | 基础攻击力 |
| Defense | int | 基础防御力 |
| Level | int | 等级 |
| Gold | int | 持有金币 |
| Experience | int | 持有经验值 |
| Weapon | Equipment | 当前武器 |
| Armor | Equipment | 当前防具 |
public struct Character
{
public string Name;
public string Description;
public int Attack;
public int Defense;
public int Level;
public int Gold;
public int Experience;
public Equipment Weapon;
public Equipment Armor;
}
2.2.2 方法结构设计
采用模块化方法,将各功能封装为独立方法,由 Main 方法统一协调。
1. 用户登录
public static bool PerformLogin()
{
return true;
}
返回布尔值,true 表示登录成功。
2. 选择英雄
public static Character PickCharacter()
{
return new Character();
}
返回 Character 类型,代表玩家选择的英雄。
3. 购买装备
public static void PurchaseItem(ref Character player)
{
}
使用 ref 关键字,确保对英雄属性的修改在方法外生效。
4. 战斗升级
public static void EngageBattle(ref Character player)
{
}
同样使用 ref 关键字,以保留战斗后英雄属性的变化。
5. 主方法入口
static void Main(string[] args)
{
Console.WriteLine("--------------------");
Console.WriteLine(" 王者荣耀 ");
Console.WriteLine("--------------------");
bool loginStatus = false;
do
{
loginStatus = PerformLogin();
} while (!loginStatus);
Console.WriteLine("召唤师,欢迎来到王者荣耀!");
Console.WriteLine("在这片虚构的王者大陆上,重生的英雄们演绎着新的传奇。");
Console.WriteLine("准备好了吗?精彩对战即将爆发!");
Character hero = PickCharacter();
Console.Write($"你已经选择了英雄:{hero.Name},");
Console.WriteLine("下面开始你的王者大陆之旅吧!");
Console.WriteLine("--------------------");
Console.WriteLine(" 新手村 ");
Console.WriteLine("--------------------");
string continueGame = "n";
do
{
Console.WriteLine("1.购买装备");
Console.WriteLine("2.出村练级");
Console.WriteLine("请输入对应功能编号进行选择。");
string choice = Console.ReadLine();
switch (choice)
{
case "1":
PurchaseItem(ref hero);
break;
case "2":
EngageBattle(ref hero);
break;
default:
Console.WriteLine("无效选项,请重新输入。");
break;
}
Console.WriteLine("是否继续游戏?(y/n)");
continueGame = Console.ReadLine();
} while (continueGame.ToLower() != "n");
Console.WriteLine("游戏结束,感谢游玩!");
}
2.3 登录模块实现
登录采用循环验证,直到账号为 "admin" 且密码为 "123" 为止。
public static bool PerformLogin()
{
Console.WriteLine("-------登录-------");
Console.Write("请输入账号:");
string username = Console.ReadLine();
Console.Write("请输入密码:");
string password = Console.ReadLine();
if (username == "admin" && password == "123")
{
Console.WriteLine("登录成功!");
Console.WriteLine("-----------------");
return true;
}
else
{
Console.WriteLine("登录失败!");
Console.WriteLine("------------------");
return false;
}
}
2.4 英雄选择模块实现
2.4.1 功能分解
为保持代码清晰,将选择模块拆分为多个子方法:
- 初始化英雄数据:
public static Character[] SetupCharacters() - 显示英雄列表:
public static void DisplayCharacterList(Character[] roster) - 显示英雄详情:
public static void ShowCharacterInfo(Character selected) - 计算实际攻击力:
public static double CalculateAttack(Character hero) - 计算实际防御力:
public static double CalculateDefense(Character hero)
攻击与防御随等级提升:攻击力 = 基础攻击 * (1 + 等级 * 0.3),防御力 = 基础防御 * (1 + 等级 * 0.15)。
2.4.2 代码实现
1. 初始化英雄数据
public static Character[] SetupCharacters()
{
Character[] roster = new Character[5];
roster[0] = new Character { Name = "东皇太一", Description = "楚人于东方立祠祭祀天神,故称东皇。", Attack = 43, Defense = 35, Level = 1, Gold = 200 };
roster[1] = new Character { Name = "大乔", Description = "即小乔的姐姐,江东庐江桥玄的女儿。", Attack = 62, Defense = 30, Level = 1, Gold = 200 };
roster[2] = new Character { Name = "程咬金", Description = "即程知节,本名程咬金,秦王李世民帐下骁将。", Attack = 47, Defense = 37, Level = 1, Gold = 200 };
roster[3] = new Character { Name = "赵云", Description = "常山真定人,字子龙,蜀汉名将。", Attack = 45, Defense = 32, Level = 1, Gold = 200 };
roster[4] = new Character { Name = "孙尚香", Description = "刘备续弦夫人,孙夫人在民间传说中的名字。", Attack = 58, Defense = 28, Level = 1, Gold = 200 };
return roster;
}
2. 显示列表与详情
public static void DisplayCharacterList(Character[] roster)
{
Console.WriteLine("英雄列表:");
for (int i = 0; i < roster.Length; i++)
Console.WriteLine($"{i + 1}.{roster[i].Name}");
}
public static void ShowCharacterInfo(Character selected)
{
Console.WriteLine($"姓名:{selected.Name}");
Console.WriteLine($"简介:{selected.Description}");
Console.WriteLine($"等级:{selected.Level}, 伤害:{CalculateAttack(selected):F2}, 防御:{CalculateDefense(selected):F2}");
}
public static double CalculateAttack(Character hero) => hero.Attack * (1 + hero.Level * 0.3);
public static double CalculateDefense(Character hero) => hero.Defense * (1 + hero.Level * 0.15);
3. 英雄选择方法
public static Character PickCharacter()
{
Character[] roster = SetupCharacters();
Console.WriteLine("--------------------");
Console.WriteLine(" 英雄列表 ");
Console.WriteLine("--------------------");
DisplayCharacterList(roster);
Console.Write("请选择英雄编号:");
int index = int.Parse(Console.ReadLine());
Character chosen;
if (index >= 1 && index <= 5)
chosen = roster[index - 1];
else
{
chosen = roster[0];
Console.WriteLine("编号输入错误,默认选中第一个英雄");
}
ShowCharacterInfo(chosen);
return chosen;
}
2.5 购买装备模块实现
2.5.1 设计思路
需判断装备类型:若防御力为 0,则为武器,增加攻击力;否则为防具,增加防御力。
2.5.2 代码实现
1. 初始化装备
public static Equipment[] SetupEquipment()
{
Equipment[] stock = new Equipment[4];
stock[0] = new Equipment { Name = "铁剑", Price = 100, AttackBonus = 15, DefenseBonus = 0 };
stock[1] = new Equipment { Name = "匕首", Price = 500, AttackBonus = 25, DefenseBonus = 0 };
stock[2] = new Equipment { Name = "布甲", Price = 200, AttackBonus = 0, DefenseBonus = 10 };
stock[3] = new Equipment { Name = "雪山圆盾", Price = 600, AttackBonus = 0, DefenseBonus = 20 };
return stock;
}
2. 显示与购买逻辑
public static void DisplayEquipmentList(Equipment[] stock)
{
for (int i = 0; i < stock.Length; i++)
{
var item = stock[i];
Console.WriteLine($"{i + 1}:{item.Name}, 价格:{item.Price}, 攻击:{item.AttackBonus}, 防御:{item.DefenseBonus}");
}
}
public static void EquipItem(ref Character player, Equipment toBuy)
{
if (player.Gold < toBuy.Price)
{
Console.WriteLine("金币不足,购买失败!");
return;
}
player.Gold -= toBuy.Price;
Console.WriteLine($"{toBuy.Name}购买成功,花费{toBuy.Price}金币!");
if (toBuy.DefenseBonus == 0)
player.Weapon = toBuy;
else
player.Armor = toBuy;
}
public static void PurchaseItem(ref Character player)
{
Console.WriteLine("----------------");
Console.WriteLine("------ 商店 ------");
Console.WriteLine("----------------");
Equipment[] stock = SetupEquipment();
DisplayEquipmentList(stock);
Console.WriteLine($"你拥有{player.Gold}个金币");
Console.WriteLine("请输入装备对应编号来购买装备。");
int choice = int.Parse(Console.ReadLine());
Equipment selected;
if (choice >= 1 && choice <= 4)
selected = stock[choice - 1];
else
{
selected = stock[0];
Console.WriteLine("编号错误,默认购买第一个装备");
}
EquipItem(ref player, selected);
}
2.6 战斗升级模块实现
2.6.1 战斗逻辑
- 怪物属性随英雄等级变化:生命值 = 180 + 等级 * 10,攻击力 = 10 + 等级 * 2,防御力 = 20 + 等级 * 2。
- 奖励:金币 = 50 + 等级 * 10,经验 = 100 + 等级 * 10。
- 伤害计算:伤害 = (英雄实际攻击力 + 武器攻击力)- 怪物防御力。
- 升级条件:累计经验值大于 500 时升级,扣除 500 经验,等级 +1。
2.6.2 代码实现
public static void EngageBattle(ref Character player)
{
Monster enemy;
enemy.Name = "荒野小怪";
enemy.Life = 180 + player.Level * 10;
enemy.Attack = 10 + player.Level * 2;
enemy.Defense = 20 + player.Level * 2;
enemy.KillMoney = 50 + player.Level * 10;
enemy.KillExp = 100 + player.Level * 10;
do
{
int damage = (int)CalculateAttack(player) + player.Weapon.AttackBonus - enemy.Defense;
if (damage < 0) damage = 0;
Console.WriteLine($"{player.Name}对{enemy.Name}造成了{damage}伤害!");
enemy.Life -= damage;
} while (enemy.Life > 0);
Console.WriteLine($"{enemy.Name}被击杀,获得{enemy.KillMoney}金币,{enemy.KillExp}经验");
player.Gold += enemy.KillMoney;
player.Experience += enemy.KillExp;
if (player.Experience > 500)
{
player.Level++;
player.Experience -= 500;
Console.WriteLine($"恭喜你,升级成功!当前等级:{player.Level}");
}
Console.WriteLine($"英雄{player.Name}:金币数:{player.Gold},等级:{player.Level},经验值:{player.Experience}");
}