在 Pygame 中实现二维空间中的平滑运动

2023-12-06

我想实现平滑的运动,加速到最大速度,然后在不按下任何键的情况下缓慢减速,类似于小行星中太空飞船的运动。这是我当前的运动代码:

import pygame

pygame.init()

display = pygame.display.set_mode((640, 480))

clock = pygame.time.Clock()

GRAY = pygame.Color('gray12')

display_width, display_height = display.get_size()

x = display_width * 0.45
y = display_height * 0.8

x_change = 0
y_change = 0
accel_x = 0
accel_y = 0
max_speed = 6

sign = lambda a: (a > 0) - (a < 0)

crashed = False
while not crashed:
    keys = pygame.key.get_pressed()

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            crashed = True
        if event.type == pygame.KEYDOWN:
            # Set the acceleration value.
            if event.key == pygame.K_LEFT:
                print('left')
                accel_x = -.2
            if event.key == pygame.K_RIGHT:
                print('right')
                accel_x = .2
            if event.key == pygame.K_DOWN:
                print('down')
                accel_y = .2
            if event.key == pygame.K_UP:
                print('up')
                accel_y = -.2
        if event.type == pygame.KEYUP:
            if event.key in (pygame.K_LEFT, pygame.K_RIGHT, pygame.K_UP, pygame.K_DOWN):
                print('key up')
                accel_x = 0
                accel_y = 0

    x_change += accel_x  # Accelerate.
    y_change += accel_y

    if abs(x_change) >= max_speed:  # If max_speed is exceeded.
        # Normalize the x_change and multiply it with the max_speed.
        x_change = sign(x_change) * max_speed

    if abs(y_change) >= max_speed:  # If max_speed is exceeded.
        # Normalize the y_change and multiply it with the max_speed.
        y_change = sign(y_change) * max_speed

    # Decelerate if no key is pressed.
    if accel_x == 0:
        x_change *= 0.98

    if accel_y == 0:
        y_change *= 0.98

    x += x_change  # Move the object.
    y += y_change

    display.fill(GRAY)
    pygame.draw.rect(display, (0, 120, 250), (x, y, 20, 40))

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

当单独按下箭头键时,运动效果完美,但是如果快速连续按下 2 个键,则记录第二个键,但对象没有运动。我尝试过使用创建键列表pygame.key.get_pressed()并将当前动作与列表中按下的键进行比较,但这并不能解决问题。


The major issue in your code is, that when you press and LEFT, then press and hold RIGHT and finally release LEFT, the resulting states of accel_x and accel_y are both 0, because the last event that happend was pygame.KEYUP.

我建议评估以下状态pygame.key.get_pressed()而不是使用关键事件:

  • If UP is pressed and DOWN is not pressed, the increment y_change up to its maximum (y_change = max(y_change-0.2, -max_speed)).
  • If UP is not pressed and DOWN is pressed, the decrement y_change down to its minimum (y_change = min(y_change+0.2, max_speed)).
  • 如果同时按下两个键或没有按下任何一个键,则降低速度(y_change *= 0.98).

Apply the same principle to x_change, when the keys LEFT and/or RIGHT are pressed:

crashed = False
while not crashed:

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

    keys = pygame.key.get_pressed()

    # handle left and right movement
    if keys[pygame.K_LEFT] and not keys[pygame.K_RIGHT]:
        x_change = max(x_change-0.2, -max_speed)
    elif keys[pygame.K_RIGHT] and not keys[pygame.K_LEFT]:
        x_change = min(x_change+0.2, max_speed)
    else:
        x_change *= 0.98

    # handle up and down movement
    if keys[pygame.K_UP] and not keys[pygame.K_DOWN]:
        y_change = max(y_change-0.2, -max_speed)
    elif keys[pygame.K_DOWN] and not keys[pygame.K_UP]:
        y_change = min(y_change+0.2, max_speed)
    else:
        y_change *= 0.98

    x += x_change  # Move the object.
    y += y_change

    display.fill(GRAY)
    pygame.draw.rect(display, (0, 120, 250), (x, y, 20, 40))

    pygame.display.update()
    clock.tick(60)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Pygame 中实现二维空间中的平滑运动 的相关文章

随机推荐