Friction in pygame

Viewed 96

for my platformer game i want to make it so when it moves it slowly slows down. i tried to do it a couple ways but it didn't work it just stays on spot. can someone help me?

class Player(pygame.sprite.Sprite):

    def __init__(self, game):
        pygame.sprite.Sprite.__init__(self)
        self.game = game
        self.speedx = 0
        self.speedy = 0
        self.alive = True

        self.image = pygame.Surface((30, 40))
        self.image.fill(YELLOW)
        self.rect = self.image.get_rect()
        self.rect.bottom = HEIGHT - 10
        self.rect.centerx = WIDTH / 2

    def update(self):
        self.speedx = 0
        self.speedy = 0
        key_pressed = pygame.key.get_pressed()
        if key_pressed[pygame.K_a]:
            self.speedx = -10
        elif key_pressed[pygame.K_d]:
            self.speedx = 10
        if key_pressed[pygame.K_SPACE]:
            self.speedy = -10

        self.speedx += self.rect.x
        self.speedx *= FRICTION
        self.speedy += self.rect.y

        if self.rect.left < 0:
            self.rect.x = 0
        elif self.rect.right > WIDTH:
            self.rect.right = WIDTH
1 Answers

Personally, I prefer calculating friction like that:

  • If a key is pressed, I add, let's say 3000 pixels per second to the speed
  • Every frame, I slow down the sprite by multiplying the speed by a number very close to 1, like for example 0.95 when the game runs at 100 frames per second.

By using this technique, if you make the sprite move, it will accelerate more and more quickly. And if you stop moving it, it will slow down smoothly. Also, if you make the sprite move to the left while it is still moving right, it will "turn around" quicker.

You can mess aorund with the values: if you increase the first number, the speed will increase. If the second number is closer to 1, the friction is less significant.


Here is how to code this, when running at 100 frames per second:

The x_speed variable is in pixels per second. Simply divide it by 100 to get it in pixels per frame.

# in the game loop

pressed = pygame.key.get_pressed()
if pressed[K_RIGHT]:
    x_speed += 30
if pressed[K_LEFT]:
    x_speed -= 30

x_speed *= 0.95

Here is how to use it, in order to run the game at any framerate (you just need a variable, time_passed, which corresponds to the time spent on a frame, in seconds: you can use pygame.time.Clock().

The x_speed variable is in pixels per second.

# in the game loop

pressed = pygame.key.get_pressed()
if pressed[K_RIGHT]:
    x_speed += 3000 * time_passed
if pressed[K_LEFT]:
    x_speed -= 3000 * time_passed

x_speed *= 0.95**(100 * time_passed)

Runnable Minimal, Reproducible Example:

Related