最近在看《python编程:从入门到实践》这本书学习python。在项目外星人入侵的射击练习——侧面射击这里遇到了问题。
侧面射击 :编写一个游戏,将一艘飞船放在屏幕左边,并允许玩家上下移动飞船。在玩家按空格键时,让飞船发射一颗在屏幕中向右穿行的子弹,并在子弹离开 屏幕而消失后将其删除。
我在编写代码时想要试一试其他效果,所以设定飞船为可以上下左右移动,子弹是一个png格式的图片而非python内生成的矩形。
我把飞船图片替换为图一,命名为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版权协议,转载请附上原文出处链接和本声明。