首页 > 解决方案 > Pygame KEYUP, KEYDOWN 导致幽灵移动

问题描述

我尝试学习 KEYUP 和 KEYDOWN。基本上,在用户撞到窗口的任何一侧后,游戏会按预期重置。即使没有按下或释放任何键,方块也不会再次开始移动。

理想的事件系列: - 用户崩溃 - 游戏在原始起始药水(静止)中以正方形重置 - 按下移动键并移动

任何关于为什么会发生这种情况的见解都会很棒。

谢谢

import pygame
import time

pygame.init()

display_width = 800
display_height = 600

black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)

car_width = 75

gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('A bit Racey')
clock = pygame.time.Clock()


def text_objects(text, font):
    textSurface = font.render(text, True, black)
    return textSurface, textSurface.get_rect()


def message_display(text):
    largeText = pygame.font.Font('freesansbold.ttf', 115)
    TextSurf, TextRect = text_objects(text, largeText)
    TextRect.center = ((display_width / 2), (display_height / 2))
    gameDisplay.blit(TextSurf, TextRect)

    pygame.display.update()

    time.sleep(2)

    game_loop()


def crash():
    message_display('You Crashed')


def game_loop():
    x = 200
    y = 200

    x_change = 0
    y_change = 0

    gameExit = False

    while not gameExit:

        # Movement logic
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RIGHT:
                    x_change += 5
                if event.key == pygame.K_LEFT:
                    x_change += -5

            if event.type == pygame.KEYUP:
                if event.key == pygame.K_RIGHT:
                    x_change += -5
                if event.key == pygame.K_LEFT:
                    x_change += 5

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_UP:
                    y_change += -5
                if event.key == pygame.K_DOWN:
                    y_change += 5

            if event.type == pygame.KEYUP:
                if event.key == pygame.K_UP:
                    y_change += 5
                if event.key == pygame.K_DOWN:
                    y_change += -5

        x += x_change
        y += y_change

        gameDisplay.fill(white)
        pygame.draw.rect(gameDisplay, red, [x, y, 75, 75])

        # Check if border hit
        if x > display_width - car_width or x < 0:
            crash()
        if y > display_height - car_width or y < 0:
            crash()

        pygame.display.update()
        clock.tick(60)


game_loop()
pygame.quit()
quit()

标签: pythonpython-3.xpygame

解决方案


拧全局变量、事件和大量标志。

只需用于pygame.key.get_pressed获取键盘的当前状态。为每个箭头键分配一个移动矢量,将它们相加,标准化,然后就可以了。

另外,如果你想用矩形做一些事情,只需使用Rect类。它会让你的生活轻松很多。

这是一个正在运行的示例:

import pygame
import time

pygame.init()

display_width = 800
display_height = 600

black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)

car_width = 75

gameDisplay = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('A bit Racey')
clock = pygame.time.Clock()


def text_objects(text, font):
    textSurface = font.render(text, True, black)
    return textSurface, textSurface.get_rect()


def message_display(text):
    largeText = pygame.font.Font('freesansbold.ttf', 115)
    TextSurf, TextRect = text_objects(text, largeText)
    TextRect.center = ((display_width / 2), (display_height / 2))
    gameDisplay.blit(TextSurf, TextRect)

    pygame.display.update()

    time.sleep(2)

    game_loop()


def crash():
    message_display('You Crashed')

keymap = {
    pygame.K_RIGHT: pygame.math.Vector2(1, 0),
    pygame.K_LEFT: pygame.math.Vector2(-1, 0),
    pygame.K_UP: pygame.math.Vector2(0, -1),
    pygame.K_DOWN: pygame.math.Vector2(0, 1)
}

def game_loop():

    # we want to draw a rect, so we simple use Rect
    rect = pygame.rect.Rect(200, 200, 75, 75)

    gameExit = False

    while not gameExit:

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

        # get the state of the keyboard
        pressed = pygame.key.get_pressed()
        # get all the direction vectors from the keymap of all keys that are pressed
        vectors = (keymap[key] for key in keymap if pressed[key])
        # add them up to we get a single vector of the final direction
        direction = pygame.math.Vector2(0, 0)
        for v in vectors:
            direction += v

        # if we have to move, we normalize the direction vector first
        # this ensures we're always moving at the correct speed, even diagonally
        if direction.length() > 0:
            rect.move_ip(*direction.normalize()*5)

        gameDisplay.fill(white)
        pygame.draw.rect(gameDisplay, red, rect)

        # Check if border hit
        # See how easy the check is
        if not gameDisplay.get_rect().contains(rect):
            crash()

        pygame.display.update()
        clock.tick(60)


game_loop()
pygame.quit()
quit()

您的代码还有其他一些问题:

例如,如果您使用time.sleep(2),您的整个程序将冻结。这意味着您不能在等待时关闭窗口,并且窗口管理器等不会重绘窗口。

此外,您的代码包含一个无限循环。如果你经常碰壁,你会遇到堆栈溢出,因为game_loop调用crash又会game_loop再次调用。起初这可能不是一个大问题,但要记住一些事情。


推荐阅读