Greg Strydom
Greg Strydom

Reputation: 159

Python Pygame Loop Unusual delay

I seem to be really stuck at a certain point in my program and hope you can help.

I am basically trying to create a simple hit the moving image game. The image is being placed at one of a series of "up points" at random, and then the player needs to hit the image before the image is placed in a new location.

Everything seems to be going fine, but i seem to be getting a strange delay with pygame.tick or python time.sleep().

I would just like to say i am quite a python and pygame newbie, but for the life of me cant understand what is going wrong. From my understanding so far, the image should be moving to the new location at regular 1s intervals.

But instead the program seems to "hang" or "get delayed" sometimes, and the image seems stuck in place for quite a few seconds then rush back and forth as if trying to catch up, then the program will seem to work for what seems to be fine for a few seconds (regular 1s delay), and then go back to struggling to move or keep up.

Hopefully that makes sense :) Hers is the code with the loop so you can see where i think i am having the problem:

# The values are tuples which hold the top-left x, y co-ordinates at which the  
# rabbit image is to be blitted...

uppoints = {1: (70, 70), 2: (250, 70), 3: (430, 70), 4: (600, 70),
        5: (70, 250), 6: (250, 250), 7: (430, 250), 8: (600, 250),
        9: (70, 430), 10: (250, 430), 11: (430, 430), 12: (600, 430)}


# Get a random location to pop up...
def getpos(ups):
    x = random.randint(1, 2)
    if x == 1:
        up = ups[1]
        return up
    elif x == 2:
        up = ups[2]
        return up

uppos = ()

while gamerunning:
    uppos = getpos(uppoints)

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

            if event.type == pygame.MOUSEMOTION:
                mpos = pygame.mouse.get_pos()

            if event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:
                    if rabbits.rect.collidepoint(event.pos):
                        score += 10

    mainwin.fill((0, 0, 0))
    scoretxt2 = basefont.render(str(score), True, (0, 0, 0))
    mainwin.blit(mainback, (0, 0))
    mainwin.blit(rabbits.image, uppos)
    mainwin.blit(scoretxt, (70, 30))
    mainwin.blit(scoretxt2, (160, 32))
    mainwin.blit(livestxt, (600, 30))
    mainwin.blit(livestxt2, (690, 32))

    pygame.display.flip()

    time.sleep(1)

    # Check which level the user is by score, and increase the speed of the rabbits  as needed...
    fpsclock.tick(60)

If i use the time.sleep, the game runs at what seems to be the right pace of blitting at 1s intervals. If i ommit time.sleep() and use .tick(60), the images blit frantically but i am sure i can still see some sort of delay.

I tried doing a bit of googling and found a few pages saying there is a problem with both pygame's .tick() method and python sleep() method but could not find out if this was true.

I honestly have no idea what ive done wrong here so hope you can help :)

Thanks alot!

Upvotes: 2

Views: 171

Answers (1)

Blckknght
Blckknght

Reputation: 104712

Your time.sleep and fpsclock.tick calls somewhat contradict each other. The call to sleep tells Python to stop for a full second, doing nothing. The tick call, on the other hand, says that you want to be running at 60 frames per second.

I suspect that you don't want to use sleep. While the program is sleeping, not IO events will be processed and the program will appear to be hung. Instead, you need to change the rest of your code so that it behaves properly when updating more than once a second.

I think you probably want to change the place where you call getpos to only do so once a second. I suggest something like:

ms = 0

while gamerunning:
    ms += fpsclock.get_time()
    if ms > 1000: # 1000 ms is one second
        ms -= 1000
        uppos = getpos(uppoints)

    # ...

Upvotes: 2

Related Questions