如何上下移动

时间:2017-11-10 03:31:36

标签: python python-3.x

我正试图让外星入侵者的船上下移动但似乎无法使其正常工作而不会弄乱某些东西。

我的代码在下面我需要添加什么?

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的一个项目。 这个项目说的是

  

制作一个以屏幕中心的火箭开头的游戏。   允许玩家使用,向上,向下,向左或向右移动火箭   四个箭头键。确保火箭永远不会超出任何边缘或   屏幕。

4 个答案:

答案 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)