20251209 《python程序设计实验4》

文字 RPG 游戏综合实践报告
一、实验分析
1.1 项目背景与目的
本项目旨在通过开发一款文字 RPG 游戏,综合运用 Python 面向对象编程、流程控制、随机数生成等核心技术,实现角色创建、属性养成、战斗系统、道具管理等核心功能,加深对 Python 编程思想和游戏逻辑设计的理解,提升代码模块化、可维护性的实践能力。
1.2 核心需求分析
本游戏需满足以下核心需求:
角色系统:支持创建不同职业(战士 / 法师)角色,具备姓名、性别、基础属性(生命、攻击、防御、速度等)、属性点分配、装备穿戴等功能;
战斗系统:实现小怪、精英怪、最终 BOSS 的分层战斗逻辑,支持普攻、技能、防御、药水使用等战斗行为,包含伤害计算、状态变化、战斗胜负判定;
道具与装备系统:提供背包管理、装备穿戴 / 卸下、装备属性加成等功能;
辅助系统:包含商店(药水 / 装备购买、抽奖)、休息(状态恢复 + 随机遇敌)、奖励结算等辅助模块;
流程控制:实现主菜单交互、战斗流程循环、游戏胜利 / 失败 / 退出的完整流程。
1.3 技术难点分析
战斗系统的伤害计算逻辑:需结合角色属性、装备加成、防御减免等多维度计算实际伤害,保证数值平衡;
状态同步问题:角色穿戴装备后属性加成需实时生效,战斗中临时属性变化(如战士剑舞加攻)需及时重置;
随机事件控制:精英怪出现概率、道具掉落、药水恢复类型等随机逻辑需兼顾游戏趣味性与平衡性;
流程闭环设计:需保证主菜单、战斗、商店、休息等模块的无缝切换,且各模块状态(如角色血量、金币)实时同步。
具体到python设计上,主要是构建函数与运用,在逻辑上形成闭环,减少bug。
二、系统设计
2.1 总体架构设计
本游戏采用模块化、面向对象的架构设计,整体分为五大核心模块,各模块职责清晰、低耦合,具体架构如下:
1.角色模块(Player类):角色属性、状态展示、加点、装备管理
2.怪物模块:小怪/精英怪/BOSS生成函数(make_enemy/make_boss)
3.战斗模块(battle函数):战斗流程、伤害计算、技能释放
4.辅助模块:商店(shop)、休息(rest)、奖励(reward)、角色创建(create_player)
5.主流程模块(game函数):菜单交互、流程调度、游戏循环
2.2 核心类与函数设计
2.2.1 Player 类(核心角色类)
表格
成员变量 作用
name/gender/job 角色基础信息(姓名 / 性别 / 职业)
max_hp/hp、max_atk 等 基础属性(生命、攻击等)及当前值
point/gold/potion 可分配属性点、金币、药水数量
bag/equip_slot 背包道具、已穿戴装备槽
real_max_hp/real_atk 等 装备加成后的实际属性值
表格
成员方法 作用
init 初始化角色基础属性
apply_equip_bonus 计算装备加成后的实际属性
show_status/show_bag 展示角色状态、背包内容
equip_manage 装备穿戴 / 卸下的交互管理
add_point 属性点分配逻辑
2.2.2 核心函数
表格
函数名 输入参数 输出 / 返回值 核心功能
make_enemy is_elite(是否精英怪) 怪物字典(含名称、血量、攻防等) 生成小怪 / 精英怪属性
make_boss 无 BOSS 生成最终 BOSS 固定属性
battle player、enemy 布尔值(战斗胜负) 核心战斗流程,包含攻击、技能、防御、伤害计算
reward player、is_elite 无 战斗胜利后奖励结算(金币、属性点、道具 / 装备)
game 无 无 游戏主循环,菜单交互与模块调度
2.3 核心逻辑设计
2.3.1 战斗伤害计算逻辑
普攻伤害:实际伤害 = 角色实际攻击 - 怪物防御,最低保底伤害 5 点;
技能伤害:法师火球术在普攻基础 + 30 伤害,战士聚力斩同理,均保底 1 点伤害;
怪物攻击伤害:普通怪物攻击 =怪物攻击 - 角色实际防御 + 10(最低 1 点),防御姿态减免基础伤害;
BOSS 技能:随机触发(初始概率 10%),造成 25-50 点固定伤害,未触发时普通攻击且技能概率递增。
2.3.2 装备加成逻辑
装备槽最多穿戴 3 件装备,宝石类装备(生命 / 攻击 / 防御 / 速度)对对应属性提供 10% 加成,通过apply_equip_bonus方法实时计算实际属性,保证装备穿戴 / 卸下后属性同步更新。
2.3.3 游戏流程逻辑
角色创建 → 主菜单循环 → 选择功能(战斗/商店/休息等)→ 对应模块执行 → 状态更新 → 回到主菜单(循环)
↓(满足条件,自行选择)
BOSS战 → 胜利/失败 → 游戏结束
三、实现过程
3.1 核心模块实现步骤
3.1.1 角色类(Player)实现
1.定义__init__方法初始化角色基础属性,区分战士 / 法师初始属性差异(战士高防御、高 TP,法师高攻击、高速度);
2.实现apply_equip_bonus方法,遍历已穿戴装备,计算属性加成并更新实际属性;
3.实现add_point方法,支持玩家分配属性点到攻击、防御、生命等维度,实时展示加点后状态;
4.实现equip_manage方法,通过交互完成装备穿戴 / 卸下,限制装备槽数量(最多 3 件),保证操作合法性校验。
3.1.2 战斗系统实现
1.怪物生成:make_enemy函数通过布尔值区分精英怪 / 小怪,利用random函数随机生成不同区间的属性;make_boss函数固定 BOSS 属性,增加技能触发概率参数;
2.战斗循环:battle函数通过 while 循环实现回合制战斗,每回合展示角色与怪物状态,提供药水、普攻、防御、技能四种操作选择;
3.伤害计算:针对不同操作(普攻 / 技能 / 防御)设计差异化伤害公式,BOSS 战增加技能随机触发逻辑,保证战斗趣味性;
4.胜负判定:怪物血量≤0 则战斗胜利,角色血量≤0 则战斗失败,触发对应奖励 / 结束逻辑。
3.1.3 辅助系统实现
1.商店系统(shop):提供药水购买、装备购买、抽奖功能,校验金币是否充足,随机发放装备 / 药水奖励;
2.休息系统(rest):恢复角色 25% 全状态,随机触发遇敌事件,无缝衔接战斗模块;
3.奖励系统(reward):根据击败怪物类型(精英 / 小怪)发放不同奖励,精英怪奖励更丰厚,稀有装备掉落概率更高。
3.1.4 主流程实现
game函数作为入口,实现角色创建后进入主菜单循环,解析玩家输入的菜单选项,调度对应模块(战斗、商店、休息等),控制 BOSS 战解锁条件(击败 10 只怪物),实现游戏胜利 / 失败 / 退出的完整闭环。
3.2 代码
import random
import os
def random_between(a, b):
return random.randint(a, b)
def yes_no(msg):
while True:
i = input(f"{msg}(Y/N):").strip().upper()
if i in ("Y", "N"):
return i == "Y"
class Player:
def init(self):
self.name = ""
self.gender = ""
self.job = ""
self.max_hp = 0
self.hp = 0
self.max_def = 0
self.max_atk = 0
self.max_spd = 0
self.max_mp = 100
self.mp = 100
self.max_tp = 100
self.tp = 100
self.point = 10
self.gold = 100
self.potion = 3
self.bag = []
self.equip_slot = []
self.kill_count = 0
def apply_equip_bonus(self):
mul_hp = 1.0
mul_atk = 1.0
mul_def = 1.0
mul_spd = 1.0
for e in self.equip_slot:
if e == "生命宝石":
mul_hp = 1.1
elif e == "攻击宝石":
mul_atk = 1.1
elif e == "防御宝石":
mul_def = 1.1
elif e == "速度宝石":
mul_spd = 1.1
self.real_max_hp = int(self.max_hp * mul_hp)
self.real_atk = int(self.max_atk * mul_atk)
self.real_def = int(self.max_def * mul_def)
self.real_spd = int(self.max_spd * mul_spd)
self.hp = min(self.hp, self.real_max_hp)
def show_status(self):
self.apply_equip_bonus()
print("\n========== 角色状态 ")
print(f"姓名:{self.name} 性别:{self.gender} 职业:{self.job}")
print(f"生命:{self.hp}/{self.real_max_hp}")
print(f"攻击:{self.real_atk} 防御:{self.real_def} 速度:{self.real_spd}")
print(f"MP:{self.mp}/{self.max_mp} TP:{self.tp}/{self.max_tp}")
print(f"金币:{self.gold} 药水:{self.potion} 剩余属性点:{self.point}")
print(f"已击杀怪物:{self.kill_count} 只")
print(f"穿戴装备:{self.equip_slot if self.equip_slot else '无'}")
print("
\n")
def show_bag(self):
print("\n
道具背包 ")
if not self.bag:
print("背包空空如也")
else:
for idx, item in enumerate(self.bag, 1):
print(f"{idx}. {item}")
print("
======\n")
def equip_manage(self):
while True:
self.show_bag()
print("1穿戴装备 2卸下装备 3返回")
opt = input("选择操作:")
if opt == "3":
break
if opt == "1":
if not self.bag:
print("背包暂无装备")
continue
try:
num = int(input("输入背包装备序号:")) - 1
if 0 <= num < len(self.bag) and len(self.equip_slot) < 3:
gear = self.bag.pop(num)
self.equip_slot.append(gear)
print(f"成功穿戴{gear}")
self.apply_equip_bonus()
else:
print("序号错误或装备槽已满")
except ValueError:
print("请输入合法数字")
elif opt == "2":
if not self.equip_slot:
print("当前无穿戴装备")
continue
print("当前穿戴:")
for idx, e in enumerate(self.equip_slot,1):
print(f"{idx}.{e}")
try:
num = int(input("输入卸下序号:")) -1
if 0 <= num < len(self.equip_slot):
gear = self.equip_slot.pop(num)
self.bag.append(gear)
print(f"卸下{gear}放回背包")
self.apply_equip_bonus()
else:
print("序号错误")
except ValueError:
print("请输入合法数字")
def add_point(self):
if self.point <= 0:
return
print(f"\n当前可分配属性点数:{self.point}")
print("1攻击+1 2防御+1 3速度+1")
print("4生命+10 5MP+10 6TP+10")
while self.point > 0:
opt = input("选择加点方向,输入0结束加点:")
if opt == "0":
break
if opt == "1":
self.max_atk += 1
elif opt == "2":
self.max_def += 1
elif opt == "3":
self.max_spd += 1
elif opt == "4":
self.max_hp += 10
elif opt == "5":
self.max_mp += 10
elif opt == "6":
self.max_tp += 10
else:
print("输入无效")
continue
self.point -= 1
print(f"加点成功,剩余点数:{self.point}")
self.show_status()
def create_player():
p = Player()
print("
= 创建角色 =====")
p.name = input("输入姓名:")
p.gender = input("输入性别:")
while True:
job = input("选择职业(1=战士 / 2=法师):")
if job in ("1", "2"):
break
if job == "1":
p.job = "战士"
elif job == "2":
p.job = "法师"
p.max_atk = 10
p.max_def = 10
p.max_spd = 10
if p.job == "战士":
p.max_hp = 50
p.max_def += 10
p.max_tp += 50
p.max_mp -= 50
elif p.job == "法师":
p.max_hp = 20
p.max_atk += 10
p.max_spd += 10
p.hp = p.max_hp
p.mp = p.max_mp
p.tp = p.max_tp
p.add_point()
return p
def make_enemy(is_elite=False):
if is_elite:
return {
"name":"精英怪",
"hp":random_between(70,100),
"def":random_between(30,50),
"atk":random_between(30,50),
"spd":random_between(20,40)
}
return {
"name":"小怪",
"hp":random_between(30,45),
"def":random_between(8,15),
"atk":random_between(12,22),
"spd":random_between(8,18)
}
def make_boss():
return {"name":"最终BOSS","hp":500,"def":35,"atk":30,"spd":30,"skill_rate":10}
def battle(p, enemy):
enemy_max_hp = enemy["hp"]
print(f"\n遭遇 {enemy['name']}!")
boss_skill_rate = enemy.get("skill_rate", 0)
temp_atk = p.max_atk
while True:
p.show_status()
print(f"敌人:{enemy['name']} 血量{enemy['hp']}/{enemy_max_hp} 攻{enemy['atk']} 防{enemy['def']}")
print("1喝药水 2普通攻击 3防御 4技能")
act = input("选择行动:")
defense = False
if act == "1":
if p.potion <= 0:
print("没有药水!")
else:
p.potion -= 1
typ = random.choice(["hp","mp","tp"])
val = int(getattr(p,f"max_{typ}")
0.25)
if typ == "hp":
p.hp = min(p.hp + val, p.real_max_hp)
elif typ == "mp":
p.mp = min(p.mp + val, p.max_mp)
else:
p.tp = min(p.tp + val, p.max_tp)
print(f"恢复{typ} {val}点")
elif act == "2":
dmg = p.real_atk - enemy["def"]
dmg = dmg if dmg >=5 else 5
enemy["hp"] -= dmg
print(f"普攻造成{dmg}伤害")
elif act == "3":
defense = True
print("进入防御姿态")
elif act == "4":
print("1魔法技能 2特殊技能")
sk = input("选择技能:")
if sk == "1":
if p.job == "法师":
if p.mp < 20:
print("MP不足,无法释放")
else:
p.mp -= 20
dmg = p.real_atk - enemy["def"] + 30
final_dmg = dmg if dmg > 0 else 1
enemy["hp"] -= final_dmg
print(f"火球术消耗20MP,造成{final_dmg}伤害")
else:
if p.mp < 20:
print("MP不足,无法释放")
else:
p.mp -= 10
p.max_atk = int(p.max_atk * 1.5)
p.apply_equip_bonus()
print("剑舞消耗10MP,攻击力提升50%")
elif sk == "2":
if p.job == "法师":
enemy["hp"] -= 20
print("魔杖打击造成20固定伤害")
else:
if p.tp < 20:
print("TP不足,无法释放")
else:
p.tp -= 20
dmg = p.real_atk - enemy["def"] + 30
final_dmg = dmg if dmg > 0 else 1
enemy["hp"] -= final_dmg
print(f"聚力斩消耗20TP,造成{final_dmg}伤害")
if enemy["hp"] <= 0:
p.max_atk = temp_atk
p.apply_equip_bonus()
print("击败敌人")
return True
if enemy["name"] == "最终BOSS":
if random.randint(1,100) <= boss_skill_rate:
dmg = random.randint(25,50)
p.hp -= dmg
print(f"BOSS技能攻击,受到{dmg}点伤害")
boss_skill_rate = 10
else:
dmg = enemy["atk"] - p.real_def + 10
dmg = max(dmg, 1)
p.hp -= dmg
print(f"BOSS普通攻击,受到{dmg}点伤害")
boss_skill_rate += 20
else:
if defense:
dmg = enemy["atk"] - p.real_def
dmg = max(dmg, 1)
p.hp -= dmg
print(f"防御减免,受到{dmg}伤害")
else:
dmg = enemy["atk"] - p.real_def + 10
dmg = max(dmg, 1)
p.hp -= dmg
print(f"敌人攻击,受到{dmg}点伤害")
if p.hp <= 0:
print("战斗失败,游戏结束")
return False
p.apply_equip_bonus()
def reward(p, is_elite):
if is_elite:
gold = random_between(50,100)
p.gold += gold
p.potion += 1
p.kill_count += 1
p.point += 3
print(f"获得{gold}金币、1瓶药水、3属性点")
if random.random()<0.1:
eq = random.choice(["生命宝石","攻击宝石","防御宝石","速度宝石"])
p.bag.append(eq)
print(f"掉落装备存入背包:{eq}")
else:
gold = random_between(30,50)
p.gold += gold
p.kill_count += 1
p.point += 1
print(f"获得{gold}金币、1属性点")
if random.random()<0.5:
p.potion += 1
print("额外获得药水")
if random.random()<0.01:
eq = random.choice(["生命宝石","攻击宝石","防御宝石","速度宝石"])
p.bag.append(eq)
print(f"稀有掉落装备存入背包:{eq}")
if p.point>0:
print("\n战斗奖励属性点,立即分配加点")
p.add_point()
def shop(p):
while True:
p.show_status()
print("1买药水40金币 2买装备500金币 3抽奖80金币 4离开")
sel = input("商店选择:")
if sel == "4":
break
if sel == "1":
if p.gold >= 40:
p.gold -= 40
p.potion += 1
print("购买药水成功,金币扣除40")
else:
print("金币不足")
elif sel == "2":
if p.gold >= 500:
p.gold -= 500
eq = random.choice(["生命宝石","攻击宝石","防御宝石","速度宝石"])
p.bag.append(eq)
print(f"扣除500金币,装备存入背包:{eq}")
else:
print("金币不足")
elif sel == "3":
if p.gold >= 80:
p.gold -= 80
if random.random()<0.1:
eq = random.choice(["生命宝石","攻击宝石","防御宝石","速度宝石"])
p.bag.append(eq)
print("扣除80金币,抽奖装备存入背包")
else:
p.potion += 1
print("扣除80金币,抽奖获得药水")
else:
print("金币不足")
def rest(p):
p.show_status()
print("休息恢复25%全部状态")
p.hp = min(p.hp+int(p.real_max_hp
0.25), p.real_max_hp)
p.mp = min(p.mp+int(p.max_mp
0.25), p.max_mp)
p.tp = min(p.tp+int(p.max_tp
0.25), p.max_tp)
if random.random()<0.5:
print("休息遭遇敌人!")
elite = p.kill_count>=4 and random.random()<0.1
if not battle(p, make_enemy(elite)):
return
def game():
print("===== 文字RPG游戏 =====")
player = create_player()
boss_require = 10
while True:
player.show_status()
print("1小怪挑战 2商店 3休息 4BOSS战")
print("5背包查看 6装备调整 8退出")
opt = input("主菜单选择:")
if opt == "8":
break
if opt == "5":
player.show_bag()
if opt == "6":
player.equip_manage()
if opt == "2":
shop(player)
if opt == "3":
rest(player)
if opt == "1":
elite = player.kill_count>=4 and random.random()<0.1
if battle(player, make_enemy(elite)):
reward(player, elite)
else:
break
if opt == "4":
if player.kill_count < boss_require:
lack = boss_require - player.kill_count
print(f"暂未达成挑战BOSS要求,还需击败{lack}只怪物才可挑战!")
continue
if battle(player, make_boss()):
print("成功击败BOSS,游戏胜利完结!")
break
if name == "main":
game()
四、实验结果与分析
4.1 功能测试结果
表格
测试模块 测试用例 测试结果
角色创建 输入姓名、性别,选择战士 / 法师职业 成功创建角色,初始属性符合职业设定
属性加点 分配属性点到攻击 / 生命等维度 属性值正确增加,剩余点数同步减少
装备管理 穿戴 / 卸下背包中的宝石装备 装备槽与背包内容同步变化,实际属性正确加成
小怪战斗 选择普攻 / 技能 / 防御 / 药水,击败小怪 伤害计算正确,战斗胜利后获得对应奖励
精英怪战斗 触发精英怪,完成战斗 精英怪属性更高,奖励更丰厚,装备掉落概率符合设定
商店系统 购买药水、装备,参与抽奖 金币扣除正确,道具 / 装备正确入库
休息系统 休息恢复状态,触发随机遇敌 状态恢复 25%,遇敌后无缝进入战斗流程
BOSS 战 击败 10 只怪物后挑战 BOSS BOSS 技能随机触发,击败后游戏胜利,失败则结束
4.2 数值平衡性分析
属性平衡:战士初始防御高、血量厚,适合抗伤;法师初始攻击高、速度快,适合输出,职业差异化明显且无明显强弱失衡;
战斗平衡:普攻保底伤害 5 点,避免低属性角色无法造成伤害;BOSS 技能概率递增,增加挑战性但不导致无法击败;
奖励平衡:精英怪奖励(3 属性点、高金币)是小怪(1 属性点)的 3 倍,稀有装备掉落概率(10%)合理,保证游戏养成节奏。
4.3 异常处理分析
输入合法性:对装备序号、属性加点选项、菜单选择等输入做了数值校验和范围校验,避免非数字输入、越界输入导致程序崩溃;
资源校验:使用药水、释放技能、购买道具前校验药水数量、MP/TP、金币是否充足,避免负资源值出现;
状态同步:装备穿戴 / 卸下后立即调用apply_equip_bonus更新属性,战斗中临时属性变化(如战士剑舞)在战斗胜利后重置,保证状态一致性。
4.4 可优化点
1.扩展职业系统:增加牧师、刺客等更多职业,丰富技能体系;
2.装备多样性:增加装备等级、耐久度、套装效果,提升养成深度;
3.存档 / 读档功能:通过文件操作实现角色状态保存,支持游戏续玩;
4.图形化界面:结合 Tkinter/Pygame 实现简单图形界面,提升交互体验;
4.5 实验过程截图
【QQ202666-112124】https://www.bilibili.com/video/BV1Sk7S6BEB9?vd_source=875618a7f7a65d5a512a709854b24770
五、总结与体会
5.1 项目总结
本项目成功实现了一款功能完整的文字 RPG 游戏,涵盖角色创建、属性养成、战斗系统、道具管理、商店休息等核心模块,基本满足文字 RPG 的核心游玩需求。
5.2 实践体会
1.面向对象思想的重要性:Player 类的设计将角色属性与行为封装,降低了模块间耦合,便于功能扩展和维护;
2.逻辑分层的必要性:将战斗、商店、休息等功能拆分为独立函数,主流程仅负责调度,提升了代码可读性和可调试性;
3.数值设计的核心地位:RPG 游戏的数值平衡直接影响游玩体验,需通过多次测试调整数值区间,保证趣味性和公平性;
4.异常处理的严谨性:用户输入、资源消耗等场景的异常处理是程序稳定运行的关键,需覆盖所有可能的异常情况。

5.3 实验中遇到的问题
1.使用攻击后,小怪血量不会变动,自己被攻击后,血量也不会变--敌人攻击那一段写反了公式,而且在防御时还写错了变量,导致扣血永远是 0 或 1,看起来像没掉血。
2.购买道具后,金币数量未发生变化--一开始函数定义有误,金币一栏将金币始终定成了一个固定值

5.4 感想
本次实践,对我而言,主要巩固了 Python 编程基础,在编程过程中,我训练了自己的逻辑能力与对函数,字典等的运用,巩固了我一学期的学习,让我发现了自身的不足之处与知识上的遗漏点,更是提升了我的信心。

课程感想
通过这段时间的 Python 课程学习,我收获了很多课本之外的实践知识,也真正体会到了编程的乐趣与魅力。从一开始对代码一窍不通,到现在能够独立编写简单的程序、完成逻辑设计,每一步进步都让我充满成就感。
在学习过程中,我不仅掌握了 Python 的基础语法、变量、循环、判断、函数和类等核心知识,更重要的是学会了用编程思维解决问题。以前面对复杂的逻辑和任务,我只会靠手动完成,现在能够通过代码实现自动化、结构化处理,无论是数据处理、逻辑判断,还是制作小游戏,都能感受到编程的强大与实用。
课程中的实战练习让我印象深刻,尤其是自己动手编写文字 RPG 游戏的过程。先从网上搜寻样本学习,再自行改良探索。从设计角色、背包、装备系统,到调整战斗逻辑、优化游戏平衡,我一步步排查错误、修改代码、完善功能,真正体会到了编程不是一蹴而就,而是不断调试、不断优化的过程。遇到 bug 时的困惑,解决问题后的喜悦,成功运行程序时的满足感,都让我更加坚定了学习编程的信心。
除此之外,python课还让我学到了许多课外知识。Socket,模块,网络爬虫,这些都极大地丰富了我的知识面,尤其是爬虫相关的知识,一方面,让我更深层次地领悟到了编程的强大之处,另一方面,也为我敲响了警钟,督促我在网络使用上更加谨慎,严谨。
当然,我也认识到自己还有很多需要提升的地方,比如代码的简洁性、逻辑的严谨性、复杂功能的设计能力等。Python 作为一门简洁高效的编程语言,应用范围非常广泛,未来我会继续坚持练习,把课堂上学到的知识运用到更多实际场景中。
非常感谢课程的学习机会,它让我从零基础走进了编程的世界,培养了我的逻辑思维和动手能力。这段学习经历不仅提升了我的专业技能,也让我变得更有耐心、更善于思考。我会带着这份收获继续学习,不断探索编程的更多可能。

posted @ 2026-06-06 12:17  yinlian  阅读(14)  评论(0)    收藏  举报