Python 如何上下移动

Python 如何上下移动,python,python-3.x,Python,Python 3.x,我试图让一艘外星入侵者的飞船上下移动,但似乎无法让它正常工作而不把事情搞砸 下面是我的代码,我需要添加什么 alien_.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

我试图让一艘外星入侵者的飞船上下移动,但似乎无法让它正常工作而不把事情搞砸

下面是我的代码,我需要添加什么

alien_.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)
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速成班的一个项目。 这个项目说

制作一个以屏幕中央的火箭开始的游戏。 允许玩家使用 四个箭头键。确保火箭不会超出任何边缘或边缘 屏幕


我还没有输入这个来检查,但我已经在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
# 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
2) 您的原始船舶等级将处理实际移动。 这应该类似于:

 # 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
# 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
#移动标志
self.moving_right=False
self.moving_left=False
self.moving_down=False
self.moving_up=False
def更新(自我):
“”“根据移动标志更新船舶的位置”“”
#更新船舶的中心值,而不是rect。
如果self.moving\u right和self.rect.right0:
self.center-=self.ai\u设置.发货速度\u系数
如果self.moving_down和self.rect.bottom>self.screen_rect.bottom:
self.center-=self.ai\u设置.发货速度\u系数
如果self.moving\u up和self.rect.top
好的,我已经破解了它-此解决方案现在正在运行:

设置.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_.py keydown和keydup检查事件:

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)
导入pygame
船舶等级:
“管理船舶的类”
定义初始(自我,ai游戏):
“”“初始化船舶并设置其起始位置”“”
self.screen=ai_game.screen
self.settings=ai_game.settings
self.screen_rect=ai_game.screen.get_rect()
#加载船舶图像并获取其rect
self.image=pygame.image.load('images/ship.bmp')
self.rect=self.image.get_rect()
#在屏幕底部中央启动每艘新船
#self.rect.midbottom=self.screen\u rect.midbottom
self.rect.center=self.screen\u rect.center
#存储船舶水平位置的十进制值
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更新(自我):
“”“更新船舶在移动旗上的位置”“”
如果self.moving\u right和self.rect.right0:
self.x-=self.settings.ship\u速度
如果self.moving_向上和self.rect.top>0:
self.y-=self.settings.ship\u速度
如果self.moving\u down和self.rect.bottom
我添加了向上移动和向下移动,加上必须为y轴添加self.rect.y。
船舶不能越过屏幕顶部或底部。

希望这对谷歌搜索同样问题的人有所帮助

我已经为这本书的第二版编写了一个可运行的解决方案

外星人入侵.py如下:

导入系统 导入pygame 从设置导入设置 从船进口 等级划分: 定义初始化(自): pygame.init() self.settings=settings() self.screen=pygame.display.set_模式((self.settings.screen_宽度、self.settings.screen_高度)) pygame.display.set_标题('外星人入侵') self.ship=ship(self) def run_游戏(自我): 尽管如此: 自我检查事件() self.ship.update() 自我更新屏幕() pygame.display.flip() 定义检查事件(自): 对于pygame.event.get()中的事件: 如果event.type==pygame.QUIT: sys.exit() elif event.type==pygame.KEYDOWN: 自我检查按键关闭事件(事件) elif event.type==pygame.KEYUP: 自我检查事件(事件) 定义检查按键关闭事件(自身、事件): 如果event.key==pygame.K_RIGHT: self.ship.moving_right=True elif event.key==pygame.K_左: self.ship.moving_left=真 elif event.key==pygame.K_UP: self.ship.moving_up=True elif event.key==pygame.K_向下: self.ship.moving_down=True elif event.key==pygame.K_q: sys.exit() def
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)