1

I try to simulate a robot's movement using pygame. Robot gets speed and interval length from an RL algorithm. For example, The robot moves at a speed of 10 for 1 second, then at a speed of 10 for 2 seconds, and so on.

I try this method, but it didn't work.

current_time = pygame.time.get_tick()
while pygame.time.get_tick() <= current_time + interval_length:
        dx = bot_vel * dt
        rect.move(dx, 0)
        screen.fill((0,0,0))
        pygame.draw.rect(screen, (255,255,255), rect)
        pygame.display.flip()
m031n
  • 11
  • 3

1 Answers1

1

Do not try to control the object with a loop inside the application loop. Use the application loop.

You have to handle the events in the application loop. See pygame.event.get() respectively pygame.event.pump():

For each frame of your game, you will need to make some sort of call to the event queue. This ensures your program can internally interact with the rest of the operating system.

Use pygame.time.Clock to control the frames per second and thus the game speed.

The method tick() of a pygame.time.Clock object, delays the game in that way, that every iteration of the loop consumes the same period of time. See pygame.time.Clock.tick():

This method should be called once per frame.

pygame.time.Clock.tick returns the number of milliseconds since the last call. When you call it in the application loop, this is the number of milliseconds that have passed since the last frame. Multiply the objects speed by the elapsed time per frame to get constant movement regardless of FPS.

Define the distance in pixels that the player should move per second (move_per_second). Then compute the distance per frame in the application loop.

pygame.Rect.move doesn't change the Rect object itself, but it returns an new Rect object. This means, that

rect.move(dx, 0)

doesn't change anything. You've to assign the rectangle which is returned by .move to "itself":

rect = rect.move(dx, 0)

Alternatively you can use pygame.Rect.move_ip

rect.move_ip(dx, 0)

Minimal example:

import pygame

pygame.init()
screen = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()

rect = pygame.Rect(0, 250, 20, 20)
bot_vel = 500 # 500 pixel / second

run = True
while run:
    dt = clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False       

    dx = bot_vel * dt / 1000   
    rect.move_ip(dx, 0)
    if rect.x > screen.get_width():
        rect.x = 0
    
    screen.fill((0,0,0))
    pygame.draw.rect(screen, (255,255,255), rect)
    pygame.display.flip()

pygame.quit()
exit()
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • Thanks for the help. I can easily handle moving bot with pygame events like key pressed but I don't understand how to control the robot’s movement by different interval lengths using events. – m031n Jul 13 '21 at 21:14