问题描述
我想实现平滑运动,加速到最大速度,然后在没有按下任何键的情况下缓慢减速,类似于小行星中太空船的运动.这是我当前的运动代码:
导入pygamepygame.init()display = pygame.display.set_mode((640, 480))时钟 = pygame.time.Clock()灰色 = pygame.Color('gray12')display_width, display_height = display.get_size()x = display_width * 0.45y = 显示高度 * 0.8x_change = 0y_change = 0加速度_x = 0加速度_y = 0最大速度 = 6符号 = lambda a: (a > 0) - (a = max_speed: # 如果超过 max_speed.# 标准化 x_change 并将其与 max_speed 相乘.x_change = 符号(x_change)* max_speedif abs(y_change) >= max_speed: # 如果超过 max_speed.# 规范化 y_change 并将其与 max_speed 相乘.y_change = sign(y_change) * max_speed# 如果没有按下任何键,则减速.如果 accel_x == 0:x_change *= 0.98如果 accel_y == 0:y_change *= 0.98x += x_change # 移动对象.y += y_change显示.填充(灰色)pygame.draw.rect(显示, (0, 120, 250), (x, y, 20, 40))pygame.display.update()时钟滴答(60)pygame.quit()
当单独按下箭头键时,运动效果很好,但是如果快速连续按下 2 个键,第二个键被注册,但对象没有运动.我尝试使用 pygame.key.get_pressed()
制作按键列表,并将当前动作与列表中按下的按键进行比较,但这并没有解决问题.
您的代码中的主要问题是,当您按下 时,然后按住 最后释放,结果accel_x
和accel_y
的状态都是0,因为最后发生的事件是pygame.KEYUP
.
我建议评估
crashed = False虽然没有崩溃:对于 pygame.event.get() 中的事件:如果 event.type == pygame.QUIT:坠毁 = 真键 = pygame.key.get_pressed()# 处理左右移动如果keys[pygame.K_LEFT]而不是keys[pygame.K_RIGHT]:x_change = max(x_change-0.2, -max_speed)elif 键[pygame.K_RIGHT] 而不是键[pygame.K_LEFT]:x_change = min(x_change+0.2, max_speed)别的:x_change *= 0.98# 处理上下运动如果keys[pygame.K_UP]而不是keys[pygame.K_DOWN]:y_change = max(y_change-0.2, -max_speed)elif 键[pygame.K_DOWN] 而不是键[pygame.K_UP]:y_change = min(y_change+0.2, max_speed)别的:y_change *= 0.98x += x_change # 移动对象.y += y_change显示.填充(灰色)pygame.draw.rect(显示, (0, 120, 250), (x, y, 20, 40))pygame.display.update()时钟滴答(60)
I want to implement smooth motion that accelerates up to max speed and then decelerates slowly if no keys are pressed, similar to the motion of the space ship in asteroid. Here is my current code for the movement:
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()
When pressing the arrow keys individually the motion works perfectly, however if pressing 2 keys in rapid succession, the second key is registered but there is no motion from the object. I've tried making a list of keys using pygame.key.get_pressed()
and comparing the current motion with the key pressed in the list, however this didn't solve the problem.
The major issue in your code is, that when you press and , then press and hold and finally release , the resulting states of accel_x
and accel_y
are both 0, because the last event that happend was pygame.KEYUP
.
I recommend to evaluate the states of pygame.key.get_pressed()
rather than to use the key events:
- If is pressed and is not pressed, the increment
y_change
up to its maximum (y_change = max(y_change-0.2, -max_speed)
). - If is not pressed and is pressed, the decrement
y_change
down to its minimum (y_change = min(y_change+0.2, max_speed)
). - If both keys are pressed simultaneously or no one of them is pressed, then decrease the speed (
y_change *= 0.98
).
Apply the same principle to x_change
, when the keys and/or 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)
这篇关于在 Pygame 中实现二维空间中的平滑运动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!