20254311孙小涵实验四Python综合实践

学号 2025-2026-2 《Python程序设计》实验四报告

课程:《Python程序设计》
班级: 2543
姓名: 孙小涵
学号:20254311
实验教师:王志强
实验日期:2026年5月25日
必修/选修: 公选课

1.实验内容:编写小游戏

游戏参考:steam游戏《卡片魔王:只剩个头》
1.编写简化游戏代码
2.实现游戏可正常运行
3.实现窗口可视化运行
4.加载中文提示运行

2. 实验过程及结果

2.1编写简化游戏代码

1.编写类Entity及内部方法,设置玩家及游戏内小怪所需信息,包括:初始位置(x,y),初始血量/最大血量,打击伤害值及颜色。方法判断:如果血量大于0,则对象存活;收到打击伤害血量会减少,但不会小于0.
屏幕截图 2026-05-25 185923

2.编写玩家及小怪子类,实现初始化
玩家子类继承Entity父类,用super().__init__继承并执行父类中定义的初始化逻辑,初始化位置、血量、伤害等
屏幕截图 2026-05-25 191444
小怪子类继承Entity父类,用super().__init__继承并执行父类中定义的初始化逻辑,初始化位置、血量、伤害等
小怪另外需要设定状态和蓄力方向:
(1)初始化:小怪处于空闲未蓄力状态
(2)开始蓄力:状态变为charging,并记录蓄力方向
(3)打断蓄力:蓄力被打断,状态变为空闲,方向清除
(4)结束蓄力:状态变为休息,方向清除,返回造成的伤害值
(5)结束休息:状态回到空闲
屏幕截图 2026-05-25 191618

3.初始化游戏数据
定义游戏运行状态常量
屏幕截图 2026-05-25 193041
重置游戏状态为运行中,玩家放在地图宽度的 1/3 处,高度的中央。初始化敌人列表为空集合,occupied 记录已被占用的格子,起始包含玩家位置。生成 6 个敌人:随机选取未被占用的格子,赋予随机生命值(6-12)和攻击力(3-6),添加到敌人列表。
屏幕截图 2026-05-25 200824

4.玩家回合
玩家攻击一个敌人:扣除敌人生命值,若敌人正在蓄力则打断,若敌人生命值小于等于0,提示敌人被击败
image
玩家移动:如果游戏不在运行状态则无效;计算新坐标,检查边界。如果新位置上有存活的敌人,则攻击该敌人;如果敌人死亡则移除,检查游戏是否胜利/失败。否则移动玩家到新格子。
屏幕截图 2026-05-25 202702

5.敌人回合
判断两个格子是否相邻
屏幕截图 2026-05-25 202843
如果两者相邻,就给定敌人和玩家坐标,判断并返回敌人指向玩家的方向字符串(up/down/left/right)
屏幕截图 2026-05-25 203042
小怪正式攻击:
(1)结束所有休息状态,设定为空闲状态
屏幕截图 2026-05-25 203403
(2)处理蓄力中的敌人:保证操作的敌人对象都是活着的。如果小怪与玩家相邻,则蓄力完成,造成伤害,变为休息状态;如果不相邻,则取消蓄力,回到空闲。若玩家死亡则设置游戏结束状态。
屏幕截图 2026-05-25 203548
(3)处理空闲敌人:保证操作的敌人对象都是活着的。
如果与玩家相邻,则开始蓄力,显示方向,本回合不攻击。
如果不相邻,尝试向玩家移动,计算差值。如果水平距离绝对值大于垂直距离,则优先水平移动(差值正右移,差值负左移);如果垂直距离绝对值大于水平距离,则优先垂直移动;如果水平距离绝对值等于垂直距离,则随机选择水平移动或垂直移动(各 50% 概率),避免固定的移动模式
屏幕截图 2026-05-25 205710
计算新位置,如果新位置在边界内,且不是玩家所在格子,并且没有其他小怪占据,则移动敌人。
屏幕截图 2026-05-25 210059
清除所有死亡敌人,检查胜利(无敌人)或失败(玩家死亡)状态。
屏幕截图 2026-05-25 210154

2.2实现游戏可正常运行

1.设置running,实现游戏循环运行,直到检查到当前事件的类型为 pygame.QUIT,将 running 设为 False,下一次循环条件判断时会退出 while 循环,游戏结束。
屏幕截图 2026-05-25 211613
在胜利/失败界面按 ESC 键即可退出游戏,按其他键则无反应。
屏幕截图 2026-05-25 214823
等待玩家按键:按 R 重置游戏并返回 True(继续运行),按 ESC 或关闭窗口返回 False(退出游戏)。
屏幕截图 2026-05-25 220406

2.玩家和小怪分别行动
上下左右或 WASD 移动玩家,move_player 返回是否发生了移动/攻击。R 键重置,ESC 退出。
屏幕截图 2026-05-25 215343
如果玩家执行了动作且游戏仍在运行,则调用敌人回合,然后再次检查游戏胜负状态。
屏幕截图 2026-05-25 215457

3.退出循环
如果游戏胜利或失败,显示结束画面。如果玩家选择退出,则 running = False 结束主循环。退出 pygame 并关闭程序。
屏幕截图 2026-05-25 215625

2.3实现窗口可视化运行

1.窗口参数
定义每个单元格的像素大小,地图的宽度和高度。定义 RGB 颜色常量:背景色、网格线、玩家颜色、敌人颜色、文字颜色、血条背景/前景、蓄力箭头颜色。
屏幕截图 2026-05-25 220055

2.可视化窗口(大模型辅助)
(1)绘制网格线:纵向和横向的直线
屏幕截图 2026-05-25 220540
(2)绘制一个实体(玩家或敌人):计算矩形区域,填充实体颜色。绘制白色边框。在格子中央显示当前生命值数字
屏幕截图 2026-05-25 220716
(3)在实体格子顶部绘制血条:灰色背景,绿色填充(比例 = 当前生命/最大生命)
屏幕截图 2026-05-25 220804
(4)敌人蓄力画面:如果敌人处于蓄力状态且有方向,则在格子中央绘制对应方向的箭头。
屏幕截图 2026-05-25 220913
(5)玩家生命:顶部显示玩家生命、攻击力和存活敌人数量。
屏幕截图 2026-05-25 221115
(6)显示胜利或失败的结束画面:居中显示标题和提示文字。
屏幕截图 2026-05-25 221616
(7)渲染画面
屏幕截图 2026-05-26 152957

2.4加载中文提示运行

1.尝试加载中文字体
尝试加载中文字体(黑体、微软雅黑等),如果失败则尝试下一个。成功则设置不同大小的字体对象。如果所有中文字体都加载失败,则使用None 默认字体,不支持中文,但箭头字符可以显示。
屏幕截图 2026-05-26 152243

2.设置提示消息
设置初始提示消息,消息计时器(用于显示一段时间后消失)
屏幕截图 2026-05-26 152511
底部显示临时消息(并递减计时器)或常驻操作提示。
屏幕截图 2026-05-26 161400

2.5程序运行结果


上传Gitte
屏幕截图 2026-05-26 155415

3. 实验过程中遇到的问题和解决过程

  • 问题1:最开始设计玩家与敌人属性时分开重复书写,代码冗余
  • 问题1解决方案:大模型修正,运用子类和父类的继承属性简化代码
  • 问题2:不会可视化界面
  • 问题2解决方案:deepseek主导生成,个人调整颜色
  • 问题3:提示停留时间太短
  • 问题3解决方案:增设消息计时器

4.课程总结

4.1课程知识点总结

1.Python 是一门面向对象的语言。
2.四大序列
列表:可变有序,用[]。方法:append()/extend()/insert()添加,remove()/pop()/del删除,sort()/reverse()排序反转,列表推导式[表达式 for 变量 in 范围 if 条件]。
元组:不可变有序,用()。单元素元组需加逗号。访问速度快,可作为字典键。元组推导式生成生成器对象。
字典:可变无序,键值对{key:value},键必须唯一且不可变。创建:dict()、dict(zip())。访问:d[key]或get()。方法:items()/keys()/values(),字典推导式。
集合:可变无序,元素不可重复,用{}或set()。运算:交集&、并集|、差集-、对称差集^。方法:add()/remove()/pop()/clear()。
3.字符串
字符串操作:拼接+、重复*、切片、分割split()、合并join()、检索count()/find()/index()、大小写转换lower()/upper()、去除首尾strip()。
格式化:%占位符(如%s %d %f)及格式控制m.n;format()方法用{}占位。
4.面向对象程序设计
类与对象:类定义class,构造方法__init__(第一个参数self指向实例)。实例属性与类属性。
封装:单下划线_表示protected,双下划线__表示private(名称修饰)。
继承:子类class Child(Parent),自动拥有父类非私有成员,可重写方法,用super()调用父类方法。

4.2课程感想体会

由于我之前学过C语言,习惯了面向过程的编程思维——先定义函数,再按顺序调用,数据和操作是分离的。刚开始接触Python的面向对象时,很不理解为什么要用类把数据和函数“捆”在一起,感觉多此一举。但随着课程深入,我逐渐体会到面向对象的优势。最深刻的就是类与对象的部分,类就像蓝图(C语言里用结构体只能封装数据,却无法封装行为),而对象是具体的实例,代码的内聚性明显提高,维护起来也更直观。在C语言中如果想复用代码,通常需要拷贝函数或者用函数指针模拟,既麻烦又容易出错。而Python中一个class Child(Parent)就能继承父类所有功能,重写方法也很自然。
总的来说,有C语言的基础,学习Python的面向对象语法并没有太大障碍,更重要的收获是对两种编程范式的对比理解。面向过程仍然适用于简单、线性的任务,而面向对象在处理复杂、多变的系统时提供了更合理的组织方式。

4.3课程建议

不是所有学过C语言的人都很会编程啊老师,咱这个课上的属实是太快了点,有点吸收不过来

仓库地址

posted @ 2026-05-26 16:59  小寒0702  阅读(12)  评论(0)    收藏  举报