python游戏练习侧面射击没有出现飞船和子弹

最近在看《python编程:从入门到实践》这本书学习python。在项目外星人入侵的射击练习——侧面射击这里遇到了问题。
侧面射击 :编写一个游戏,将一艘飞船放在屏幕左边,并允许玩家上下移动飞船。在玩家按空格键时,让飞船发射一颗在屏幕中向右穿行的子弹,并在子弹离开 屏幕而消失后将其删除。
我在编写代码时想要试一试其他效果,所以设定飞船为可以上下左右移动,子弹是一个png格式的图片而非python内生成的矩形。

我把飞船图片替换为图一,命名为eye 后面的飞船概念命名都为eye

我把子弹图片设置为图二,命名为fire,后面的子弹概念命名都为fire

我把飞船图片替换为这个,命名为eye 后面的飞船概念命名都为eye
我将子弹图片设置为这个,命名为fire,后面子弹的概念命名都为fire
设置模块
settings.py#储存相关设置的模块 class Settings: def __init__(self): #设置屏幕参数 self.screen_width = 1400 self.screen_height = 750 self.bg_color = (200,200,200) #设置眼的参数 self.eye_speed_factor = 1.5 #设置关于火的参数 self.fire_speed_factor = 2.5 #此游戏不限制子弹数量

eye.py

#创建一个关于眼的模块
import pygame
class Eye:
    def __init__(self,settings,screen):
        #初始化眼
        self.setting = settings
        self.screen = screen
        #返回飞船贴图路径
        self.image = pygame.image.load("image/eye.png")
        #矩形化屏幕和眼贴图
        self.screen_rect = self.screen.get_rect()
        self.rect = self.image.get_rect()
        #以屏幕为参照设置眼的初始位置(屏幕右边界中央)
        self.rect.right = self.screen_rect.right
        self.rect.centery = self.screen_rect.centery
        #用属性x和y来储存浮点化后的坐标
        self.x = float(self.rect.right)
        self.y = float(self.rect.centery)
        #设置眼上下左右移动的标志
        self.moving_right = False
        self.moving_left = False
        self.moving_down = False
        self.moving_up = False
    #创建一个函数用于传输图像
    def blitme(self):
        self.screen.blit(self.image,self.rect)
    #创建一个根据标志来移动眼的函数
    def update(self):
        if self.moving_right and self.rect.right < self.screen_rect.right :
            self.x += self.setting.eye_speed_factor
        if self.moving_left and self.rect.left > 0 :
            self.x  -= self.setting.eye_speed_factor
        if self.moving_down and self.rect.bottom < self.screen_rect.bottom :
            self.y += self.setting.eye_speed_factor
        if self.moving_up and self.rect.top > 0 :
            self.y -= self.setting.eye_speed_factor
        #根据x和y的值来更新rect
        self.rect.x = self.x
        self.rect.y = self.y

fire.py

#导入精灵类
import pygame
from pygame.sprite import Sprite
class Fire(Sprite):
    '''一个对发射的子弹进行管理的类'''
    def __init__(self,settings,screen,eye):
        #通过super来继承sprite
        super().__init__()
        self.screen = screen
        #利用load返回火球贴图并矩形化处理
        self.image = pygame.image.load('image/fire.png')
        self.rect = self.image.get_rect()
        #根据眼的位置来确定眼的位置
        #由于这个游戏的移动程度大,所以根据眼当时所在位置来确定
        self.rect.x = eye.rect.x
        self.rect.y = eye.rect.y
        #浮点化储存火的位置
        '''由于火是从右到左直线移动,y轴坐标由发射时的眼决定,所以这里只需储存x轴的位置'''
        self.x = float(self.rect.x)
        #储存火移动速度
        self.speed_factor = settings.fire_speed_factor
    def update(self):
        #让火球向左移动
        self.x -= self.speed_factor
        #更新火rect的位置
        self.rect.x = self.x
    def blitme(self):
        #利用位块传输绘制火球
        self.screen.blit(self.image,self.rect)




functions.py

#将管理事件的代码放在这个模块,以简化主程序
import sys
import pygame
from fire import Fire
def fire(settings,screen,eye,fires):
    #创建一个新火,将新火添加到编组中去
    new_fire = Fire(settings,screen,eye)
    fires.add(new_fire)
def check_keydown_events(event,settings,screen,eye,fires):
    #检查按键情况
    if event.key == pygame.K_RIGHT:
        eye.moving_right = True
    elif event.key == pygame.K_LEFT:
        eye.moving_left = True
    elif event.key == pygame.K_DOWN:
        eye.moving_down = True
    elif event.key == pygame.K_UP:
        eye.moving_up = True
        #当按键为空格时调用前面定义的管理火的函数
    elif event.key == pygame.K_SPACE:
        fire(settings,screen,eye,fires)
def check_keyup_events(event,eye):
    #检查松开情况
    if event.key == pygame.K_RIGHT:
        eye.moving_right = False
    elif event.key == pygame.K_LEFT:
        eye.moving_left = False
    elif event.key == pygame.K_DOWN:
        eye.moving_down = False
    elif event.key == pygame.K_UP:
        eye.moving_up = False
        '''由于玩家松开空格键也没有实际影响,这里不必检查空格松开'''
def check_events(settings,screen,eye,fires):
    #循环检测事件类型
    for event in pygame.event.get():
        #当按键时调用检查按键函数
        if event.type == pygame.K_DOWN:
            check_keydown_events(event,settings,screen,eye,fires)
        #当松开时调用检查松开函数
        elif event.type == pygame.K_UP:
            check_keyup_events(event,eye)
        #检测到退出条件时退出
        elif event.type == pygame.QUIT:
            sys.exit()
def update_fire(fires):
    #对编组中每一个火调用update进行更新
    fires.update()
    #删除已消失的火球
    #为防止漏掉需要删掉的精灵,此处遍历的是编组的副本,能有效删除已消失的火球
    for fire in fires.copy():
        if fire.rect.left <= 0:
            fires.remove(fire)
def update_screen(settings,screen,fires,eye):
    #填充屏幕颜色
    screen.fill(settings.bg_color)
    #对编组中每一个火使用blitme(),绘制所有火
    #这里对编组使用了方法sprites,它返回编组里的每一个精灵
    for fire in fires.sprites():
        fire.blitme()
    #绘制眼
    eye.blitme()
    #让最近绘制的屏幕可见
    pygame.display.flip()


主程序
side_shoot.py

#侧面射击 :编写一个游戏,将一艘飞船放在屏幕右边,并允许玩家上下左右移动飞船。
# 在玩家按空格键时,让飞船发射一颗在屏幕中向左穿行的子弹,并在子弹离开屏幕而消失后将其删除。
import pygame
from settings import Settings
from eye import Eye
import functions as f
#导入编组
from pygame.sprite import Group
def run_game():
    #初始化游戏
    pygame.init()
    settings = Settings()
    #设置屏幕
    #这里是括号中引用一个元组,所以是括中括
    screen = pygame.display.set_mode((settings.screen_width,settings.screen_height))
    #设置游戏标题
    pygame.display.set_caption('side_shoot')
    #创建一个眼实例
    eye = Eye(settings,screen)
    #创建一个火编组
    fires = Group()
    #开始游戏主循环
    while True:
        #调用模块functions的check_events对事件进行检查
        f.check_events(settings,screen,eye,fires)
        #根据事件来改变眼的位置
        eye.update()
        #更新和删除火
        f.update_fire(fires)
        #绘制屏幕、眼和火
        f.update_screen(settings,screen,fires,eye)
#运行游戏
run_game()

运行主程序如图,没有火也没有眼
屏幕填充颜色是在绘制眼和火之前啊,为什么还是没有显示呢

看了几遍还是没有找到问题求大神解惑,指点迷津。


版权声明:本文为weixin_46467641原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。