1

I'm currently creating a program where a circle will move to the left, stay for 3 seconds, and then move to the right of the screen. However, when trying to implement this solution there: In PyGame, how to move an image every 3 seconds without using the sleep function?, it does not work. I would appreciate if somebody can tell me what am I doing.

Here's my code:

import pygame, sys, time, random
from pygame.locals import *

currentPosition = [300, 368]

def moveLeft():
    currentPosition[0] -= 1

def moveRight():
    currentPosition[0] += 1


pygame.init()

windowCalibration = pygame.display.set_mode((0,0))

WHITE = (255, 255, 255)



windowCalibration.fill(WHITE)

pygame.display.set_caption("Eye calibration")
pygame.draw.circle(windowCalibration, (0,0,0), currentPosition, 10)
done = False

circleIsIdle = True

clock = pygame.time.Clock()

time_counter = 0

def stopCircle():
    circleIsIdle = True
    while circleIsIdle:
        time_counter = clock.tick()
        if time_counter > 3000:
            time_counter = 0
            circleIsIdle = False

while not done:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                done = True
    while currentPosition[0] >= 10:
        moveLeft()
        windowCalibration.fill(WHITE)
        pygame.draw.circle(windowCalibration, (0,0,0), currentPosition, 10)
        pygame.display.update()
    stopCircle()

    while currentPosition[0] <= 1350:
        moveRight()
        windowCalibration.fill(WHITE)
        pygame.draw.circle(windowCalibration, (0,0,0), currentPosition, 10)
        pygame.display.update()
    stopCircle()
    done = True        
TimBluesWin
  • 33
  • 1
  • 8
  • I think you forgot the `+=` in `time_counter = clock.tick()` – Mercury Platinum Apr 09 '19 at 11:38
  • in `while not done` you should use `pygame.display.update()` only once - at the end of loop. This way it should run smoother. But problem is `while circleIsIdle:` which stops `while not done` and it can't check if you press `ESC`. In game you shouldn't use other `while` which takes longer time. – furas Apr 09 '19 at 15:03
  • Thanks @Pygasm. That fixed my problem. – TimBluesWin Apr 09 '19 at 15:22

1 Answers1

1

Inside while not done you shouldn't use other while which takes longer time. It stops while not done and it can't check if you pressed ESC, etc.

You should rather use pygame.time.get_ticks() to get current time and use it to control which element move or draw.

I also use state to see if I move left or right or I wait before move left or right. This way I can do different things - I can move or not, I can draw or not (ie. if I have button "Pause" I could use state_pause to draw or not this button).

This code runs while not done all time so you can always exit using ESC. You can also move second circle even when first circle is waiting.

import pygame

# --- constants ---

WHITE = (255, 255, 255)
BLACK = (  0,   0,   0)

# --- classes ---

# empty

# --- functions ---

def moveLeft():
    currentPosition[0] -= 1

def moveRight():
    currentPosition[0] += 1
# --- main ---

pygame.init()

windowCalibration = pygame.display.set_mode((0,0))
pygame.display.set_caption("Eye calibration")

currentPosition = [300, 368]
state = 'move_left'
wait_to = 0

done = False
while not done:

    # --- events ---
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                done = True

    # --- moves ---

    if state == 'move_left':
        if currentPosition[0] >= 10:
            moveLeft()
        else:
            state = 'wait_before_move_right'
            wait_to = pygame.time.get_ticks() + 3000

    elif state == 'move_right':
        if currentPosition[0] <= 1350:
            moveRight()
        else:
            state = 'wait_before_move_left'
            wait_to = pygame.time.get_ticks() + 3000

    elif state == 'wait_before_move_right':
        current_time = pygame.time.get_ticks()
        if current_time > wait_to:
            state = 'move_right'

    elif state == 'wait_before_move_left':
        current_time = pygame.time.get_ticks()
        if current_time > wait_to:
            state = 'move_left'

    # --- draws ----

    windowCalibration.fill(WHITE)
    pygame.draw.circle(windowCalibration, BLACK, currentPosition, 10)
    pygame.display.update()

# --- end ---
pygame.quit()

EDIT: this code moves 3 circles at the same time, they wait before they change direction and it doesn't stops other circles, and you can use ESC in any moment.

import pygame

# --- constants ---

WHITE = (255, 255, 255)
BLACK = (  0,   0,   0)
RED   = (255,   0,   0)
GREEN = (  0, 255,   0)
BLUE  = (  0,   0, 255)

# --- classes ---

# empty

# --- functions ---

# empty

# --- main ---

pygame.init()

windowCalibration = pygame.display.set_mode((0,0))
pygame.display.set_caption("Eye calibration")

circles = [
    {'pos': [300, 368], 'speed': 1, 'state': 'move_left', 'wait_to': 0, 'color': RED},
    {'pos': [300, 268], 'speed': 10, 'state': 'move_right', 'wait_to': 0, 'color': GREEN},
    {'pos': [300, 168], 'speed': 30, 'state': 'move_right', 'wait_to': 0, 'color': BLUE},
]

done = False
while not done:

    # --- events ---
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                done = True

    # --- moves ---

    current_time = pygame.time.get_ticks()

    for circle in circles:
        if circle['state'] == 'move_left':
            if circle['pos'][0] >= 10:
                circle['pos'][0] -= circle['speed']
            else:
                circle['pos'][0] = 10
                circle['state'] = 'wait_before_move_right'
                circle['wait_to'] = pygame.time.get_ticks() + 3000

        elif circle['state'] == 'move_right':
            if circle['pos'][0] <= 1350:
                circle['pos'][0] += circle['speed']
            else:
                circle['pos'][0] = 1350
                circle['state'] = 'wait_before_move_left'
                circle['wait_to'] = pygame.time.get_ticks() + 3000

        elif circle['state'] == 'wait_before_move_right':
            if current_time > circle['wait_to']:
                circle['state'] = 'move_right'

        elif circle['state'] == 'wait_before_move_left':
            if current_time > circle['wait_to']:
                circle['state'] = 'move_left'

    # --- draws ----

    windowCalibration.fill(WHITE)

    for circle in circles:
        pygame.draw.circle(windowCalibration, circle['color'], circle['pos'], 10)

    pygame.display.update()

# --- end ---

pygame.quit()
furas
  • 134,197
  • 12
  • 106
  • 148
  • Big thanks for your detailed code. I want to make the circle move automatically, but regardless I think your code will help me to improve my program. – TimBluesWin Apr 11 '19 at 04:55