How do i get my character to accelerate and decelerate instead of just moving with a certain velocity (in pygame)?

Viewed 35

Can someone tell me what to change so that my ship uses thrust mechanics instead of static movement like it does now?

I want the movement to be like in asteroids, where it accelerates in the direction you're facing and the velocity caps off at some point, then if you stop accelerating, it's velocity slowly decreases until it stops.

rn if I press the forward button it just starts moving with its max velocity directly and stops immediately when I let go.

This is the code for my ship class

class Ship:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = 0
        self.vel = 0
        self.angle = 0

    def draw(self):
        ship_img = pygame.image.load("sprites/ship_off.png")
        ship_img_copy = pygame.transform.rotate(ship_img, self.angle)
        window.blit(ship_img_copy,
                    (self.x - (ship_img_copy.get_width()) / 2, self.y - (ship_img_copy.get_height()) / 2))

        keys = pygame.key.get_pressed()

        if keys[pygame.K_w]:
            ship_img = pygame.image.load("sprites/ship_on.png")
            ship_img_copy = pygame.transform.rotate(ship_img, self.angle)
            window.blit(ship_img_copy,
                        (self.x - (ship_img_copy.get_width()) / 2, self.y - (ship_img_copy.get_height()) / 2))

    def move(self):
        keys = pygame.key.get_pressed()
        # todo acceleration and thrust mechanics
        if keys[pygame.K_w]:
            self.x += self.vel * cos(self.angle * (pi / 180) + (90 * pi / 180))
            self.y -= self.vel * sin(self.angle * (pi / 180) + 90 * (pi / 180))
            # So that if it leaves one side it comes from the other
            if self.y < 0:
                self.y = (self.y - self.vel) % 600

            elif self.y > 600:
                self.y = (self.y + self.vel) % 600

            elif self.x < 0:
                self.x = (self.x - self.vel) % 800

            elif self.x > 800:
                self.x = (self.x + self.vel) % 800

        if keys[pygame.K_a]:
            self.angle += 7

        if keys[pygame.K_d]:
            self.angle -= 7

I've tried but I couldn't do it, so here's my code

1 Answers

You have to change self.vel when w or s is pressed, but you have to change self.x and self.y in every frame, dependent on self.vel:

class Ship:
    def __init__(self, x, y):
        # [...] 

        self.vel = 0
        self.max_vel = 10

    # [...]

    def move(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_w]:
            self.vel = min(self.vel+1, self.max_vel)
        if keys[pygame.K_s]:
            self.vel = max(self.vel-1, 0)

        if keys[pygame.K_a]:
            self.angle += 7
        if keys[pygame.K_d]:
            self.angle -= 7

        self.x += self.vel * cos(self.angle * (pi / 180) + (90 * pi / 180))
        self.y -= self.vel * sin(self.angle * (pi / 180) + 90 * (pi / 180))
        if self.y < 0:
            self.y = (self.y - self.vel) % 600
        elif self.y > 600:
            self.y = (self.y + self.vel) % 600
        elif self.x < 0:
            self.x = (self.x - self.vel) % 800
        elif self.x > 800:
            self.x = (self.x + self.vel) % 800
Related