我正试图让外星入侵者的船上下移动但似乎无法使其正常工作而不会弄乱某些东西。
我的代码在下面我需要添加什么?
alien_invasion.py:
import sys
import pygame
from settings import Settings
from ship import Ship
import game_functions as gf
def run_game():
#Initialize pygame, settings, and screen object
pygame.init()
ai_settings = Settings()
screen = pygame.display.set_mode(
(ai_settings.screen_width, ai_settings.screen_height))
pygame.display.set_caption("Alien Invasion")
#Draw the ship
ship = Ship(ai_settings, screen)
#Start the main loop for the game.
while True:
#Watch for keyboard and mouse events
gf.check_events(ship)
ship.update()
gf.update_screen(ai_settings, screen, ship)
run_game()
ship.py:
import pygame
class Ship():
def __init__(self, ai_settings, screen):
"""Initialize teh ship and set its starting position"""
self.screen = screen
self.ai_settings = ai_settings
#Load teh ship image and get its rect
self.image = pygame.image.load('ship.bmp')
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
#Start each new ship at the bottom center of the screen
self.rect.centerx = self.screen_rect.centerx
self.rect.bottom = self.screen_rect.bottom
# Store a decimal value for the ship's center.
self.center = float(self.rect.centerx)
# Movement flag
self.moving_right = False
self.moving_left = False
def update(self):
"""Update the ship's postion based on the movement flag"""
# Update the ship's center value, not the rect.
if self.moving_right and self.rect.right < self.screen_rect.right:
self.center += self.ai_settings.ship_speed_factor
if self.moving_left and self.rect.left > 0:
self.center -= self.ai_settings.ship_speed_factor
# Update rect object from self.center
self.rect.centerx = self.center
def blitme(self):
"""Draw the ship at its current location"""
self.screen.blit(self.image, self.rect)
game_fuction.py:
import sys
import pygame
def check_keydown_events(event, ship):
"""Responds to keypresses"""
if event.key == pygame.K_RIGHT:
ship.moving_right = True
elif event.key == pygame.K_LEFT:
ship.moving_left = True
def check_keyup_events(event, ship):
"""Respoinds to key releases"""
if event.key == pygame.K_RIGHT:
ship.moving_right = False
elif event.key == pygame.K_LEFT:
ship.moving_left = False
def check_events(ship):
"""Respond to keypresses and mouse events."""
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
check_keydown_events(event, ship)
elif event.type == pygame.KEYUP:
check_keyup_events(event, ship)
def update_screen(ai_settings, screen, ship):
"""Update images on the screen and flip to the new screen"""
#Redraw the screen during each pass through the loop
screen.fill(ai_settings.bg_color)
ship.blitme()
#Make the most recently drawn screen visible.
pygame.display.flip()
settings.py:
class Settings():
"""A Class to store all settings for ALein INvasion"""
def __init__(self):
"""Initialize the game's settings"""
#screen settings
self.screen_width = 1200
self.screen_height = 800
self.bg_color = (255,255,255)
# Ship Settings
self.ship_speed_factor = 1.5
这是Python Crash Course的一个项目。 这个项目说的是
制作一个以屏幕中心的火箭开头的游戏。 允许玩家使用,向上,向下,向左或向右移动火箭 四个箭头键。确保火箭永远不会超出任何边缘或 屏幕。
答案 0 :(得分:1)
我没有输入这个来检查,但我已经在pygame中解决了类似的问题/项目。看起来你需要在两个地方修改代码:
1)抓住按下向下键和向上键的事件。 这可能是这样的:
# from your game_function.py
def check_keydown_events(event, ship):
"""Responds to keypresses"""
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_DOWN:
ship.moving_down = True
elif event.key == pygame.K_UP:
ship.moving_up = True
def check_keyup_events(event, ship):
"""Respoinds to key releases"""
if event.key == pygame.K_RIGHT:
ship.moving_right = False
elif event.key == pygame.K_LEFT:
ship.moving_left = False
elif event.key == pygame.K_DOWN:
ship.moving_down = False
elif event.key == pygame.K_UP:
ship.moving_up = False
2)您的原始船级处理实际运动。 这应该类似于:
# Movement flag
self.moving_right = False
self.moving_left = False
self.moving_down = False
self.moving_up = False
def update(self):
"""Update the ship's postion based on the movement flag"""
# Update the ship's center value, not the rect.
if self.moving_right and self.rect.right < self.screen_rect.right:
self.center += self.ai_settings.ship_speed_factor
if self.moving_left and self.rect.left > 0:
self.center -= self.ai_settings.ship_speed_factor
if self.moving_down and self.rect.bottom > self.screen_rect.bottom:
self.center -= self.ai_settings.ship_speed_factor
if self.moving_up and self.rect.top < self.screen_rect.top:
self.center -= self.ai_settings.ship_speed_factor
# Update rect object from self.center - might need to be changed now to handle
# movement in two directions properly.
if self.moving_up or self.moving_down:
self.rect.centery = self.center
if self.moving_left or self.moving_right:
self.rect.centerx = self.center
答案 1 :(得分:0)
好的,我已经破解了 - 这个解决方案现在正在运行:
settings.py
class Settings:
"""A Class to store all settings for ALien INvasion"""
def __init__(self):
"""Initialize the game's settings"""
#screen settings
self.screen_width = 1200
self.screen_height = 800
self.bg_color = (255,255,255)
# Ship Settings
ship_speed_factor = 1.5
game_functions.py
import sys
import pygame
def check_keydown_events(event, ship):
"""Responds to keypresses"""
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_DOWN:
ship.moving_down = True
elif event.key == pygame.K_UP:
ship.moving_up = True
def check_keyup_events(event, ship):
"""Responds to key releases"""
if event.key == pygame.K_RIGHT:
ship.moving_right = False
elif event.key == pygame.K_LEFT:
ship.moving_left = False
elif event.key == pygame.K_DOWN:
ship.moving_down = False
elif event.key == pygame.K_UP:
ship.moving_up = False
def check_events(ship):
"""Respond to keypresses and mouse events."""
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
elif event.type == pygame.KEYDOWN:
check_keydown_events(event, ship)
elif event.type == pygame.KEYUP:
check_keyup_events(event, ship)
def update_screen(ai_settings, screen, ship):
"""Update images on the screen and flip to the new screen"""
#Redraw the screen during each pass through the loop
screen.fill(ai_settings.bg_color)
ship.blitme()
#Make the most recently drawn screen visible.
pygame.display.flip()
ship.py
import pygame
class Ship:
def __init__(self, ai_settings, screen):
"""Initialize teh ship and set its starting position"""
self.screen = screen
self.ai_settings = ai_settings
#Load the ship image and get its rect
self.image = pygame.image.load('ship.bmp')
self.rect = self.image.get_rect()
self.screen_rect = screen.get_rect()
#Start each new ship at the bottom center of the screen
self.rect.centerx = self.screen_rect.centerx
self.rect.bottom = self.screen_rect.bottom
# Store a decimal value for the ship's x and y center.
self.centerx = float(self.rect.centerx)
self.centery = float(self.rect.centery)
# Movement flag
self.moving_right = False
self.moving_left = False
self.moving_down = False
self.moving_up = False
def update(self):
"""Update the ship's postion based on the movement flag"""
# Update the ship's center value, not the rect.
if self.moving_right and self.rect.right < self.screen_rect.right:
self.centerx += self.ai_settings.ship_speed_factor
if self.moving_left and self.rect.left > 0:
self.centerx -= self.ai_settings.ship_speed_factor
if self.moving_down and self.rect.bottom < self.screen_rect.bottom:
self.centery += self.ai_settings.ship_speed_factor
if self.moving_up and self.rect.top > self.screen_rect.top:
self.centery -= self.ai_settings.ship_speed_factor
# Update rect object from self.center - might need to be changed now to handle
# movement in two directions properly.
if self.moving_up or self.moving_down:
self.rect.centery = self.centery
if self.moving_left or self.moving_right:
self.rect.centerx = self.centerx
def blitme(self):
"""Draw the ship at its current location"""
self.screen.blit(self.image, self.rect)
alien_invasion.py
import sys
import pygame
from settings import Settings
from ship import Ship
import game_functions as gf
def run_game():
#Initialize pygame, settings, and screen object
pygame.init()
ai_settings = Settings()
screen = pygame.display.set_mode(
(ai_settings.screen_width, ai_settings.screen_height))
pygame.display.set_caption("Alien Invasion")
#Draw the ship
ship = Ship(ai_settings, screen)
#Start the main loop for the game.
while True:
#Watch for keyboard and mouse events
gf.check_events(ship)
ship.update()
gf.update_screen(ai_settings, screen, ship)
run_game()
实际上,我所做的只是实现我描述的所有更改,并消除布局/语法中的一些基本错误。请注意,当您单击红色按钮时,我添加了一个更好的退出功能来关闭图形画布。
如果此解决方案也适用于您,请将其标记为答案,以便我可以在堆栈流程中获得足够的声誉。
答案 2 :(得分:0)
我知道这是一个古老的问题,但是当我遇到相同的问题时,这是最高的结果。只是想展示我最终是怎么做到的。
alien_invasion.py按键和按键检查事件:
def _check_keydown_events(self, event):
"""respond to keypresses"""
if event.key == pygame.K_RIGHT:
self.ship.moving_right = True
elif event.key == pygame.K_d:
self.ship.moving_right = True
elif event.key == pygame.K_LEFT:
self.ship.moving_left = True
elif event.key == pygame.K_a:
self.ship.moving_left = True
elif event.key == pygame.K_UP:
self.ship.moving_up = True
elif event.key == pygame.K_DOWN:
self.ship.moving_down = True
elif event.key == pygame.K_q:
sys.exit()
def _check_keyup_events(self, event):
"""respond to key releases"""
if event.key == pygame.K_RIGHT:
self.ship.moving_right = False
elif event.key == pygame.K_d:
self.ship.moving_right = False
elif event.key == pygame.K_LEFT:
self.ship.moving_left = False
elif event.key == pygame.K_a:
self.ship.moving_left = False
elif event.key == pygame.K_UP:
self.ship.moving_up = False
elif event.key == pygame.K_DOWN:
self.ship.moving_down = False
ship.py
import pygame
class Ship:
"""A class to manage the ship"""
def __init__(self, ai_game):
"""initialize the ship and set its starting position"""
self.screen = ai_game.screen
self.settings = ai_game.settings
self.screen_rect = ai_game.screen.get_rect()
# load the ship image and get its rect
self.image = pygame.image.load('images/ship.bmp')
self.rect = self.image.get_rect()
# start each new ship at the bottom center of the screen
# self.rect.midbottom = self.screen_rect.midbottom
self.rect.center = self.screen_rect.center
# store a decimal value for the ship's horizontal position
self.x = float(self.rect.x)
self.y = float(self.rect.y)
# movement flag
self.moving_right = False
self.moving_left = False
self.moving_up = False
self.moving_down = False
def update(self):
"""update the ship's position on the movement flag"""
if self.moving_right and self.rect.right < self.screen_rect.right:
self.x += self.settings.ship_speed
if self.moving_left and self.rect.left > 0:
self.x -= self.settings.ship_speed
if self.moving_up and self.rect.top > 0:
self.y -= self.settings.ship_speed
if self.moving_down and self.rect.bottom < self.screen_rect.bottom:
self.y += self.settings.ship_speed
# update rect object from self.x
self.rect.x = self.x
self.rect.y = self.y
def blitme(self):
"""draw the ship at its current location"""
self.screen.blit(self.image, self.rect)
我添加了moving_up和moving_down,还不得不为y轴添加self.rect.y。
船只不能越过屏幕顶部或底部。
希望这对使用Google搜索相同问题的人有所帮助。
答案 3 :(得分:0)
我已经为本书的第二版写了一个可运行的解决方案。
alien_invasion.py 如下:
import sys
import pygame
from settings import Settings
from ship import Ship
class AlienInvasion:
def __init__(self):
pygame.init()
self.settings = Settings()
self.screen = pygame.display.set_mode((self.settings.screen_width, self.settings.screen_height))
pygame.display.set_caption('Alien Invasion')
self.ship = Ship(self)
def run_game(self):
while True:
self._check_event()
self.ship.update()
self._update_screen()
pygame.display.flip()
def _check_event(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
self._check_keydown_events(event)
elif event.type == pygame.KEYUP:
self._check_keyup_event(event)
def _check_keydown_events(self, event):
if event.key == pygame.K_RIGHT:
self.ship.moving_right = True
elif event.key == pygame.K_LEFT:
self.ship.moving_left = True
elif event.key == pygame.K_UP:
self.ship.moving_up = True
elif event.key == pygame.K_DOWN:
self.ship.moving_down = True
elif event.key == pygame.K_q:
sys.exit()
def _check_keyup_event(self, event):
if event.key == pygame.K_RIGHT:
self.ship.moving_right = False
elif event.key == pygame.K_LEFT:
self.ship.moving_left = False
elif event.key == pygame.K_DOWN:
self.ship.moving_down = False
elif event.key == pygame.K_UP:
self.ship.moving_up = False
def _update_screen(self):
self.screen.fill(self.settings.bg_color)
self.ship.blitme()
if __name__ == '__main__':
ai = AlienInvasion()
ai.run_game()
settings.py
class Settings:
def __init__(self):
self.screen_width = 1200
self.screen_height = 800
self.bg_color = (230, 230, 230)
self.ship_speed = 1.5
ship.py
import pygame
class Ship:
def __init__(self, ai_game):
self.screen = ai_game.screen
self.settings = ai_game.settings
self.screen_rect = ai_game.screen.get_rect()
self.image = pygame.image.load('images/ship.bmp')
self.rect = self.image.get_rect()
self.rect.midbottom = self.screen_rect.midbottom
self.x = float(self.rect.x)
self.y = float(self.rect.y)
self.moving_right = False
self.moving_left = False
self.moving_up = False
self.moving_down = False
def update(self):
if self.moving_right and self.rect.right < self.screen_rect.right:
self.x += self.settings.ship_speed
if self.moving_left and self.rect.left > 0:
self.x -= self.settings.ship_speed
if self.moving_up and self.rect.top > self.screen_rect.top:
self.y -= self.settings.ship_speed
if self.moving_down and self.rect.bottom < self.screen_rect.bottom:
self.y += self.settings.ship_speed
self.rect.x = self.x
self.rect.y = self.y
def blitme(self):
self.screen.blit(self.image, self.rect)