2

I asked a question earlier about a multiple collision detection but I don't have the skill to create code to fix that problem instead I am just adding a second wall and trying to put in a timer.

My question is how do I put a timer into my code?

It needs to count down and when it hits 00:00 show the text: GAME OVER and end the game. I am putting in the main line of my code if that helps. If you need more code such as classes etc. I am happy to post it.

while done == False:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True

            #This makes the player move
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                player.changespeed(-6,0)
            if event.key == pygame.K_RIGHT:
                player.changespeed(6,0)
            if event.key == pygame.K_UP:
                player.changespeed(0,-6)
            if event.key == pygame.K_DOWN:
                player.changespeed(0,6)

        #This stops the player from moving
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT:
                player.changespeed(6,0)
            if event.key == pygame.K_RIGHT:
                player.changespeed(-6,0)
            if event.key == pygame.K_UP:
                player.changespeed(0,6)
            if event.key == pygame.K_DOWN:
                player.changespeed(0,-6)

    player.updateWall(wall_list)

    window.fill(black)

    movingsprt.draw(window)
    wall_list.draw(window)

    pygame.display.flip()

    clock.tick(40)

pygame.quit()            
msturdy
  • 10,479
  • 11
  • 41
  • 52
Lucas Murphy
  • 23
  • 1
  • 1
  • 5

4 Answers4

2

Like Hans Then said, you can use the pygame.time.set_timer() method to call a function after a specific amount of time has passed. But in terms of showing how much time has passed you are probably better off using another method.

Using the pygame.time.Clock.tick_busy_loop method, you can controll how many FPS your game runs at and track how much time has gone by, since it returns how many millisecons have passed since the last call:

clock = pygame.time.Clock()
minutes = 0
seconds = 0
milliseconds = 0

while True: #game loop
    #do stuff here
    if milliseconds > 1000:
        seconds += 1
        milliseconds -= 1000
    if seconds > 60:
        minutes += 1
        seconds -= 60

    print ("{}:{}".format(minutes, seconds))

    milliseconds += clock.tick_busy_loop(60) #returns the time since the last time we called the function, and limits the frame rate to 60FPS
The-IT
  • 660
  • 8
  • 19
1

You can generate an event after some time. See: http://www.pygame.org/docs/ref/time.html#pygame.time.set_timer

Using code similar to the one you have now, you can see if the event is a timer event and act accordingly.

Hans Then
  • 10,935
  • 3
  • 32
  • 51
1

You could do this

time = 100 #time in seconds
pygame.time.set_timer(USEREVENT+1, 1000)#1 second is 1000 milliseconds 

#everything below this line should be in your main loop
for event in pygame.event.get():
    if event.type = USEREVENT+1:
        time -= 1

if time == 0:
    print "GAME OVER"
Marko Scekic
  • 105
  • 6
0

I am not sure if you found your answer or, for that matter, if this will be helpful... I, too am working on adding a timer to a game, but I also have some questions... for starters, I am having success with the following code. (I got this from another message board, but I can't seem to find it again so I apologize for not giving credit at this time - I will edit this post when I find the site).

I took this code which was written to display the count in the console window and modified it to show on screen.

I had little success with timer and ticks (for some reason it seemed like my program was running an infinite loop... anyhow:

This is what I'm using:

import time
import threading
import pygame, sys
#among others....

#timer clock
global timerrun #I added this to show / hide the clock from my main screen
timerrun = 0 #just a default 

class Timer (threading.Thread):
    def __init__(self,seconds):
        self.runTime = seconds
        threading.Thread.__init__(self)
    def run(self):
        time.sleep(self.runTime)

class CountDownTimer(Timer):
    def run(self):
            counter = self.runTime
            for sec in range(self.runTime):
                global timerrun
                timerrun = 1 #set timer is running global variable - tells main loop to display clock
                global timedisp #set timedisplay as global var so it can be shared between threads
                timedisp = clockfont.render(str(counter),1,(255,255,255))
                #print str(counter)
                time.sleep(1.0)
                counter -= 1

class CountDownExec(CountDownTimer):
        def __init__(self, seconds, action):
            self.action = action
            CountDownTimer.__init__(self, seconds)
        def run (self):
            CountDownTimer.run(self)
            self.action()

def myAction():
    #print "Perform an action here... say GAME OVER!"
    global timedisp
    timedisp = clockfont.render("GAME OVER",1,(255,255,255))

c = CountDownExec(timeonclock,myAction)

Some caveats: Firstly, I'm not 100% sure what all of this does... essentially, the first part sets up a timer function. The second part setups the timer's variables (the count and the delay... for now, I am using 1 second increments for simplicity.)

The next part (I think) tells this function to run inside of a new Thread - so it is running independently from my main loop at it's own pace (ie, it is not pausing my game 1 second at a time)

The last part is what I want to happen when the clock hits zero... I re-set the global timedisp variable to say "GAME OVER"

ALso, I have no idea how taxing this method is on the system. I have no idea if this is "efficient or not" - I'd love someone's input on this.

Before these functions, I have the font defined as:

clockfont = pygame.font.SysFont("#FONT_NAME",SIZE) #font to use for timer clock

In my main loop, I am displaying the result with:

if timerrun == 1:
        clockpos = (screenwidth - timedisp.get_width()) /2 #center my clock
        screen.blit(timedisp,(clockpos,100)) #put it on screen

Again, I am using the timerrun variable because I want the clock (in my game) to be optional... for testing, the clock won't show until you press the "t" key on the keyboard.. which executes the timer in a new thread:

    if event.key==K_t:
        c.start();

It will then display the clock, count down, and then show "GAME OVER" when finished.

Here are MY questions if anyone can help...

I am not sure if passing the changing text via global variable is the "Right" way to do this.. can anyone tell me if / how might be a better way to update the display on screen using these 2 threads.

I would like the action that happens when the time is up (the part that displays "Game Over" - to execute some functions back in the main thread (am I saying this right?)

For instance: when time runs out, it runs a function that compares 2 player's scores and declares a winner. - How can I make "thread 2" (the timer) call a function back in "thread 1" (the rest of the game)??

Lastly, I a looking for a way to "Reset" the clock without resetting the whole program. When I press "t" again, I get an error that you can't start a thread over again. Can anyone offer a suggestion on how to restart my clock??

Thank you very much!

Jay

Jay
  • 458
  • 1
  • 5
  • 9