问题描述
如果您能帮助我解决在我的项目中移动 Rocket 的问题,我将不胜感激。
根据我在“Python 速成课程”一书中学到的材料,我已经开始编写我的第一个游戏。
我需要让火箭在游戏中移动到整个窗口并围绕它的轴移动。 一切正常(向左、向右、顶部、底部移动),然后我决定让我的火箭围绕它的轴移动。我花了很多时间来知道如何去做,而且它已经可以工作了(左 Shift)。 但现在我面临另一个问题。我的火箭现在不在屏幕上移动,而是绕着它的轴移动。我知道我的问题可能看起来很愚蠢,而且我的代码中的某处显然缺乏简单的逻辑。但是我尝试了几个小时自己修复它并没有得到结果。
这是我的代码:
import pygame
import sys
class Settings():
"""A class to store all settings for Rocket."""
def __init__(self):
"""Initialize the game screen settings."""
# Screen settings.
self.screen_width = 900
self.screen_height = 700
self.bg_color = (21,36,110)
class Rocket():
"""A class that describes rocket."""
def __init__(self,screen):
"""Initialize rocket and its starting position."""
self.screen = screen
#Load the rocket image and get its rect.
self.image = pygame.image.load('/media/philip/9074-45DF/Python/rocket/images/rocket.png')
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
#set starting position of a rocket.
self.rect.centerx = self.screen_rect.centerx
self.rect.centery = self.screen_rect.centery
#movement flag.
self.moving_right = False
self.moving_left = False
self.moving_up = False
self.moving_down = False
self.rotate_left = False
self.rocket_angle = 0
def update(self):
"""Update the rocket position based on the movement flag."""
if self.moving_right and self.rect.right < self.screen_rect.right:
self.rect.centerx += 2
if self.moving_left and self.rect.left > 0:
self.rect.centerx -= 2
if self.moving_up and self.rect.top > 0:
self.rect.centery -= 2
if self.moving_down and self.rect.bottom < self.screen_rect.bottom:
self.rect.centery += 2
def rotated_center(self,image,rocket_angle):
"""Rotating rocket around its axis."""
self.center = self.image.get_rect().center
self.rotated_image = pygame.transform.rotate(self.image,self.rocket_angle)
self.new_rect = self.rotated_image.get_rect(center = self.center)
return self.rotated_image,self.new_rect
def blit_rocket(self,rect,rocket_angle):
"""Draw the rocket at its current location."""
if self.rotate_left:
self.rocket_angle = (self.rocket_angle + 1) % 360
self.screen.blit(self.rotated_image,self.new_rect)
else:
self.rocket_angle = (self.rocket_angle + 0) % 360
self.screen.blit(self.rotated_image,self.new_rect)
def check_events(self):
"""Respond to a key events."""
# Responses to the keydown events.
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
self.moving_right = True
if event.key == pygame.K_LEFT:
self.moving_left = True
if event.key == pygame.K_DOWN:
self.moving_down = True
if event.key == pygame.K_UP:
self.moving_up = True
if event.key == pygame.K_LSHIFT:
self.rotate_left = True
# Responses to the keyup events.
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
self.moving_right = False
if event.key == pygame.K_LEFT:
self.moving_left = False
if event.key == pygame.K_DOWN:
self.moving_down = False
if event.key == pygame.K_UP:
self.moving_up = False
if event.key == pygame.K_LSHIFT:
self.rotate_left = False
pygame.init()
rocket_settings = Settings()
icon = pygame.image.load('/media/philip/9074-45DF/Python/rocket/images/rocket_icon.png')
pygame.display.set_icon(icon)
screen = pygame.display.set_mode((rocket_settings.screen_width,rocket_settings.screen_height))
pygame.display.set_caption("Rocket")
rocket = Rocket(screen)
"""The main game loop."""
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screen.fill((rocket_settings.bg_color))
rocket.update()
rocket.check_events()
rocket.rotated_center(rocket.image,rocket.rocket_angle)
rocket.blit_rocket(rocket.rect,rocket.rocket_angle)
pygame.display.flip()
解决方法
event
必须是方法 Rocket.check_events
的参数:
class Rocket():
# [...]
def check_events(self,event): # event argument
"""Respond to a key events."""
# Responses to the keydown events.
# [...]
您必须在事件循环中调用 rocket.check_events()
并将 event
传递给方法:
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
rocket.check_events(event) # <--- ADD
screen.fill((rocket_settings.bg_color))
rocket.update()
# rocket.check_events() <--- DELETE
rocket.rotated_center(rocket.image,rocket.rocket_angle)
rocket.blit_rocket(rocket.rect,rocket.rocket_angle)
pygame.display.flip()
pygame.Surface.get_rect.get_rect()
返回一个具有 Surface 对象大小的矩形,但它返回一个始终从 (0,0) 开始的矩形。
您必须从 self.rect.center
而不是 self.image.get_rect().center
获取对象的位置:
class Rocket():
# [...]
def rotated_center(self,image,rocket_angle):
"""Rotating rocket around its axis."""
self.rotated_image = pygame.transform.rotate(self.image,self.rocket_angle)
self.new_rect = self.rotated_image.get_rect(center = self.rect.center)
return self.rotated_image,self.new_rect
完整示例:
import pygame
import sys
class Settings():
"""A class to store all settings for Rocket."""
def __init__(self):
"""Initialize the game screen settings."""
# Screen settings.
self.screen_width = 900
self.screen_height = 700
self.bg_color = (21,36,110)
class Rocket():
"""A class that describes rocket."""
def __init__(self,screen):
"""Initialize rocket and its starting position."""
self.screen = screen
#Load the rocket image and get its rect.
self.image = pygame.image.load('/media/philip/9074-45DF/Python/rocket/images/rocket.png')
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
#set starting position of a rocket.
self.rect.centerx = self.screen_rect.centerx
self.rect.centery = self.screen_rect.centery
#movement flag.
self.moving_right = False
self.moving_left = False
self.moving_up = False
self.moving_down = False
self.rotate_left = False
self.rocket_angle = 0
def update(self):
"""Update the rocket position based on the movement flag."""
if self.moving_right and self.rect.right < self.screen_rect.right:
self.rect.centerx += 2
if self.moving_left and self.rect.left > 0:
self.rect.centerx -= 2
if self.moving_up and self.rect.top > 0:
self.rect.centery -= 2
if self.moving_down and self.rect.bottom < self.screen_rect.bottom:
self.rect.centery += 2
def rotated_center(self,self.new_rect
def blit_rocket(self,rect,rocket_angle):
"""Draw the rocket at its current location."""
if self.rotate_left:
self.rocket_angle = (self.rocket_angle + 1) % 360
self.screen.blit(self.rotated_image,self.new_rect)
else:
self.rocket_angle = (self.rocket_angle + 0) % 360
self.screen.blit(self.rotated_image,self.new_rect)
def check_events(self,event):
"""Respond to a key events."""
# Responses to the keydown events.
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
self.moving_right = True
if event.key == pygame.K_LEFT:
self.moving_left = True
if event.key == pygame.K_DOWN:
self.moving_down = True
if event.key == pygame.K_UP:
self.moving_up = True
if event.key == pygame.K_LSHIFT:
self.rotate_left = True
# Responses to the keyup events.
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
self.moving_right = False
if event.key == pygame.K_LEFT:
self.moving_left = False
if event.key == pygame.K_DOWN:
self.moving_down = False
if event.key == pygame.K_UP:
self.moving_up = False
if event.key == pygame.K_LSHIFT:
self.rotate_left = False
pygame.init()
rocket_settings = Settings()
icon = pygame.image.load('/media/philip/9074-45DF/Python/rocket/images/rocket_icon.png')
pygame.display.set_icon(icon)
screen = pygame.display.set_mode((rocket_settings.screen_width,rocket_settings.screen_height))
pygame.display.set_caption("Rocket")
rocket = Rocket(screen)
"""The main game loop."""
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
rocket.check_events(event)
screen.fill((rocket_settings.bg_color))
rocket.update()
rocket.rotated_center(rocket.image,rocket.rocket_angle)
pygame.display.flip()