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

1.实验背景

由于本人对FPS类的射击游戏较为感兴趣,所以在这次实验中我打算从坦克大战这一经典的游戏着手,利用AI的辅助,进行创新性的优化和改变,主要的点就是加入双人模式的加入以及可玩性的提高。
(代码已托管至Gitee仓库)(网址 https://gitee.com/Drunkdy/drunk/blob/master/tank.py

2.实验内容

本实验实现了一个经典的坦克大战游戏,是完全基于 Python 和 Pygame 开发的,不需要依赖其他软件。游戏主要包含以下 7 个核心功能:

2.1 单人游戏模式

支持完整的单人游戏流程,玩家可以操控绿色坦克,在随机生成的地图中击败敌方坦克,进而完成 3 个递进难度的关卡。游戏包含开始界面、游戏界面、暂停界面、游戏结束界面和胜利界面,流程完整,体验感拉满。

2.2 坦克移动与射击系统

玩家可以使用 WASD 键或方向键控制坦克上下左右移动
坦克移动时会自动转向,炮管始终朝向移动方向
按下空格键发射子弹,限制玩家最多同时连发3发子弹,保持游戏均衡性
坦克移动带有边界检测,不会超出游戏屏幕范围
坦克之间不能互相穿过,增加游戏真实感

2.3 完整障碍物系统

设计了 4 种不同类型的障碍物,每种有不同的规则:

  • 砖墙:棕色,可被子弹摧毁,阻挡坦克和子弹通行
  • 钢墙:灰色,不可被子弹摧毁,阻挡坦克和子弹通行
  • 水域:蓝色,不可被子弹摧毁,阻挡坦克通行,子弹可穿过
  • 草地:绿色,半透明,不阻挡任何通行,仅作为视觉装饰

2.4 敌方 AI 系统

敌方坦克为红色,从屏幕顶部三个固定位置随机生成
敌方坦克会随机改变移动方向,但移动速度比玩家慢
敌方坦克会随机发射子弹攻击玩家
敌方坦克同样遵守碰撞规则,不能穿过固体墙和其他坦克

2.5 关卡递进系统

设计了 3 个递进难度的关卡:

  • 第 1 关:简单难度,敌人数量少,移动速度慢,地图障碍物少
  • 第 2 关:中等难度,敌人数量增加,移动速度加快,地图障碍物增多,电脑AI更加聪明
  • 第 3 关:困难难度,敌人数量最多,移动速度最快,地图障碍物最复杂,电脑AI十分聪明

每关击杀所有敌人后自动进入下一关,关卡越高难度越大,十分地挑战玩家的水平

2.6 爆炸特效与视觉反馈

子弹击中墙壁或坦克时会产生橙黄两色渐变的爆炸动画
玩家坦克被击中后会有短暂的无敌时间,无敌期间坦克闪烁透明
所有界面均使用中文显示,操作提示清晰易懂
界面以及坦克均有所设计,带有高光的色彩(本人有点有点颜控哈)
且坦克在移动的过程中尾迹,十分逼真

2.7 生命值与得分系统

玩家初始有 3 条生命值,被敌方子弹击中一次减少 1 条
击毁一辆敌方坦克可以获得 100 分
屏幕左上角实时显示玩家剩余生命值和当前得分,同时为了增加趣味性,增设基地,若玩家的子弹击中基地,则直接淘汰
屏幕右上角显示当前关卡和剩余敌人数量

三、实现关键功能的代码的讲解

3.1 面向对象类设计

本游戏采用面向对象的设计思想,将游戏中的各个元素抽象为类,实现了代码的高内聚低耦合的特性。

3.1.1 坦克基类Tank

作为所有坦克的父类,封装了坦克的通用属性和方法,包括颜色、速度、生命值、方向、射击冷却等。通用使用move()和shoot()方法,玩家坦克和敌方坦克可以继承并扩展。

class Tank(pygame.sprite.Sprite):
    def __init__(self, x, y, color, num):
        super().__init__()
        self.rect = pygame.Rect(0, 0, 45, 45)
        self.rect.center = (x, y)

        self.base_color = color
        self.color = color
        self.num = num
        self.dir = "up"
        self.speed = 4
        self.base_speed = 4
        self.hp = 5
        self.max_hp = 5
        self.shoot_delay = 300
        self.last_shoot = 0
        self.last_track = 0
        self.invincible = False
        self.inv_time = 0
        self.power_bullet = False
        self.power_time = 0
        self.speed_time = 0

        self.create_surf()

    def create_surf(self):
        """重新绘制坦克(增加高光细节)"""
        self.image = pygame.Surface((45, 45), pygame.SRCALPHA)
        # 计算高光颜色(修复生成器错误)
        highlight1 = (min(self.color[0] + 30, 255), min(self.color[1] + 30, 255), min(self.color[2] + 30, 255))
        highlight2 = (min(self.color[0] + 40, 255), min(self.color[1] + 40, 255), min(self.color[2] + 40, 255))
        highlight3 = (min(self.color[0] + 50, 255), min(self.color[1] + 50, 255), min(self.color[2] + 50, 255))

        # 履带(增加高光)
        pygame.draw.rect(self.image, self.color, (2, 2, 10, 41))
        pygame.draw.rect(self.image, self.color, (33, 2, 10, 41))
        pygame.draw.rect(self.image, highlight1, (4, 4, 6, 37))
        pygame.draw.rect(self.image, highlight1, (35, 4, 6, 37))
        # 主体(增加高光)
        pygame.draw.rect(self.image, self.color, (12, 12, 21, 21))
        pygame.draw.rect(self.image, highlight2, (14, 14, 17, 17))
        # 炮塔(增加高光)
        pygame.draw.circle(self.image, self.color, (22, 22), 10)
        pygame.draw.circle(self.image, highlight3, (22, 22), 7)
        # 炮管
        if self.dir == "up": pygame.draw.rect(self.image, self.color, (20, 0, 5, 22))
        if self.dir == "down": pygame.draw.rect(self.image, self.color, (20, 23, 5, 22))
        if self.dir == "left": pygame.draw.rect(self.image, self.color, (0, 20, 22, 5))
        if self.dir == "right": pygame.draw.rect(self.image, self.color, (23, 20, 22, 5))

3.1.2 玩家坦克类PlayerTank

继承自Tank类,扩展了玩家特有的属性和方法,包括生命值、得分、无敌状态等。实现了update()方法处理无敌状态的闪烁效果,以及完善了take_damage()方法处理玩家受伤逻辑。

3.1.3 敌方坦克类EnemyTank

继承自Tank类,写出了了敌方 AI 逻辑。敌方坦克会随机改变移动方向,随机发射子弹,且自动避开固体墙和其他坦克,保证具有挑战性

3.2 碰撞检测系统

碰撞检测是游戏实现功能的关键之一,本游戏采用了分层碰撞检测的设计,将固体墙单独分组,提高了检测效率。

# 固体墙壁碰撞检测
if pygame.sprite.spritecollideany(self, solid_walls):
    self.rect.x, self.rect.y = original_x, original_y

# 玩家子弹击中敌方坦克
hits = pygame.sprite.groupcollide(
    self.enemies,
    self.player_bullets,
    True,  # 击毁敌方坦克
    True,  # 销毁子弹
    pygame.sprite.collide_rect  # 使用精确矩形碰撞检测
)

3.3 中文显示解决方案

针对 Pygame 在 Windows 系统上中文显示乱码的常见问题,设计了三级兼容方案,确保游戏能够正常显示中文:

try:
    # 优先使用系统黑体(Windows默认中文字体)
    font_small = pygame.font.SysFont("SimHei", 28)
    font_medium = pygame.font.SysFont("SimHei", 36)
    font_large = pygame.font.SysFont("SimHei", 72)
except:
    # 备用方案:使用微软雅黑
    try:
        font_small = pygame.font.SysFont("Microsoft YaHei", 28)
        font_medium = pygame.font.SysFont("Microsoft YaHei", 36)
        font_large = pygame.font.SysFont("Microsoft YaHei", 72)
    except:
        # 终极备用:使用默认字体
        font_small = pygame.font.Font(None, 32)
        font_medium = pygame.font.Font(None, 48)
        font_large = pygame.font.Font(None, 72)

3.4 游戏主循环逻辑

游戏主循环采用 "事件处理 - 逻辑更新 - 画面绘制" 的经典架构,每一环节都会依次执行这三个步骤,确保游戏运行流畅。

def run(self):
    while True:
        self.handle_events()  # 处理键盘、鼠标事件
        self.update()         # 更新所有游戏元素状态
        self.draw()           # 绘制游戏画面
        clock.tick(FPS)       # 控制游戏帧率为60FPS

四、程序运行步骤与效果

4.1 运行步骤

安装 Pygame 库(已提前安装)
将代码保存为坦克大战 大作业.py文件
点击运行

4.2 运行效果

开始界面:显示黄色 "坦克大战" 标题,下方有操作提示指引玩家选择单人模式或双人模式
image
(特意加入有关颜色的代码,使整体的风格更加炫酷,同时也兼顾了界面的简洁性)

游戏界面:黑色背景,玩家绿色坦克位于屏幕底部中央,敌方红色坦克从顶部生成。左上角显示生命值和得分,右上角则显示关卡和剩余敌人数量
操作反馈:坦克移动流畅,炮管跟随方向转动,子弹飞行速度适中,击中目标后产生爆炸动画,十分炫酷
暂停界面:按 P 键暂停游戏,屏幕中央显示 "游戏暂停" 字样,再次按 P 键继续
游戏结束界面:玩家生命值耗尽时显示,展示最终得分,按回车键重新开始
胜利界面:通关所有 3 个关卡后显示,恭喜玩家通关,按回车键可以再玩一次

单人模式下运行截图:
image

双人模式下运行截图:
image
(蓝色坦克为玩家一的坦克,绿色坦克为玩家二的坦克)

4.3 所录制的视频(包括在华为云服务器上运行的视频)

https://www.bilibili.com/video/BV1RHJc61E6s/?spm_id_from=333.1387.upload.video_card.click&vd_source=142a9f6668fb9c3837c0bb8869d35068

五、在华为云服务器上部署与运行

步骤为创建云主机、在终端更新、安装Ubuntu 图形桌面以及pygame插件、将自己的源代码文件保存至主机中,之后通过VNC登录至图形化的桌面,打开终端,运行游戏文件
以下为相关截图
屏幕截图 2026-06-14 004653
(pygame安装成功)
屏幕截图 2026-06-14 001432
(图形化界面安装成功)

六、遇到的问题与解决方案

中文显示乱码问题
问题:Pygame 默认字体不支持中文,导致所有中文文字显示为方框
解决方案:设计三级中文显示兼容方案,然后再优先使用系统自带的中文字体,确保在所有 Windows 系统上都能正常显示

碰撞检测不准确问题
问题:初期子弹经常穿过敌方坦克,无法正确击中
解决方案:增大子弹的碰撞盒大小,再使用 Pygame 内置的collide_rect精确矩形碰撞检测,且同时调整子弹发射位置,这样能够确保子弹从炮管前端发射

坦克互穿问题
问题:初期玩家坦克可以穿过敌方坦克,影响游戏体验
解决方案:在坦克移动时增加与其他坦克的碰撞检测,如果发生碰撞就退回到原先的位置

敌方坦克出生在墙里问题
问题:随机生成敌方坦克时,有时会出生在固体墙里,导致坦克卡住不动
解决方案:在生成敌方坦克前,先用if语句检查出生点是否有固体墙,如果有则重新选择出生点

七、python课程总结:

作为一门全院公选课,课程主要讲解了有关python语言的基础语法知识,比如说数字、字符串、运算符、正则表达式的写法,python作为一门高级语言的特点,比如说代码具有简洁性、代码简单易懂以及python语言与其他编程语言相比较下的特点,例如与C语言相比,python具有简单、易上手、效率高的特点。同时,课程还包括了许多的实验,比如说有关剪刀石头布简单游戏的编写、简单计算器的实现以及socket相关的加密通话的实验,这些实验十分地具有代表性,难度由浅至深,循序渐进,很好地提升了我们的编程水平。以下为本人整理的知识点。

Python 入门知识点

1、运行环境与基础规范

Python 版本区分,主流使用 Python 3
解释器运行、脚本文件运行、常用开发工具
代码注释分类与使用规则
缩进规则,Python 依靠缩进划分代码块
基础书写规范,语句结尾无需特殊符号

2、变量与基础数据类型

变量的概念、作用与定义规则
变量命名规范、合法字符、禁用规则与关键字
六大基础数据类型:整数、浮点数、字符串、布尔值、列表、元组
不同数据类型之间的相互转换

3、运算符

算术运算符:常规运算、取余、整除、幂运算
赋值运算符:基础赋值、复合赋值
比较运算符:用于条件判断,结果为布尔类型
逻辑运算符:与、或、非,多条件组合判断

4、字符串

字符串定义形式与基本特性
索引与切片的使用逻辑
字符串拼接、内容截取、格式输出
常用内置方法:长度获取、空格处理、内容分割等

5、输入与输出

控制台输出功能作用
控制台输入功能特性,输入内容默认数据类型

6、流程控制

条件判断

单分支、多分支条件判断结构
条件判断嵌套使用逻辑

循环结构

while 循环:条件循环执行逻辑
for 循环:遍历序列类数据
区间序列 range 的作用
循环控制关键字:跳出循环、跳过单次循环

7、序列与容器类型

列表

列表特性:有序、元素可修改
元素增加、删除、修改、查询操作
列表排序、元素查找等常用功能

元组

元组特性:有序、元素不可修改
适用场景与基础使用逻辑

字典

字典结构:键值对形式,键具有唯一性
字典增删改查操作,键、值、键值对遍历

集合

集合特性:无序、自动去重
集合运算:交集、并集等,主要用途

8、函数

函数概念、作用与定义方式
函数分类:无参函数、有参函数、带返回值函数
形参与实参区别
变量作用域:局部变量、全局变量

9、文件操作

文件打开、关闭基本流程
三种基础打开模式:读取、覆盖写入、追加写入
文件读取、内容写入操作
安全文件操作写法与优势

10、正则表达式

正则表达式概念与应用场景
正则基础元字符、限定符、边界符的含义
字符组、分组、转义字符的使用规则
匹配、查找、替换、分割等常用正则操作
Python 正则模块的基本使用逻辑

八.课程感想体会:

因为本人对算法比较感兴趣并且在寒假自学了些c++语言和一点基本算法,所以想在这学期中再拓展一下,就选了python的公选课(也是比较幸运,居然抢到了)。我觉得老师上课的氛围非常的轻松活泼,讲课的内容也时分详实,基本涵盖了Python语言的入门语法,让我一个Python小白在一学期的课程学习之后能够掌握基础的语法和应用并能在大模型的辅助之下完成一款游戏的改良的创新,当看到成果的那一刻也是非常的激动。总的来说,老师讲课幽默风趣,通过抽人回答问题的方式来引导我们巩固所学知识点,在课后通过多次实验和作业来帮助我们理解代码的使用,同时也引导我们参与英语打卡,让我们全面发展,哈哈,总之非常喜欢老师的课。(手势签到真是让人非常难忘哈)

课程改进建议:
1.个人感觉老师讲课的节奏有些偏快,像对于我这种没怎么接触过python的人来说跟上老师的思路有些困难。
2.我觉得老师可以多布置一些需要同学们合作的作业,这样子能促进同学们的相互交流,进而提升编程水平

参考资料

一、参考书籍

《Python 编程:从入门到实践》
《Python 游戏编程入门(Pygame)》
《Pygame 游戏开发实战》
《Python 核心编程》

二、官方文档网站

Pygame 官方文档:https://www.pygame.org/docs/
Python 官方文档:https://docs.python.org/3/

posted @ 2026-06-14 11:26  Drunkdy  阅读(1)  评论(0)    收藏  举报