新手求助,外星人入侵游戏的练习问题

雪地猢狲 2020-05-01 10:53:40
新手,学习《python:从入门到实践》这本书,到第十四章第二个练习这里卡住了。
14-2 射击练习 :创建一个矩形,它在屏幕右边缘以固定的速度上下移动。然后,在屏幕左边缘创建一艘飞船,玩家可上下移动该飞船,并射击前述矩形目标。添加一 个用于开始游戏的Play按钮,在玩家三次未击中目标时结束游戏,并重新显示Play按钮,让玩家能够通过单击该按钮来重新开始游戏。
问题:飞船、子弹和目标矩形都不会移动,按键无响应(空格有,但子弹不移动)我检查代码之后还是找不出问题所在
情况如图:

代码如下:
分为六个模块

settings.py
#创建射击练习射击类
class Settings():
def __init__(self):
#初始化
#设置屏幕
self.screen_width = 1400
self.screen_height = 750
self.bg_color = (200,200,200)
#设置飞船移动速度
self.ship_factor = 3
#设置火移动速度
self.fire_factor = 1
#限制火的数量
self.fire_limited = 2
#设置矩形移动速度
self.rect_factor = 5
#设置矩形方向值
self.rect_direction = 1



ship.py
创建飞船类
import pygame
class Ship():
def __init__(self,screen,settings):
#初始化
self.screen = screen
self.settings = settings
self.image = pygame.image.load('image/ship.png')
#矩形化飞船和屏幕
self.rect = self.image.get_rect()
self.screen_rect = self.screen.get_rect()
#飞船初始位置为屏幕左侧中间
self.rect.x = self.screen_rect.left
self.rect.y = self.screen_rect.centery
#储存准确位置
self.y = float(self.rect.y)
#设置移动标志
self.moving_up = False
self.moving_down = False

def update(self):
#根据标志来移动飞船
if self.moving_down and self.rect.y < self.screen_rect.bottom :
self.rect.y += self.settings.ship_factor
if self.moving_up and self.rect.y > 0:
self.rect.y -= self.settings.ship_factor
#根据准确位置来更新
self.rect.y = self.y

def blitme(self):
#绘制飞船
self.screen.blit(self.image,self.rect)

def reset_ship(self):
#重置飞船
self.rect.y = self.screen_rect.centery



fire.py
from pygame.sprite import Sprite
import pygame
#创建火球类(火球为编组)
class Fire(Sprite):
def __init__(self,screen,settings,ship):
#初始化
#继承编组
super().__init__()
self.screen = screen
self.settings = settings
self.image = pygame.image.load('image/fire.png')
#矩形化
self.rect = self.image.get_rect()
#设置火球位置(由于火球由飞船发射,所以坐标与发射时的飞船一致)
self.rect.x = ship.rect.x
self.rect.y = ship.rect.y
#储存准确位置
self.x = float(self.rect.x)

def update(self):
#火球向右移动
self.rect.x += self.settings.fire_factor
#更新火球位置
self.rect.x = self.x

def blitme(self):
#绘制子弹
self.screen.blit(self.image,self.rect)



rect.py
#创建射击目标矩形
import pygame
class Rect():
def __init__(self,screen,settings):
#初始化
self.screen =screen
self.settings = settings
self.image = pygame.image.load('image/rect.png')
#矩形化图标和屏幕
self.rect = self.image.get_rect()
self.screen_rect = self.screen.get_rect()
#设置初始位置
self.rect.x = self.screen_rect.right - self.rect.width
self.rect.y = self.screen_rect.centery
#储存准确位置
self.y = float(self.rect.y)

def update(self):
#根据方向值来移动
self.rect.y += self.settings.rect_factor * self.settings.rect_direction
#更新位置
self.rect.y = self.y

def blitme(self):
#绘制矩形
self.screen.blit(self.image,self.rect)

def check_edges(self):
# 检查矩形是否触碰到了边缘
if self.rect.y >= self.screen_rect.bottom:
return True
elif self.rect.y <= 0 :
return True



functions.py
#此模块储存游戏主要功能
from fire import Fire
import pygame
import sys

def check_keydown(event,ship,fires,settings,screen):
#检查案件事件
if event.key == pygame.K_DOWN:
ship.moving_down = True
elif event.key == pygame.K_UP:
ship.moving_up = True
elif event.key == pygame.K_SPACE:
fire_fire(fires,settings,screen,ship)
elif event.key == pygame.K_q:
sys.exit()
elif event.key == pygame.K_p:
start_game()

def check_keyup(event,ship):
#检查松开事件
if event.key == pygame.K_DOWN:
ship.moving_down = False
elif event.key == pygame.K_UP:
ship.moving_up = False

def check_event(ship,fires,settings,screen):
#检查事件
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
check_keydown(event,ship,fires,settings,screen)
elif event.type == pygame.KEYUP:
check_keyup(event,ship)
elif event.type == pygame.QUIT:
sys.exit()

def fire_fire(fires,settings,screen,ship):
#当小于限制数量时开火
if len(fires) < settings.fire_limited :
new_fire = Fire(screen,settings,ship)
fires.add(new_fire)

def rect_update(rect,settings):
#更新矩形
rect.update()
#检查触边
rect_check_edges(rect,settings)

def rect_check_edges(rect,settings):
#当矩形触边时改变移动方向
if rect.check_edges:
settings.rect_direction *= -1

def fire_update(screen,rect,fires):
screen_rect = screen.get_rect()
#更新火位置
for fire in fires.sprites():
fire.update()
#删除不可见的火
if fire.rect.x >= screen_rect.right :
fires.remove(fire)
#检查碰撞
check_collisions(rect,fires)

def check_collisions(rect,fires):
#当击中矩形时,火消失
if pygame.sprite.spritecollideany(rect,fires,False):
for fire in pygame.sprites():
fires.remove(fire)

def update_screen(screen,settings,fires,ship,rect):
#显示屏幕各要素
screen.fill(settings.bg_color)
for fire in fires.sprites():
fire.blitme()
ship.blitme()
rect.blitme()
pygame.display.flip()


主程序

shot.py
#创建游戏主程序
import pygame
from settings import Settings
from ship import Ship
from rect import Rect
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('shot')
#创建飞船实例
ship = Ship(screen,settings)
#创建火球编组实例
fires = Group()
#创建矩形实例
rect = Rect(screen,settings)
#主循环
while True:
f.check_event(ship,fires,settings,screen)
ship.update()
f.rect_update(rect,settings)
f.fire_update(screen, rect, fires)
f.update_screen(screen,settings,fires,ship,rect)
#运行游戏
run_game()


怀疑是显示的问题,但是没找到问题
求大神指点
...全文
210 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_45903952 2020-05-02
  • 打赏
  • 举报
回复


    def update(self):
        #根据标志来移动飞船
      if self.moving_down and self.rect.y < self.screen_rect.bottom-self.rect.height:
            self.rect.y += self.settings.ship_factor
      if self.moving_up and self.rect.y > 0:
            self.rect.y -= self.settings.ship_factor
这里还有个小错误
weixin_45903952 2020-05-02
  • 打赏
  • 举报
回复
fire.py def update(self): #火球向右移动 self.rect.x += self.settings.fire_factor #更新火球位置 #self.rect.x = self.x
weixin_45903952 2020-05-02
  • 打赏
  • 举报
回复
ship.py


    def update(self):
        #根据标志来移动飞船
      if self.moving_down and self.rect.y < self.screen_rect.bottom :
            self.rect.y += self.settings.ship_factor
      if self.moving_up and self.rect.y > 0:
            self.rect.y -= self.settings.ship_factor
      #根据准确位置来更新
      #self.rect.y = self.y

      
Vegdie 2020-05-02
  • 打赏
  • 举报
回复
刚看见,还以为是Qt,结果你是用Python,那么我无法帮忙,因为我Python小白
雪地猢狲 2020-05-02
  • 打赏
  • 举报
回复
没有人来看看吗
雪地猢狲 2020-05-02
  • 打赏
  • 举报
回复
引用 10 楼 weixin_45903952的回复:
你的self.x值是一个定值,如果令self.rect.x=self.x,那就是一直不动了,而真正想实现的是,X以一定的速度向右移动,即要增加x值
明白了明白了
weixin_45903952 2020-05-02
  • 打赏
  • 举报
回复
你的self.x值是一个定值,如果令self.rect.x=self.x,那就是一直不动了,而真正想实现的是,X以一定的速度向右移动,即要增加x值
雪地猢狲 2020-05-02
  • 打赏
  • 举报
回复
引用 8 楼 weixin_45903952 的回复:
[quote=引用 7 楼 雪地猢狲 的回复:]
[quote=引用 4 楼 weixin_45903952的回复:]fire.py

def update(self):
#火球向右移动
self.rect.x += self.settings.fire_factor
#更新火球位置
#self.rect.x = self.x

这个也是和上面一样错在更新位置部分吗[/quote]

把语句给# 注释了,用不着这句了,加上位置一直不变[/quote]
为什么位置一直不变,不太理解
weixin_45903952 2020-05-02
  • 打赏
  • 举报
回复
引用 7 楼 雪地猢狲 的回复:
[quote=引用 4 楼 weixin_45903952的回复:]fire.py def update(self): #火球向右移动 self.rect.x += self.settings.fire_factor #更新火球位置 #self.rect.x = self.x
这个也是和上面一样错在更新位置部分吗[/quote] 把语句给# 注释了,用不着这句了,加上位置一直不变
雪地猢狲 2020-05-02
  • 打赏
  • 举报
回复
引用 4 楼 weixin_45903952的回复:
fire.py def update(self): #火球向右移动 self.rect.x += self.settings.fire_factor #更新火球位置 #self.rect.x = self.x
这个也是和上面一样错在更新位置部分吗
雪地猢狲 2020-05-02
  • 打赏
  • 举报
回复
引用 3 楼 weixin_45903952的回复:
ship.py


    def update(self):
        #根据标志来移动飞船
      if self.moving_down and self.rect.y < self.screen_rect.bottom :
            self.rect.y += self.settings.ship_factor
      if self.moving_up and self.rect.y > 0:
            self.rect.y -= self.settings.ship_factor
      #根据准确位置来更新
      #self.rect.y = self.y

      
这个是哪里错了更新位置那里吗

37,721

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • IT.BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧