【问题标题】:Reverse direction on borders in pygame在pygame中的边界上反转方向
【发布时间】:2021-06-27 18:05:42
【问题描述】:

我正在尝试使用 pygame 制作太空入侵者游戏,但我不知道如何让 ufo(敌人)对象在每次碰到边界时左右移动。基本上我希望它看起来像这样:https://www.youtube.com/watchv=jM0v4VemWu8&ab_channel=AndrijaOluji%C4%87AndrijaOluji%C4%87

我遇到的问题出在这部分代码中:

UFO_VEL = 5
def ufo_movement(ufo, UFO_VEL):
    ufo.x -= UFO_VEL
    if ufo.x == 0:
        ufo.x += UFO_VEL

这似乎是一项非常简单的任务,我设法使它在与 Tkinter 的类似项目中工作,但在 pygame 中它卡在无限循环中,而 pygame.display.update() 所以它达到 0,它反转了方向为一帧,然后再次以原始方向( ufo.x -= UFO_VEL )开始,因此有效地 ufo.x 卡在 0 和 5 之间,并且宇宙飞船似乎没有移动。我尝试了一切,甚至画了一条线(矩形)作为边框,并让它在碰到线(UserEvent)时反弹,但我就是无法让它工作。这是我的完整代码:

import os
import pygame

# WIN CONSTANTS
WIDTH, HEIGHT = 500, 700
WIN = pygame.display.set_mode(((WIDTH, HEIGHT)))
pygame.display.set_caption("First Game!")

# COLORS LIST
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
FPS = 60

# BACKGROUND IMAGE
BG = pygame.image.load(os.path.join("spacebg.jpg"))
BG_RESIZED = pygame.transform.scale(BG, (WIDTH, HEIGHT))

# SPACESHIP CONSTANTS
SPACESHIP_WIDTH = 100
SPACESHIP_HEIGHT = 40
SPACESHIP_IMAGE = pygame.image.load(os.path.join("spaceship.png"))
# Resize image
SPACESHIP = pygame.transform.scale(SPACESHIP_IMAGE, (SPACESHIP_WIDTH, SPACESHIP_HEIGHT))  
SPACESHIP_VEL = 10

# UFO CONSTANTS
UFO_WIDTH = 100
UFO_HEIGHT = 40
UFO_IMAGE = pygame.image.load(os.path.join("ufo.png"))
UFO = pygame.transform.scale(UFO_IMAGE, (UFO_WIDTH, UFO_HEIGHT))  # resize image
UFO_VEL = 5
UFO_HIT = pygame.USEREVENT + 1  # Create custom event

# BULLET CONSTANTS
BULLET_VEL = 7


def draw_window(space_ship, ufo, bullets, UFO_VEL):
    WIN.blit(BG_RESIZED, (0, 0))
    WIN.blit(SPACESHIP, (space_ship.x, space_ship.y))  # Insert one object to window
    WIN.blit(UFO, (ufo.x, ufo.y))

    for bul in bullets:
        pygame.draw.rect(WIN, WHITE, bul)

    pygame.display.update()  # update at maximum FPS, FUNDAMENTAL
    # IS THIS THE ISSUE? 


def spaceship_move(space_ship):
    keys_pressed = pygame.key.get_pressed()
    if keys_pressed[pygame.K_a] and space_ship.x > 10:  # LEFT
        space_ship.x -= SPACESHIP_VEL
    if keys_pressed[pygame.K_d] and space_ship.x < 390:  # RIGHT
        space_ship.x += SPACESHIP_VEL
    if keys_pressed[pygame.K_w] and space_ship.y > 500:  # UP
        space_ship.y -= SPACESHIP_VEL
    if keys_pressed[pygame.K_s] and space_ship.y < 640:  # DOWN
        space_ship.y += SPACESHIP_VEL


def handle_bullets(bullets, space_ship):
    for bul in bullets:
        bul.y -= BULLET_VEL
        if ufo.colliderect(bul):
            pygame.event.post(pygame.event.Event(UFO_HIT))
            bullets.remove(bul)
        if bul.y < 5:
            bullets.remove(bul)


def ufo_movement(ufo, UFO_VEL): # ISSUE HERE ##########
    ufo.x -= UFO_VEL
    if ufo.x <= 0:
        ufo.x += UFO_VEL


def main():
    space_ship = pygame.Rect(200, 640, SPACESHIP_WIDTH, SPACESHIP_HEIGHT)
    ufo = pygame.Rect(200, 30, UFO_WIDTH, UFO_HEIGHT) ######## DEFINING UFO OBJECT 
    bullets = []
    clock = pygame.time.Clock()  # Count FPS
    run = True
    while run:  # while run is true the game will stay open
        clock.tick(FPS)  # Ensure the frame rate doesn't go over FPS var
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    bullet = pygame.Rect(space_ship.x + space_ship.width // 2 - 5,
                                     space_ship.y + space_ship.height // 2, 10, 5)
                    bullets.append(bullet)

        ufo_movement(ufo, UFO_VEL) # CALLING AUTOMATIC BOUNCING

        draw_window(space_ship, ufo, bullets, UFO_VEL)
        spaceship_move(space_ship)
        handle_bullets(bullets, space_ship)

    pygame.quit()


if __name__ == "__main__":
    main()

【问题讨论】:

    标签: python loops pygame border collision


    【解决方案1】:

    你的代码的问题是它只向右移动一次并停止移动,以解决你应该添加一个移动方向

    你可以试试这个

    import os
    import pygame
    
    # WIN CONSTANTS
    WIDTH, HEIGHT = 500, 700
    WIN = pygame.display.set_mode(((WIDTH, HEIGHT)))
    pygame.display.set_caption("First Game!")
    
    # COLORS LIST
    WHITE = (255, 255, 255)
    BLACK = (0, 0, 0)
    FPS = 60
    
    # BACKGROUND IMAGE
    BG = pygame.image.load(os.path.join("spacebg.jpg"))
    BG_RESIZED = pygame.transform.scale(BG, (WIDTH, HEIGHT))
    
    # SPACESHIP CONSTANTS
    SPACESHIP_WIDTH = 100
    SPACESHIP_HEIGHT = 40
    SPACESHIP_IMAGE = pygame.image.load(os.path.join("spaceship.jpg"))
    # Resize image
    SPACESHIP = pygame.transform.scale(
        SPACESHIP_IMAGE, (SPACESHIP_WIDTH, SPACESHIP_HEIGHT))
    SPACESHIP_VEL = 10
    
    # UFO CONSTANTS
    UFO_WIDTH = 100
    UFO_HEIGHT = 40
    UFO_IMAGE = pygame.image.load(os.path.join("ufo.jpg"))
    UFO = pygame.transform.scale(
        UFO_IMAGE, (UFO_WIDTH, UFO_HEIGHT))  # resize image
    UFO_VEL = 5
    UFO_HIT = pygame.USEREVENT + 1  # Create custom event
    
    # BULLET CONSTANTS
    BULLET_VEL = 7
    
    
    def draw_window(space_ship, ufo, bullets, UFO_VEL):
        WIN.blit(BG_RESIZED, (0, 0))
        # Insert one object to window
        WIN.blit(SPACESHIP, (space_ship.x, space_ship.y))
        WIN.blit(UFO, (ufo.x, ufo.y))
    
        for bul in bullets:
            pygame.draw.rect(WIN, WHITE, bul)
    
        pygame.display.update()  # update at maximum FPS, FUNDAMENTAL
        # IS THIS THE ISSUE?
    
    
    def spaceship_move(space_ship):
        keys_pressed = pygame.key.get_pressed()
        if keys_pressed[pygame.K_a] and space_ship.x > 10:  # LEFT
            space_ship.x -= SPACESHIP_VEL
        if keys_pressed[pygame.K_d] and space_ship.x < 390:  # RIGHT
            space_ship.x += SPACESHIP_VEL
        if keys_pressed[pygame.K_w] and space_ship.y > 500:  # UP
            space_ship.y -= SPACESHIP_VEL
        if keys_pressed[pygame.K_s] and space_ship.y < 640:  # DOWN
            space_ship.y += SPACESHIP_VEL
    
    
    def handle_bullets(bullets, space_ship):
        for bul in bullets:
            bul.y -= BULLET_VEL
            if ufo.colliderect(bul):
                pygame.event.post(pygame.event.Event(UFO_HIT))
                bullets.remove(bul)
            if bul.y < 5:
                bullets.remove(bul)
    
    
    def ufo_movement(ufo, UFO_VEL, direction_left):
        if direction_left:
            ufo_left(ufo, UFO_VEL)
        else:
            ufo_right(ufo, UFO_VEL)
        direction_left = update_direction(ufo, direction_left)
        return direction_left
    
    
    def ufo_left(ufo, UFO_VEL):
        ufo.x -= UFO_VEL
    
    
    def ufo_right(ufo, UFO_VEL):
        ufo.x += UFO_VEL
    
    
    def update_direction(ufo, direction_left):
        if ufo.x <= 0:
            direction_left = False
        if ufo.x >= WIDTH-SPACESHIP_WIDTH:
            direction_left = True
    
        return direction_left
    
    
    def main():
        space_ship = pygame.Rect(200, 640, SPACESHIP_WIDTH, SPACESHIP_HEIGHT)
        ufo = pygame.Rect(200, 30, UFO_WIDTH, UFO_HEIGHT)  # DEFINING UFO OBJECT
        bullets = []
        clock = pygame.time.Clock()  # Count FPS
        run = True
    
        direction_left = True
        while run:  # while run is true the game will stay open
            clock.tick(FPS)  # Ensure the frame rate doesn't go over FPS var
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    run = False
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_SPACE:
                        bullet = pygame.Rect(space_ship.x + space_ship.width // 2 - 5,
                                             space_ship.y + space_ship.height // 2, 10, 5)
                        bullets.append(bullet)
    
            # CALLING AUTOMATIC BOUNCING
            direction_left = ufo_movement(ufo, UFO_VEL, direction_left)
    
            draw_window(space_ship, ufo, bullets, UFO_VEL)
            spaceship_move(space_ship)
            handle_bullets(bullets, space_ship)
    
        pygame.quit()
    
    
    if __name__ == "__main__":
        main()
    

    【讨论】:

    • 这终于完美运行了! pygame 处理 Rect 和 Sprites 的方式有什么不同吗?因为我发现了很多教程,我的代码足以反弹一个 Rect,但在这里我使用的是 Sprite (Rect = draw(), Sprite = blit()。对吗?
    • 我不确定这里的Rect and Sprites 是什么,我能看到任何代码吗?
    【解决方案2】:

    在全局命名空间中为不明飞行物的移动添加一个变量:

    ufo_move_x = UFO_VEL
    

    当不明飞行物撞击边界时更改ufo_move_x

    def ufo_movement(ufo, UFO_VEL):
        global ufo_move_x
    
        if ufo.left <= 0:
            ufo_move_x = UFO_VEL
        elif ufo.right >= 500:
            ufo_move_x = -UFO_VEL 
    
        ufo.x += ufo_move_x
    

    【讨论】:

    • @MatteoScalas 该代码对我来说很好。你忘了全球ufo_move_x吗?这是一个新问题吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-16
    • 1970-01-01
    • 2022-08-06
    相关资源
    最近更新 更多