【问题标题】:Pygame KEYUP, KEYDOWN causing ghost movementPygame KEYUP, KEYDOWN 导致幽灵移动
【发布时间】:2018-08-21 12:14:07
【问题描述】:

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

【问题讨论】:

    标签: python python-3.x pygame


    【解决方案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,而crash 又再次调用game_loop。起初这可能不是什么大问题,但要牢记。

    【讨论】:

      【解决方案2】:

      您需要将游戏变量 (x, y, x_change, y_change) 设置回默认值,很可能在崩溃后的 crash() 函数中。 pygame 不会为你这样做。

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

      【讨论】:

        【解决方案3】:

        正如 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()
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-09-13
          • 2014-02-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多