Ad

How Can I Get Smooth Movement In Pygame?

- 1 answer

How can I make my character move smoothly in pygame? When I create a regular program I seem to be able to get smooth movement by decreasing the velocity (how far the character moves for each step) and decreasing the time delay so that it quickly moves small steps.

The code for that could look something like this (here I just have a simple rectangle moving across the screen.

import pygame

pygame.init()

win = pygame.display.set_mode((500, 500))

x = 400
y = 400
width = 60
height = 60
vel = 2

run = True

while run:
    pygame.time.delay(10)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    keys = pygame.key.get_pressed()

    if keys[pygame.K_LEFT] and x > vel:
        x -= vel

    if keys[pygame.K_RIGHT] and x < 500 - width - vel:
        x += vel

    win.fill((0, 0, 0))
    pygame.draw.rect(win, (255, 0, 0), (x, y, width, height))
    pygame.display.update()

pygame.quit()

However, when I tried to make the game object-oriented I didn't get the character to move smoothly. The code for that looks like this. What am I doing wrong?

import pygame

pygame.init()

win = pygame.display.set_mode((500, 500))

class player():
    def __init__(self, x, y, width, height):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.vel = 2
        self.left = False
        self.right = False

    def draw(self):
        pygame.draw.rect(win, (255, 0, 0), (man.x, man.y, man.height, man.width))
        if self.left:
            pygame.draw.rect(win, (255, 0, 0), (man.x, man.y, man.height, man.width))
        elif self.right:
            pygame.draw.rect(win, (255, 0, 0), (man.x, man.y, man.height, man.width))


def re_draw():
    win = pygame.display.set_mode((500, 500))
    man.draw()
    pygame.display.update()


man = player(400, 400, 60, 60)

run = True


while run:
        pygame.time.delay(10)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False

        keys = pygame.key.get_pressed()

        if keys[pygame.K_LEFT] and man.x > man.vel:
            man.x -= man.vel
            man.left = True
            man.right = False

        elif keys[pygame.K_RIGHT] and man.x < 500 - man.width - man.vel:
            man.x += man.vel
            man.left = False
            man.right = True

        re_draw()

pygame.quit()
Ad

Answer

Instead of using pygame.time.delay, you can use clock.tick.

import pygame

pygame.init()

win = pygame.display.set_mode((500, 500))

class player():
    def __init__(self, x, y, width, height):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.vel = 2
        self.left = False
        self.right = False

    def draw(self):
        pygame.draw.rect(win, (255, 0, 0), (man.x, man.y, man.height, man.width))
        if self.left:
            pygame.draw.rect(win, (255, 0, 0), (man.x, man.y, man.height, man.width))
        elif self.right:
            pygame.draw.rect(win, (255, 0, 0), (man.x, man.y, man.height, man.width))


def re_draw():

    man.draw()
    pygame.display.update()


man = player(400, 400, 60, 60)

run = True
clock = pygame.time.Clock()

while run:

        win.fill((0, 0, 0)) # fill the window with your desired color
        # pygame.time.delay(10) use clock.tick instead

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False

        keys = pygame.key.get_pressed()

        if keys[pygame.K_LEFT] and man.x > man.vel:
            man.x -= man.vel
            man.left = True
            man.right = False

        elif keys[pygame.K_RIGHT] and man.x < 500 - man.width - man.vel:
            man.x += man.vel
            man.left = False
            man.right = True

        man.draw() # this might be better

        pygame.display.update()

        clock.tick(60) 

pygame.quit()

Hope this helps and welcome to StackOverflow.

Ad
source: stackoverflow.com
Ad