Pygame KEYUP,KEYDOWN导致幻影移动

时间:2018-08-21 12:14:07

标签: python python-3.x pygame

我在学习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()

3 个答案:

答案 0 :(得分:1)

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

只需使用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。起初这可能不是一个大问题,但要记住一点。

答案 1 :(得分:0)

您需要的是将游戏变量(x,y,x_change,y_change)恢复为默认值,很可能是在崩溃后通过crash()函数。 pygame不会帮您这样做。

要么使变量成为全局变量,要么使用一些可变对象(例如字典)从其他方法访问它们。

答案 2 :(得分:0)

正如Daniel Kukiela所说,您可以将“ x_change”和“ y_change”变成全局变量,并在开始时将它们的值设置为0,据我所知,这是工作项目。

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
x_change = 0
y_change = 0

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
    global x_change
    x_change == 0
    global y_change
    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()