python

环境

pillow

类的确定

2.明白需求(基于面向对象的分析):
    1、有哪些类: 2、不同的类所具备的一些功能:
        1.主逻辑类
            开始游戏
            结束游戏
        2.坦克类(1.我方坦克  2.敌方坦克)
            移动
            射击
            展示坦克
        3.子弹类
            移动
            展示子弹
        4.爆炸效果类
            展示爆炸效果
        5.墙壁类
            属性: 是否可以通过
        6.音效类
            播放音乐
3.坦克大战项目框架的搭建
    涉及到的类,用代码简单的实现

官方文档

https://www.pygame.org/docs/

ishine

shinejjy/Battle-City ()

按键操作说明.txt · youlinghei/python版坦克大战 - 码云 - 开源中国 (gitee.com)


报错:

:241: RuntimeWarning: Your system is avx2 capable but pygame was not built with support for it. The performance of some of your blits could be adversely affected. Consider enabling compile time detection with environment variables like PYGAME_DETECT_AVX2=1 if you are compiling without cross compilation.

您收到的警告信息表明您的系统支持 AVX2 指令集,但是您安装的 pygame 版本并没有针对 AVX2 进行优化。AVX2(Advanced Vector Extensions 2)是一种提高性能的指令集,特别是在进行大量图像处理操作时。

要解决这个问题,您可以尝试以下几个步骤:

  1. 确保您的环境变量中设置了 PYGAME_DETECT_AVX2=1。这将允许 pygame 在编译时检测到 AVX2 并启用相应的优化。
  2. 如果您是从源代码编译 pygame,确保在编译前设置了上述环境变量。
  3. 如果您是通过 pip 安装的 pygame,您可能需要查找一个已经为 AVX2 优化的 pygame 版本或者自己从源代码编译。

根据我的搜索结果,pygame 的 GitHub 发布页面提供了多个预编译的 pygame 轮子(wheel),您可以尝试下载一个适合您系统的版本1。此外,如果您在编译过程中遇到任何问题,您可以参考 pygame 的 GitHub 问题跟踪器,那里有关于类似问题的讨论和可能的解决方案2

请注意,如果您不熟悉编译过程或环境变量的设置,您可能需要进一步的指导或寻求社区的帮助。在进行任何更改之前,请确保备份您的工作,以防万一出现问题。如果您需要更详细的指导,请告诉我,我会尽力提供帮助。

进度记录

12.12

  1. 大体确定框架,明确每个类
    12.13
  2. 初始化窗口 pygame.display()
  3. 创建事件,包括退出、以及基本移动和发射子弹的键 pygame.event

12.14

显示剩余敌方坦克的辆数 font 字体模块(加载和渲染字体) Font模块

  1. 初始化字体模块
  2. 找到字体模块(从系统,从字体文件中找到) ps: 需要查询字体是否兼容中文模式, 比如kaiti就支持
  3. 使用字体模块绘制(在s u r face上绘制)


可以通过pygame.font.get_fonts 来获取所有可用字体

12.14

导入坦克图片

12.15

实现按键 坦克的调头和移动

新增:

  1. 坦克类中速度属性:用来控制坦克移动的快慢
  2. 对Start Game中 的getEvent处理 :
  1. 改变坦克方向
  2. 根据速度 修改坦克位置

12.16:

新增边界判断

边界优化:

当坦克所在的位置超出屏幕大小以后,就撞墙

up 的 代码是

if self.direction == "U":
    if  > 0:
          -= self.speed

但是当 坦克位于top =3, speed = 5 这样 操纵以后还是会出现 top = -2的情况

if self.direction == "U":
     -= self.speed
    if  < 0:
         = 0

Rect 类的四个参数: top,left,width,height

12.17

按下方向键坦克持续移动

1.  按下方向按键移动,抬起方向键停止(设置开关)

新增:

敌方坦克的创建

  1. 敌方坦克通常为多个,可以继承Tank类的方法

12.18

实现敌方坦克的随机移动(在一个方向移动一定距离的时候,随机更改移动方向)

  1. 方向随机
  2. 前进的、

思路:

通过新增一个敌方坦克的步长属性,当随机产生步长时, 一旦步长走完就随机产生一个方向,并再次随机产生步长

修改文字显示部分: 剩余坦克的数量通过 len(列表)


class EnemyTank(Tank):
    def __init__(self, left, top, speed):

        # 需要新增速度属性
        self.speed = speed
        # 新增敌方坦克随机移动步长
        self.step = random.randint(5, 25)
     def randDirection(self):
        num = random.randint(1, 4)
        tmpdirection = None
        if num == 1:
            tmpdirection = "U"
        elif num == 2:
            tmpdirection = "D"
        elif num == 3:
            tmpdirection = "L"
        elif num == 4:
            tmpdirection = "R"
        return tmpdirection

    def displayTank(self):
        super().displayTank()  # 调用父类

    def randMove(self):
        if self.step <= 0:
            self.direction = self.randDirection()  # 随机更换方向
            self.step = random.randint(1, 26)
        else:
            self.move()  # 当前方向继续前进
            self.step -= 1

bullet的创建


子弹的发射,完善子弹的发射


子弹打中墙壁的优化:

当子弹打中墙壁,直接消失

敌方坦克的子弹发射:

碰撞:

不需要重写,可以使用sprite,直接调用

对于类的调整

bullet

tank 二者继承中间类baseitem() ->继承sprite

新增爆炸效果:

  1. 我方被击中的爆炸,游戏结束
  2. 敌方被击中的爆炸

我方坦克的无限重生

实现墙壁

保证子弹不穿过墙壁

实现坦克不穿墙

待办

需要设置, 不穿墙

设置子弹射程的优化(子弹不应该发出以后就一直沿窗口移动)

设置碰撞的处理

idea

  1. 新增 坦克皮肤的选择
  2. 关于碰撞的优化: 最好不是一击就倒,尽量加个血条

报错总结


直接使用 MainGame.window.blit() 与 MainGame().window.blit() 的区别


因为 这一版本是将window定义为类变量,所以可以直接访问,不需要实例化,而mine window定义为实例变量,所以必须实例化以后才能使用属性,同时,直接使用匿名实例化


报错原因: 由于 window 是实例变量,所以使用MainGame().window.blit() 相当于是在新建的一个MainGame类上 的window添加,此时唯一的解决办法是,在MainGame的内部直接调用window.blit()



报错原因:

def createEnemyTank(self):
    top = 100
    speed = random.randint(3,6)
    for i in range(self.EnemyTank_count):
        # 每次都随机生成一个left值,因为需要保证每次生成的两个坦克不会有重合部分
        left = random.randint(1,7)
        tmp_Tank = EnemyTank(left*100,top, speed)
        print(left*100)
        self.EnemyTank_list.append(tmp_Tank)

因为随机生成的位置可能有重合

解决方法:

# 创建敌方坦克
def createEnemyTank(self):
    top = 100
    speed = random.randint(3,6)
    left_values = random.sample(range(1, 8), self.EnemyTank_count)
    for i in range(self.EnemyTank_count):
        # 每次都随机生成一个left值,因为需要保证每次生成的两个坦克不会有重合部分
        left = left_values[i]
        tmp_Tank = EnemyTank(left*100,top, speed)
        print(left*100)
        self.EnemyTank_list.append(tmp_Tank)


可以看到,由于eBullet是通过eTank.shot() 而重写的shot中,是只有当1/100可能才有子弹,剩余返回空,所以,对于空子弹,不要添加到list中


不知道为啥一直报错

双方坦克的碰撞

""

1.敌我双方坦克碰撞处理
 1.1我方坦克主动碰撞敌方坦克	我方先停
 1.2敌方坦克主动碰撞我方坦克

笔记

pygame.rect()

Rect类: left,top 可以用来当作坐标


保证按下方向键坦克一直移动



对于第一张图,第一遍调用的时候比如右键,此时就有了向右的方向,终端会输出向右,然后调用move()函数移动,然后第二次循环,由于没有事件发生, getEvent()此时没有任何效果,但是 move()仍然会被调用

这样就达到了按下一个键 坦克可以一直移动

对于第二张图,因为事件里面才调用 一个move,所以只有按下一个键松开,再按下一个键,才会发生两次移动(就没有连续的效果)

所以针对第一种,就算当时松开按键,坦克仍然会死循环,这就需要设置一个开关键

开关键默认是stop = True

只有当按键按了方向才会改动


用到的函数

获取当前图片的位置 self.rect = self.image.get_rect() # 有长宽高

游戏设计

总体设计表


内容


详细内容

分工

12/19日之前






爆炸效果


新增爆炸效果,当一个敌方坦克生命降为0,增添爆炸效果



暂停键


游戏暂停

zyf


关卡-3


新增射击对方大本营(敌方home 加强防守,火柴人)

wxc


关卡-4


新增拾取道具轰炸对方home

wxc


关卡-5


加强防守,设置火柴人,保证火柴人有一定扇形区域的视野,当视野范围内,坦克不可以前进,前进会导致血条量减少

wxc







菜单栏内容的提醒


进入的关卡提示(1.菜单栏游戏按键说明,关卡介绍说明)

zyf

优化处理:

闯关模式


每个关卡的墙壁数量由低到高



双人对抗模式


坦克分为,敌方坦克,player1,player2,并且两个玩家是fight模式,一旦其中一个Player的生命值<0 ,则对方胜利



双人合作模式


两位玩家共同闯关,闯关成功的flag就是 消灭敌方所有坦克



双人对抗之-反恐精英模式


玩家可以选择1. 自动分组 2. 玩家自由选择

wxc


用户账号的保存



wxc


风格(画面风格)


圣诞画风

zyf




UI设计

zyf

游戏模式的详细介绍

反恐精英模式

mission_time

  1. 故事背景介绍: 分为两个阵营,反恐坦克阵营需要炸毁 T阵营的两个点,A/B点(这两个点为任务爆破点,一旦成功炸,则任务完成),或者全歼灭恐怖分子T方坦克 也认为 游戏胜利(mission success)
    mission success: mission_time内,炸毁T的A/B,或者
    mission fail: mission_time 内 CT没有获得胜利; CT生命值 <= 0

**反恐精英(Counter Terrorists/CT)**阵营

可以通过炸掉敌方

**恐怖分子(Terrorists/T)**阵营两队:

游戏音效的收集

mission success,mission fail,进入A/B点附近



代码


wxc










新增功能:

第三关:

目标:实现 歼灭敌方坦克或者

markdown

版本说明

  1. 功能新增,生命值提醒