pygame.display.update() causing periodic lag spikes - python

I made a simple program with Pygame that was basically a scrolling background and noticed periodic lag spikes. After messing with the code for a long time, I found out that calls to pygame.display.update() would sometimes take a lot longer to execute.
To really strip down and replicate the problem, I wrote the following piece of code:
import pygame
import sys
import time
FRAME_RATE = 30
# don't mind the screen and time_passed variables; they aren't used in this script
def run_game():
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((500, 500))
prev_spike = 0
time_passed = 0
while 1:
start = time.clock()
pygame.display.update()
timenow = time.clock()
time_spent = timenow - start
if time_spent > 0.01:
print time_spent
if prev_spike:
print "Last spike was: {} seconds ago".format(timenow - prev_spike)
prev_spike = timenow
time_passed = clock.tick(FRAME_RATE)
if __name__ == "__main__":
run_game()
A snippet of output at that framerate:
0.0258948412828
Last spike was: 1.01579813191 seconds ago
0.0186809297657
Last spike was: 0.982841934526 seconds ago
0.0225958783907
Last spike was: 2.01697784257 seconds ago
0.0145269648427
Last spike was: 1.01603407404 seconds ago
0.0186094554386
Last spike was: 2.01713885195 seconds ago
0.0283046020628
Last spike was: 1.03270104172 seconds ago
0.0223322687757
Last spike was: 1.01709735072 seconds ago
0.0152536205013
Last spike was: 1.01601639759 seconds ago
I've really no clue what's going on, and would really love some insight.
Some more details:
A snippet of the output when printing the time_spent in every loop iteration (instead of only when it was > 0.01):
0.000204431946257
0.000242090462673
0.000207890381438
0.000272447838151
0.000230178074828
0.0357667523718 <-- update taking two orders of magnitude longer than normal
0.000293582719813
0.000343153624075
0.000287818661178
0.000249391603611
When run at 60 FPS, the interval between each spike almost always be 1 second, very rarely 2 seconds (and the spikes would last about twice as long). At lower frame rates, the interval between spikes would start to vary more, but would always be close to a whole number in value.
I tried running the script on another computer, but the problem wasn't replicated; the execution time on pygame.display.update() was reasonably quick and consistent. However, when I ran my original program on that machine, the one-second-interval lag spikes remained (I'll probably look for other machines to test on...)
Both machines that I tested on ran Windows 7.
EDIT:
I grabbed a few random games hosted on the Pygame website and I'm getting similar behaviour - calls to pygame.display.update (or flip) periodically take between 10 - 40 ms, whereas they normally take less than 2 ms.
Nobody else seems to be having this problem (or complaining about, at it least. That could be because most games run on less than 30 FPS where this issue isn't too noticeable), so there's likely something off with my environment. I did (kinda) reproduce the issue on a second machine though (as described above), so I'd rather not ignore the problem and hope end users don't experience it...

Try asking this in Game Development and you might get a better answer.
EDIT: The following code doesn't seem to fix the issues raised, but does provide testing for animation and uses timed callbacks for main game loop
Try working with a timed callback to your render function.
import pygame
import time
import math
from pygame.locals import *
desiredfps = 60
updaterate = int(1000 / desiredfps)
print "Aiming for {0}fps, update every {1} millisecond".format(desiredfps, updaterate)
lasttime = 0
rectx = 0
recty = 0
def run_game():
pygame.init()
screen = pygame.display.set_mode((500, 500))
pygame.time.set_timer(USEREVENT+1, updaterate)
def mainloop():
global lasttime
global rectx
global recty
screen.fill(pygame.Color("white"))
screen.fill(pygame.Color("red"), pygame.Rect(rectx,recty,20,20))
screen.fill(pygame.Color("blue"), pygame.Rect(480-rectx,480-recty,20,20))
screen.fill(pygame.Color("green"), pygame.Rect(rectx,480-recty,20,20))
screen.fill(pygame.Color("yellow"), pygame.Rect(480-rectx,recty,20,20))
rectx += 5
if rectx > 500:
rectx = 0
recty += 20
beforerender = time.clock()
pygame.display.update()
afterrender = time.clock()
renderdelta = afterrender - beforerender
framedelta = beforerender - lasttime
lasttime = beforerender
if renderdelta > 0.01:
print "render time: {0}".format(renderdelta)
print "frame delta: {0}".format(framedelta)
print "-------------------------------------"
while(1):
for event in pygame.event.get():
if event.type == USEREVENT+1:
mainloop()
if event.type == QUIT:
pygame.quit()
return
# Run test
run_game()
I don't seem to have any trouble when doing this, but please let me know if you still experience issues.

After some testing, here are some of the results. First, to answer the question:
The cause of lag spikes is not pygame.display.update(). The cause of lag spikes is clock.tick(FRAME_RATE). Note, that clock.tick() without the FRAME_RATE parameter doesn't cause spikes. The problem did not go away when I tried to substitute pygame's clock.tick() with manual tracking of frame rate using python's time.sleep() method. I think it is because internally, both python's time.sleep() and pygame's clock.tick() use the same function, which is known to be imprecise. It seems that if you feed that function 1ms to sleep (so as to not hog all of the CPU if the game is simple enough), the function will sometimes sleep much longer than that, about 10-15ms longer. It depends on the OS implementation of the sleep mechanism and the scheduling involved.
The solution is to not use any sleep-related functions.
There is also a second part. Even if you don't use any sleep(), there is an issue of an inconsistent delta time between individual frames, which when not taken into account may cause visual jittering/stuttering. I believe that this issue has been explored in great detail in this tutorial.
So I went ahead and implemented the solution presented in this tutorial in python and pygame, and it works perfectly. It looks very smooth even though I'm updating "physics" at only 30fps. It eats a lot of cpu, but it looks nice. Here is the code:
from __future__ import division
import pygame
from random import randint
from math import fabs
PHYS_FPS = 30
DT = 1 / PHYS_FPS
MAX_FRAMETIME = 0.25
def interpolate(star1, star2, alpha):
x1 = star1[0]
x2 = star2[0]
# since I "teleport" stars at the end of the screen, I need to ignore
# interpolation in such cases. try 1000 instead of 100 and see what happens
if fabs(x2 - x1) < 100:
return (x2 * alpha + x1 * (1 - alpha), star1[1], star1[2])
return star2
def run_game():
pygame.init()
clock = pygame.time.Clock()
screen = pygame.display.set_mode((500, 500))
# generate stars
stars = [(randint(0, 500), randint(0, 500), randint(2, 6)) for i in range(50)]
stars_prev = stars
accumulator = 0
frametime = clock.tick()
play = True
while play:
frametime = clock.tick() / 1000
if frametime > MAX_FRAMETIME:
frametime = MAX_FRAMETIME
accumulator += frametime
# handle events to quit on 'X' and escape key
for e in pygame.event.get():
if e.type == pygame.QUIT:
play = False
elif e.type == pygame.KEYDOWN:
if e.key == pygame.K_ESCAPE:
play = False
while accumulator >= DT:
stars_prev = stars[:]
# move stars
for i, (x, y, r) in enumerate(stars):
stars[i] = (x - r * 50 * DT, y, r) if x > -20 else (520, randint(0, 500), r)
accumulator -= DT
alpha = accumulator / DT
stars_inter = [interpolate(s1, s2, alpha) for s1, s2 in zip(stars_prev, stars)]
# clear screen
screen.fill(pygame.Color('black'))
# draw stars
for x, y, r in stars_inter:
pygame.draw.circle(screen, pygame.Color('white'), (int(x), y), r)
pygame.display.update()
if __name__ == "__main__":
run_game()

import pygame
import time
import math
from pygame.locals import *
desiredfps = 60
updaterate = int(1000 / desiredfps)
lasttime = 0
rectx = 0
recty = 0
def run_game():
pygame.init()
screen = pygame.display.set_mode((500, 500))
pygame.time.set_timer(USEREVENT+1, updaterate)
def mainloop():
global lasttime
global rectx
global recty
screen.fill(pygame.Color("white"))
screen.fill(pygame.Color("red"), pygame.Rect(rectx,recty,20,20))
screen.fill(pygame.Color("blue"), pygame.Rect(480-rectx,480-recty,20,20))
screen.fill(pygame.Color("green"), pygame.Rect(rectx,480-recty,20,20))
screen.fill(pygame.Color("yellow"), pygame.Rect(480-rectx,recty,20,20))
rectx += 5
if rectx > 500:
rectx = 0
recty += 20
beforerender = time.clock()
pygame.display.update()
afterrender = time.clock()
renderdelta = afterrender - beforerender
framedelta = beforerender - lasttime
lasttime = beforerender
if renderdelta > 0.01:
print ("render time: {0}").format(renderdelta)
print ("frame delta: {0}").format(framedelta)
print ("-------------------------------------")
while(1):
for event in pygame.event.get():
if event.type == USEREVENT+1:
mainloop()
if event.type == QUIT:
pygame.quit()
return #

Related

How do I reset pygame.time.Clock()?

I made a sudoku game for my introduction to computer programming class and I want to expand it over Winter break by adding some new features. The first of which I want to be a clock. I found some code on here that helped me implement a clock system on my screen, but now I want the clock to reset when the restart button is pressed and the user goes back to the home screen.
Any help would be greatly appreciated! I am not married to my current code I am more than willing to change it, I am just very new to programming and don't even know where to start with something like this.
Attached is the current code I have to make my clock run and display it to my screen:
I tried to "time = 0", and "time = pygame.clock.Time()" hoping that it would initialize the time again and the count would start from 0 but it did not work. I looked for other answers, but I am new to programming and they didn't make much sense to me.
I was expecting the time to be reset to 0.000 and to start counting up again, but it just continued counting from where it left off
Below is the code I currently have that makes my clock and displays it to my game screen:
clock = pygame.time.Clock() # initialize clock
font = pygame.freetype.SysFont(None, 34) # font for clock
font.origin = True # makes the font not shake around for whatever
while True:
if not game_over:
screen.fill(pygame.Color(button_words_color), (0, 0, screen_dimension, 50))
ticks = pygame.time.get_ticks()
millis = ticks % 1000
seconds = int(ticks / 1000 % 60)
minutes = int(ticks / 60000 % 24)
out = '{minutes:02d}:{seconds:02d}:{millis}'.format(minutes=minutes, millis=millis, seconds=seconds)
font.render_to(screen, (5, 35), out, pygame.Color(button_color)) # (5, 35) is where it's displayed)
pygame.display.flip()
clock.tick(60)
pygame.time.get_ticks() returns the milliseconds since pygame.init() and cannot be reseted. However you can remember and change the start time:
start_ticks = pygame.time.get_ticks()
while True:
current_ticks = pygame.time.get_ticks()
# [...]
if not game_over:
ticks = current_ticks - start_ticks
# [...]
else:
start_ticks = current_ticks
# [...]

How to implement a Pygame timed game loop?

I am looking to write a better game loop in Python using pygame.time.Clock(), and I understand the concept of keeping time and de-coupling rendering from the main game loop in order to better utilise the ticks. I also understand about passing time lag into the rendering so that it renders the correct amount of movement, but the only examples I've found are written in C# and although I first thought it fairly simple to convert to Python, it's not behaving.
I've figured out that Pygame's Clock() already works out the milliseconds between the last 2 calls to .tick, and I've tried to adapt the sample code I found, but I really need to see a working example written in Python. Here's what I've come up with so far:
FPS = 60
MS_PER_UPDATE = 1000 / FPS
lag = 0.0
clock = pygame.time.Clock()
running = True
# Do an initial tick so the loop has 2 previous ticks.
clock.tick(FPS)
while running:
clock.tick(FPS)
lag += clock.get_time()
user_input()
while lag >= MS_PER_UPDATE:
update()
lag -= MS_PER_UPDATE
render(lag / MS_PER_UPDATE)
I'm not sure if this is all worth it in Pygame, or if it's already taken care of in some of it's time functions already? My game runs slower on the laptop (expected) but I thought doing this might even out the FPS a bit between my main PC and laptop by de-coupling the rendering. Does anyone have experience doing these advanced game loops in Pygame? I just want it to be as good as it can be...
Just take the time it took to render the last frame (called delta time) and pass it to your game objects so they can decide what to do (e.g. move more or less).
Here's a super simple example:
import pygame
class Actor(pygame.sprite.Sprite):
def __init__(self, *args):
super().__init__(*args)
self.image = pygame.Surface((32, 32))
self.rect = pygame.display.get_surface().get_rect()
self.image.fill(pygame.Color('dodgerblue'))
def update(self, events, dt):
self.rect.move_ip((1 * dt / 5, 2 * dt / 5))
if self.rect.x > 500: self.rect.x = 0
if self.rect.y > 500: self.rect.y = 0
def main():
pygame.init()
screen = pygame.display.set_mode((500, 500))
sprites = pygame.sprite.Group()
Actor(sprites)
clock = pygame.time.Clock()
dt = 0
while True:
events = pygame.event.get()
for e in events:
if e.type == pygame.QUIT:
return
sprites.update(events, dt)
screen.fill((30, 30, 30))
sprites.draw(screen)
pygame.display.update()
dt = clock.tick(60)
if __name__ == '__main__':
main()
If your game slows down below 60 (or whatever) FPS, dt gets bigger, and Actor moves more to make up for the lost time.

Can't click on image again, what's wrong with my pygame code?

Okay, I'am trying to create a Tom and Jerry game with the pygame library.
The game focuses on catching mice by clicking on them as they appear in their holes. The problem
is that sometimes a cat appears instead of a mouse and should the player erroneously click on the
cat (s)he looses all earned points, but the game continues.
The mouse is an image of a mouse and the cat is an image of an cat.
If you click on the mouse, you get mouse, otherwise the cat gets the points.
The code is a mess, that's because I don't know what I'am doing and just set an another event loop because then it works, because it runs after I create the mouse. It works to click on the mouse but then you click somewhere else and after that it's like you did not clicked on the mouse.
The mouse is created in a loop and is supposed to wait for 5 seconds and if you click on the mouse within these seconds then an appropriate message prints out in the console ,,Jerry clicked!" else "1 click". If you don't click on the mouse within 5 seconds a image covers the mouse so she disappears.
Now, what I'am trying to do right now is to print the message 1 click when the player does not click on anything but print 1 click jerry clicked when the player clicks on the mouse. I have a image of the mousehole and then I put the mouse on the mousehole, that is, on an another image.
This code works with one image at least:
pygame.init()
width=350;
height=400
screen = pygame.display.set_mode( (width, height ) )
pygame.display.set_caption('clicked on image')
redSquare = pygame.image.load("images/red-square.png").convert()
x = 20; # x coordnate of image
y = 30; # y coordinate of image
screen.blit(redSquare , ( x,y)) # paint to screen
pygame.display.flip() # paint screen one time
running = True
while (running):
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.MOUSEBUTTONDOWN:
# Set the x, y postions of the mouse click
x, y = event.pos
if redSquare.get_rect().collidepoint(x, y):
print('clicked on image')
#loop over, quite pygame
pygame.quit()
My problem is that, when I click on the mouse and then I don't click on the mouse I can't click on the mouse again at another position.
So what's wrong? What I'am doing wrong here?
Here is my code:
import pygame
from pygame import *
from random import *
init()
run = True
screen = (800,800)
screen = display.set_mode(screen)
xpos = 0
ypos = 0
mouseorcatxpos = 5
mouseorcatypos = 0
mousehole = image.load("mousehole.png").convert()
cat = image.load("tom.png")
jerry = image.load("jerry.png")
def makeholes():
global ypos
global xpos
for holey in range(1,9):
for holex in range(1,9):
screen.blit(mousehole,(xpos,ypos))
display.flip()
xpos += 100
ypos += 100
xpos = 0
def mouseorcat():
global xpos
mouseorcatxpos = 5
ypos = 0
for mousecaty in range(1,9):
pygame.event.pump()
for mousecatx in range(1,9):
randommouse = randint(1, 3)
randomcat = randint(1, 10)
if(randommouse == 2):
screen.blit(jerry, (mouseorcatxpos, ypos))
display.flip()
for event in pygame.event.get():
if (event.type == MOUSEBUTTONDOWN):
if jerry.get_rect().collidepoint(xpos, ypos) == False:
print("l clicked!")
x, y = event.pos
if jerry.get_rect().collidepoint(xpos, y):
print("JERRY CLICKED!!")
x, y = event.pos
print(x, y)
time.wait(5000)
#screen.blit(mousehole, (mouseorcatxpos - 5, ypos))
display.flip()
elif(randomcat == 2):
screen.blit(cat, (mouseorcatxpos, ypos))
display.flip()
time.wait(1500)
screen.blit(mousehole, (mouseorcatxpos-5, ypos))
display.flip()
mouseorcatxpos += 100
mouseorcatxpos = 0
ypos += 100
makeholes()
while run == True:
for event in pygame.event.get():
mouseorcat()
if event.type == QUIT:
run = False
I rewrote your game to show you how I would do it.
To keep track of the time and to limit the framerate I used a pygame.time.Clock and a timer variable. The clock returns the time in milliseconds since clock.tick was called the last time, which is used to increase the timer variable. The cat just replaces the mouse after two seconds and the mouse is set to a new position. I use pygame.Rects to store the positions, but you could also use lists or tuples.
import sys
import random
import pygame
pygame.init()
size = (800, 800)
screen = pygame.display.set_mode(size)
# Images replaced by pygame.Surface. Do that too
# in the future before you post your code.
mousehole = pygame.Surface((40, 40)).convert()
mousehole.fill(pygame.Color(30, 30, 30))
cat = pygame.Surface((40, 40)).convert()
cat.fill(pygame.Color(110, 110, 130))
jerry = pygame.Surface((40, 40)).convert()
jerry.fill(pygame.Color(190, 130, 0))
# Create the background image and blit the holes.
background = pygame.Surface(size).convert()
for holey in range(8):
for holex in range(8):
background.blit(mousehole, (holex*100, holey*100))
def new_position():
"""Return a random position between 0-700 in steps of 100."""
return (random.randrange(0, 701, 100), random.randrange(0, 701, 100))
def main():
fps = 30
clock = pygame.time.Clock()
jerry_rect = jerry.get_rect() # Stores jerry's position and size.
jerry_rect.topleft = new_position() # New random position.
# The cat is outside of the screen first.
cat_rect = cat.get_rect(topleft=(-100, -100))
points = 0
timer = 0
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.MOUSEBUTTONDOWN:
if jerry_rect.collidepoint(event.pos):
points += 1
print('Jerry caught! Points:', points)
timer = 0
jerry_rect.topleft = new_position()
else:
print('Missed. Points:', points)
# Run logic.
timer += clock.tick(fps) / 1000 # timer + seconds since last tick.
if timer > 2: # Cat catches mouse after 2 seconds.
cat_rect.topleft = jerry_rect.topleft
jerry_rect.topleft = new_position()
timer = 0
points = 0
print('Tom caught Jerry.')
# Draw.
# Clear the screen by blitting the bg.
screen.blit(background, (0, 0))
screen.blit(jerry, jerry_rect)
screen.blit(cat, cat_rect)
pygame.display.flip()
if __name__ == '__main__':
main()
pygame.quit()
sys.exit()
Side notes:
Don't use star imports (from module import *), because that can make code harder to read. If you want you can use from pygame.locals import *, if it's the only star import.
Don't use global variables, because they can make code harder to read, understand and maintain. Pass variables to functions as arguments and then return the result.
Update: Some notes about your program:
The first big problem is that your game has two event loops and the important one is deeply nested inside of two other for loops and a if. The event loop should be directly under the main while loop (one indentation level (when you have more experience you can put it into a function or class method)).
The two for loops seem to have the purpose to let the code run until randommouse or randomcat are 2. To run code until a condition is met is the purpose of a while loop. But in this case you should better just pick a random number and write the if/elif conditions so that they always apply. For example, you want a 2/3 chance for mouse and 1/3 for a cat,
random_number = random.randint(1, 3)
if random_number < 3:
print("2/3 probability. It's a mouse")
else:
print("1/3 probability. It's a cat")
Or use random.choice with a list:
>>> random.choice(['mouse', 'mouse', 'cat'])
'mouse'
time.wait(5000) shouldn't be used because the game just hangs in this time. You can't even close the window. Limit the framerate and get the time since the last tick with a pygame.time.Clock.
pygame.event.pump() is not needed.
If you call get_rect() without an argument, the rect is positioned at (0, 0).
if jerry.get_rect().collidepoint(xpos, y):
That's the reason why clicking on jerry only works in the top row, and because you use the global xpos here. Since xpos is 0, the whole top row counts as Jerry.
You can pass coordinates to get_rect like so (you can also use center or other args instead of topleft):
jerry_rect = jerry.get_rect(topleft=(50, 100))
I'm sorry but I don't think I can simply fix your code. I've tried it several times, but I always end up re-writing it completely.
I begin by extracting the event loop out of the two nested for loops, then remove these loops, create rects for the mouse and cat, fix the collision detection, add a timer and so on. Take a close look at my example and try to rewrite your game in a similar way, and keep asking questions if you don't understand something.

Python time counter in Pygame-mouse events

I want to calculate the time of user's mouse events in Pygame, if user doesn't move his mouse about 15 seconds, then I want to display a text to the screen. I tried time module for that, but it's not working.
import pygame,time
pygame.init()
#codes
...
...
font = pygame.font.SysFont(None,25)
text = font.render("Move your mouse!", True, red)
FPS = 30
while True:
#codes
...
...
start = time.time()
cur = pygame.mouse.get_pos() #catching mouse event
end = time.time()
diff = end-start
if 15 < diff:
gameDisplay.blit(text,(10,500))
pygame.display.update()
clock.tick(FPS)
pygame.quit()
quit()
Well output is not what I want, I don't know how to calculate it if user doesn't move his mouse.
If I want to write a text when user's mouse in a special area, it's working like;
if 100 < cur[0] < 200 and 100 < cur[1] < 200:
gameDisplay.blit(text,(10,500))
But how can I calculate? I even couldn't find how to tell Python, user's mouse is on the same coordinates or not.Then I can say, if mouse coordinates changes, start the timer, and if it's bigger than 15, print the text.
Edit: You can assume it in normal Python without Pygame module, assume you have a function that catching the mouse events, then how to tell Python if coordinates of mouse doesn't change, start the timer, if the time is bigger than 15 seconds,print a text, then refresh the timer.
To display a text on the screen if there is no mouse movement within the pygame window for 3 seconds:
#!/usr/bin/python
import sys
import pygame
WHITE, RED = (255,255,255), (255,0,0)
pygame.init()
screen = pygame.display.set_mode((300,200))
pygame.display.set_caption('Warn on no movement')
font = pygame.font.SysFont(None, 25)
text = font.render("Move your mouse!", True, RED, WHITE)
clock = pygame.time.Clock()
timer = pygame.time.get_ticks
timeout = 3000 # milliseconds
deadline = timer() + timeout
while True:
now = timer()
if pygame.mouse.get_rel() != (0, 0): # mouse moved within the pygame screen
deadline = now + timeout # reset the deadline
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
screen.fill(WHITE)
if now > deadline: # no movement for too long
screen.blit(text, (10, 50))
pygame.display.flip()
clock.tick(60) # set fps
You should add:
start = time.time()
cur = None
before while loop.
You should also change start = time.time() in while loop to:
if cur != pygame.mouse.get_pos():
start = time.time()
Also you could use pygame.time (it's similar to time but measure time in milliseconds)
In your code, the while True: code block is continuously running. The cur = pygame.mouse.get_pos() function is non blocking. This means it does not wait for mouse input - it will return straight away. So you need to initialize the start and cur variables before your while True: code block and then check the mouse position constantly in your loop.
If cur has changed since the last time the loop ran, then reset the start variable to the current time, and if the difference between the current time and start becomes larger than your 15 seconds, you can display the text.
You can also do that even without getting time, since you can calculate the pause as an integer counter through your FPS. Consider following example. Note that if the cursor is out of the window, the values of its positon will not change even if you move the cursor.
import pygame
pygame.init()
clock = pygame.time.Clock( )
DISP = pygame.display.set_mode((600, 400))
FPS = 25
Timeout = 15
Ticks = FPS*Timeout # your pause but as an integer value
count = 0 # counter
MC = pygame.mouse.get_pos()
MC_old = MC
MainLoop = True
while MainLoop :
clock.tick(FPS)
pygame.event.pump()
Keys = pygame.key.get_pressed()
if Keys[pygame.K_ESCAPE]:
MainLoop = False
MC = pygame.mouse.get_pos() # get mouse position
if (MC[0]-MC_old[0] == 0) and (MC[1]-MC_old[1] == 0) :
count = count + 1
else : count = 0
if count > Ticks :
print "What are you waiting for"
count = 0
MC_old = MC # save mouse position
pygame.display.flip( )
pygame.quit( )

How do I make a timer in pygame without delaying the program

I am making a pygame game and need the variable "img" to cycle through multiple slides to make a walking animation, but all the timers i can find made with python/pygame delay the program which i don't want.
You can measure time with Python's time module. You could do something like the following:
import time
t = time.clock()
deltaT = 1 #time between updates, in seconds
while True: #inside the game loop...
if (time.clock() - t) > deltaT:
#change your image
t = time.clock()
Although if you're animating sprites, you might have better luck looking for animation modules for pygame.
You can do something like the following:
import time, pygame
from pygame.locals import *
images = ['img1.jpg', 'img2.jpg', 'img3.jpg', 'img4.jpg']
pygame.init()
screen = pygame.display.set_mode((1024, 1280))
i = 0
x = time.time()
while True:
screen.blit(images[i]) #Create the image, this syntax is wrong
screen.fill((255, 255, 255))
if i != 3:
i+=1
elif i == 4:
i = 0

Categories