How to fix character constantly accelerating in both directions after deceleration Pygame?

后端 未结 1 1053
梦谈多话
梦谈多话 2021-01-25 02:01

I was able to successfully implement acceleration into my Pygame game, but there is a bit of a problem. Problem is: After the character decelerates, the character will start acc

相关标签:
1条回答
  • 2021-01-25 02:56

    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
    

    See the 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
    
        keys = pygame.key.get_pressed()
        move_R = keys[pygame.K_RIGHT]
        move_L = keys[pygame.K_LEFT]
    
        # set acceleration in this frame
        accel = 0
        if move_R:
            accel += PLAYER_ACCEL
        if move_L:
            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()
    
    0 讨论(0)
提交回复
热议问题