Fight Aliens 子弹夹清除和限制子弹数量功能
基础版我们用数组list来保存创建的子弹实现,但是有很多问题,我们这里使用pygame里的sprite里提供的一个容器Group来实现
# Group对象相当于一个列表,在列表中可以保存游戏中的Surface对象
# 特点:
# 1.可以对group中的对象做统一的操作
# 2.可以直接通过元素删除自己,而不需要获取group
# group() 中存放的元素必须继承 Sprite
具体实现如下:
在bullet模块中bullet.py文件中调整如下:
1 # -*- coding: utf-8 -*- 2 # 作者: guos 3 # 日期: 2023/3/29 4 import pygame 5 from pygame.sprite import Sprite 6 7 class Bullet(Sprite): 8 """ 9 表示子弹的类 10 """ 11 def __init__(self, screen, gc, ship): 12 # 因为继承Sprite, 而没有调用父类Sprite的init方法,导致其无法初始化父类的属性, 所以需要调用如下方法 13 super().__init__() 14 # fill(color, rect) 15 self.color = gc.bullet_color # 子弹的颜色 16 # Rect(left, top, width, height), left -> x轴; top -> y轴; width -> 宽度; height -> 高度; 17 self.rect = pygame.Rect(0, 0, gc.bullet_width, gc.bullet_height) # 表示子弹矩形位置 和大小 18 # 设置子弹的位置,子弹的x和y和飞船保持一致 19 self.rect.centerx = ship.rect.centerx 20 self.rect.centery = ship.rect.centery 21 22 23 self.screen = screen 24 self.gc = gc 25 26 def draw_bullet(self): 27 """ 28 在屏幕中绘制子弹 29 :return: 30 """ 31 self.screen.fill(self.color, self.rect) 32 33 def update(self): 34 """ 35 更新子弹的位置,实现飞出去的效果 36 :return: 37 """ 38 self.rect.y -= self.gc.bullet_speed 39 # 将飞出屏幕的子弹销毁 40 if self.rect.bottom < 0: 41 # 销毁子弹 --> 从弹夹中删除 42 # list.remove(item), 但是列表管理比较麻烦不合适 43 self.kill() 44 # 重绘一下子弹 45 self.draw_bullet()
main.py模块中修改如下:
# -*- coding: utf-8 -*- # 作者: guos # 日期: 2023/3/29 # 游戏的主文件,使用该文件来启动游戏 import pygame from pygame.sprite import Group import sys from game_config import GameConfig from ship import Ship from bullet import Bullet # 创建配置对象 gc = GameConfig() # 初始化 pygame.init() # 设置窗口大小 screen = pygame.display.set_mode(gc.size) # 设置窗口的标题 pygame.display.set_caption(gc.title) # 创建一个飞船实例对象 ship = Ship(screen, gc) # 弹夹 -- 存放子弹的列表 # bullets = [] bullets = Group() # 创建主循环 while True: # 处理事件 for event in pygame.event.get(): # 处理退出的事件 if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.KEYDOWN: # 键盘按下 if event.key == pygame.K_LEFT: # 向左移动,设置飞船的移动方向,而不是控制飞船移动 -1 # 这里把这个方向 放入到 配置对象里 gc.ship_dir = -1 elif event.key == pygame.K_RIGHT: # 向右移动 1 gc.ship_dir = 1 elif event.key == pygame.K_SPACE: # 限制子弹数量 if len(bullets) < gc.bullet_count: # 点击空格键开跑 创建子弹实例对象 # 当我们按下空格键后创建,并append到弹夹中 # bullets.append(Bullet(screen, gc, ship)) bullets.add(Bullet(screen, gc, ship)) elif event.type == pygame.KEYUP: # 何时将 ship_dir 设置为0 # 当键盘松开,如果此时为向左移动或者向右移动时 if gc.ship_dir == 1 and event.key == pygame.K_RIGHT or gc.ship_dir == -1 and event.key == pygame.K_LEFT: gc.ship_dir = 0 # 设置窗口背景颜色, rgb值 screen.fill(gc.bg_color) # 更新飞船的位置 必须在显示之前 ship.update() # # 遍历弹夹实现子弹无限发射,而不是按一下发一个 # for bl in bullets: # # 更新子弹的位置 # bl.update() # # 子弹显示 子弹在飞船后面展示会显示在飞船上面,如果想在飞船下面,先展示子弹 # bl.draw_bullet() # 只更新类位置,但无法调用 bullets里每个元素的draw_bullet, 所以需要自己调用的都写到update里来实现 bullets.update() # 查看子弹数量是否有变化 # print(len(bullets)) # 飞船显示 ship.blit_ship() # 对窗口进行重绘 pygame.display.flip()
game_config.py文件中的配置调整如下:
# -*- coding: utf-8 -*- # 作者: guos # 日期: 2023/3/29 # 该模块[即一个py文件就是一个模块,命名小写开头]用来存储游戏的配置信息 class GameConfig: # 类名:大驼峰 def __init__(self): # 直接将配置信息,存储到GameConfig实例对象中 self.width = 800 # 宽度 self.height = 600 # 高度 self.title = 'Fight Aliens' # 外星人入侵 游戏标题 self.bg_color = (230, 230, 230) # 窗口背景颜色 self.ship_dir = 0 # 飞船移动的方向 -1 向左 1 向右 self.ship_speed = 1 # 飞船移动的速度 # 可以根据充值来提升武器的配置参数 self.bullet_color = (0, 0, 0) # 子弹的颜色 self.bullet_width = 3 # 子弹的宽度 self.bullet_height = 15 # 子弹的高度 self.bullet_speed = 1 # 子弹的速度 self.bullet_count = 3 # 限制子弹的数量【即满屏最多有三个】 @property def size(self): # @property 使 size变为属性,可以直接 对象.size 来获取值 # 这里使用来属性方法,返回元组 来动态计算窗口的大小 return self.width, self.height