一、添加子弹设置
首先在settings中存储子弹的基本设置:
def __init__(self):
# 子弹设置
self.bullet_speed_factor = 1
self.bullet_width = 3
self.bullet_height = 15
self.bullet_color = 60,60,60
其次,创建Bullet类,并用 pygame.Rect(x,y,width,height)方法创建一个个小矩形来表示子弹的产生。
Bullet类继承了便于做动画效果的Sprite类,他是pygame本身自带的一个精灵,通过使用精灵,可将游戏中相关的元素编组,进而同时操作编组中的所有元素。但是这个类的功能比较少,因此我们新建一个类对其继承,在其基础上进一步丰富,以方便我们的使用。
import pygame
from pygame.sprite import Sprite
class Bullet(Sprite):
def __init__(self,ai_settings,screen,ship):
# 在飞船所处位置创建一个子弹对象
super().__init__()
self.screen = screen
# 在(0,0)处始创一个表示子弹的矩形,再设置正确位置
self.rect = pygame.Rect(0,0,ai_settings.bullet_width,ai_settings.bullet_height)
self.rect.centerx = ship.rect.centerx
self.rect.top = ship.rect.top
# 存储用小数表示的子弹位置,以便微调
self.y = float(self.rect.y)
self.color = ai_settings.bullet_color
self.speed_factor = ai_settings.bullet_speed_factor
def update(self):
# 向上移动子弹
# 更新表示子弹位置的小数值
self.y -= self.speed_factor
# 更新表示子弹的rect的位置
self.rect.y = self.y
def draw_bullet(self):
# 在屏幕上绘制子弹
pygame.draw.rect(self.screen,self.color,self.rect)
二、开火
在主函数中创建一个编组,用于存储管理所有有效的子弹,并在game_functions.py中的check_keydown_events()方法中创建映射,在玩家按空格键时发射一颗子弹。
alien_invasion.py
--snip--
from pygame.sprite import Group
def run_game():
--snip--
# 创建一搜飞船
ship = Ship(ai_settings,screen)
# 创建存储子弹的编组
bullets = Group()
# 游戏的主循环
while True:
gf.check_events(ai_settings,screen,ship,bullets)
ship.update()
bullets.update()
gf.update_screen(ai_settings,screen,ship,bullets)
run_game()
game_functions.py
--snip--
from bullet import Bullet
def check_keydown_events(event,ai_settings,screen,ship,bullets):
--snip--
elif event.key == pygame.K_SPACE:
# 创建一颗子弹,并将其加入到编组中
new_bullet = Bullet(ai_settings,screen,ship)
bullets.add(new_bullet)
--snip--
def check_events(ai_settings,screen,ship,bullets):
# 响应按键和鼠标事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
check_keydown_events(event,ai_settings,screen,ship,bullets)
elif event.type == pygame.KEYUP:
check_keyup_events(event,ship)
def update_screen(ai_settings,screen,ship,bullets):
--snip--
# 在飞船和外星人后面重绘所有子弹
for bullet in bullets.sprites():
bullet.draw_bullet()
ship.blitme()
# 让最近绘制的屏幕可见
pygame.display.flip()
三、删除、限制子弹
虽然目前子弹抵达屏幕顶端后会消失,但这只是因为Pygame无法再屏幕外绘制它们,这些子弹依然存在,只是y坐标为负数且越来越小,并且会继续消耗内存和处理能力。因此需要设置筛选条件,对无意义的子弹进行删除。
有时候,适当地增加限制条件提高游戏难度反而能够增加其趣味性,因而我们可以考虑对同一时刻出现在屏幕上的子弹数量进行限制,以鼓励玩家有目标地射击。因而,可以先在settings中存储允许的最大子弹数,然后在game_functions中新建子弹前,先检查未消失的子弹是否已到上限。
对现有代码进行相应修改和重构后如下:
settings.py
class Settings():
# 存储游戏所有设置的类
def __init__(self):
# 初始化游戏的设置
# 屏幕设置
self.screen_width = 1200
self.screen_height = 600
self.bg_color = (230,230,230) # 设置背景色,由RGB指定,(230,230,230)为浅灰色
self.ship_speed_factor = 1.5
# 子弹设置
self.bullet_speed_factor = 1
self.bullet_width = 3
self.bullet_height = 15
self.bullet_color = 60,60,60
self.bullets_allowed = 5
game_functions.py
import sys
import pygame
from bullet import Bullet
def check_keydown_events(event,ai_settings,screen,ship,bullets):
# 响应按键
if event.key == pygame.K_RIGHT:
ship.moving_right = True
elif event.key == pygame.K_LEFT:
ship.moving_left = True
elif event.key == pygame.K_SPACE:
fire_bullet(ai_settings,screen,ship,bullets)
def fire_bullet(ai_settings,screen,ship,bullets):
# 创建一颗子弹,并将其加入到编组中
if len(bullets) < ai_settings.bullets_allowed:
new_bullet = Bullet(ai_settings, screen, ship)
bullets.add(new_bullet)
def check_keyup_events(event,ship):
# 响应松开
if event.key == pygame.K_RIGHT:
ship.moving_right = False
elif event.key == pygame.K_LEFT:
ship.moving_left = False
def check_events(ai_settings,screen,ship,bullets):
# 响应按键和鼠标事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
check_keydown_events(event,ai_settings,screen,ship,bullets)
elif event.type == pygame.KEYUP:
check_keyup_events(event,ship)
def update_screen(ai_settings,screen,ship,bullets):
# 更新屏幕上的图像,并切换到新屏幕
# 每次循环时都重绘屏幕
screen.fill(ai_settings.bg_color)
# 在飞船和外星人后面重绘所有子弹
for bullet in bullets.sprites():
bullet.draw_bullet()
ship.blitme()
# 让最近绘制的屏幕可见
pygame.display.flip()
def update_bullets(bullets):
# 更新子弹的位置,并删除已消失的子弹
bullets.update()
for bullet in bullets.copy():
if bullet.rect.bottom <= 0:
bullets.remove(bullet)
alien_invasion.py
import sys
import pygame
from settings import Settings
import game_functions as gf
from ship import Ship
from pygame.sprite import Group
def run_game():
# 初始化并创建一个屏幕对象
pygame.init()
ai_settings = Settings()
screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
pygame.display.set_caption("Alien Invasion")
# 创建一搜飞船
ship = Ship(ai_settings,screen)
# 创建存储子弹的编组
bullets = Group()
# 游戏的主循环
while True:
gf.check_events(ai_settings,screen,ship,bullets)
ship.update()
gf.update_bullets(bullets)
gf.update_screen(ai_settings,screen,ship,bullets)
run_game()
版权声明:本文为weixin_43697287原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。