The acceleration depends on the input only, if there is no input, the acceleration is zero:
accel = 0
if move_R:
accel += PLAYER_ACCEL
if move_L:
accel -= PLAYER_ACCEL
The velocity changes by the acceleration, but it is reduced by the friction.
veloc = (veloc + accel) * (1 - PLAYER_FRICT)
Note, at a certain point, the acceleration can not compensate the friction. The complete acceleration energy is consumed by the friction.
If veloc / (veloc + accel)
is equal 1 - PLAYER_FRICT
, the movement is uniform.
The position of the player changes by the current velocity:
player_xy[0] += veloc
Minimal example:
import pygame
pygame.init()
size = 500, 500
window = pygame.display.set_mode(size)
clock = pygame.time.Clock()
border = pygame.Rect(0, 0, size[0]-40, 100)
border.center = [size[0] // 2, size[1] // 2]
player_xy = [size[0] // 2, size[1] // 2]
radius = 10
PLAYER_ACCEL, PLAYER_FRICT = 0.5, 0.02
veloc = 0
run = True
while run:
clock.tick(120)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# set acceleration in this frame
accel = 0
keys = pygame.key.get_pressed()
if keys[pygame.K_RIGHT]:
accel += PLAYER_ACCEL
if keys[pygame.K_LEFT]:
accel -= PLAYER_ACCEL
# change velocity by acceleration and reduce dependent on friction
veloc = (veloc + accel) * (1 - PLAYER_FRICT)
# change position of player by velocity
player_xy[0] += veloc
if player_xy[0] < border.left + radius:
player_xy[0] = border.left + radius
veloc = 0
if player_xy[0] > border.right - radius:
player_xy[0] = border.right - radius
veloc = 0
window.fill(0)
pygame.draw.rect(window, (255, 0, 0), border, 1)
pygame.draw.circle(window, (0, 255, 0), (round(player_xy[0]), round(player_xy[1])), radius)
pygame.display.flip()
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…