python - terminar - Temporizador de cuenta regresiva para pygame
funcion para ordenar en python (4)
Hice una pregunta anterior acerca de una detección de colisión múltiple, pero no tengo la habilidad para crear código para solucionar ese problema, solo estoy agregando un segundo muro e intentando poner un temporizador.
Mi pregunta es ¿cómo pongo un temporizador en mi código?
Necesita contar hacia atrás y cuando llegue a 00:00
muestre el texto: GAME OVER
y finalice el juego. Estoy poniendo la línea principal de mi código si eso ayuda. Si necesita más código como clases, etc. Me complace publicarlo.
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()
Puede generar un evento después de un tiempo. Ver: http://www.pygame.org/docs/ref/time.html#pygame.time.set_timer
Usando un código similar al que tienes ahora, puedes ver si el evento es un evento de temporizador y actuar en consecuencia.
Al igual que Hans Then dijo, puede usar el método pygame.time.set_timer()
para llamar a una función después de que ha transcurrido un tiempo específico. Pero en términos de mostrar cuánto tiempo ha pasado, probablemente sea mejor utilizar otro método.
Usando el método pygame.time.Clock.tick_busy_loop
, puedes controlar cuántos FPS ejecuta tu juego y registrar cuánto tiempo ha pasado, dado que devuelve cuántos milisegundos han pasado desde la última llamada:
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
Podrías hacer esto
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"
No estoy seguro si encontraste tu respuesta o, para el caso, si esto será útil ... Yo también estoy trabajando para agregar un temporizador a un juego, pero también tengo algunas preguntas ... para empezar, soy teniendo éxito con el siguiente código. (Lo recibí de otro tablero de mensajes, pero parece que no puedo encontrarlo nuevamente, así que me disculpo por no dar crédito en este momento; editaré esta publicación cuando encuentre el sitio).
Tomé este código que fue escrito para mostrar el recuento en la ventana de la consola y lo modifiqué para mostrarlo en la pantalla.
Tuve poco éxito con el temporizador y los tics (por alguna razón, parecía que mi programa estaba ejecutando un ciclo infinito ... de todos modos:
Esto es lo que estoy usando:
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)
Algunas advertencias: En primer lugar, no estoy 100% seguro de lo que hace todo esto ... esencialmente, la primera parte configura una función de temporizador. La segunda parte configura las variables del temporizador (el recuento y la demora ... por ahora, estoy usando incrementos de 1 segundo para simplificar).
La siguiente parte (creo) le dice a esta función que se ejecute dentro de un nuevo subproceso, por lo que se ejecuta independientemente de mi ciclo principal a su propio ritmo (es decir, no está pausando mi juego 1 segundo a la vez)
La última parte es lo que quiero que suceda cuando el reloj llegue a cero ... Restablecé la variable global timedisp para decir "GAME OVER"
Además, no tengo idea de qué tan gravoso es este método en el sistema. No tengo idea si esto es "eficiente o no". Me encantaría la opinión de alguien sobre esto.
Antes de estas funciones, tengo la fuente definida como:
clockfont = pygame.font.SysFont("#FONT_NAME",SIZE) #font to use for timer clock
En mi ciclo principal, estoy mostrando el resultado con:
if timerrun == 1:
clockpos = (screenwidth - timedisp.get_width()) /2 #center my clock
screen.blit(timedisp,(clockpos,100)) #put it on screen
De nuevo, estoy usando la variable timerrun porque quiero que el reloj (en mi juego) sea opcional ... para la prueba, el reloj no se mostrará hasta que presione la tecla "t" en el teclado ... que ejecuta el temporizador en un nuevo hilo:
if event.key==K_t:
c.start();
A continuación, mostrará el reloj, la cuenta regresiva y luego mostrará "GAME OVER" cuando haya terminado.
Aquí hay MIS preguntas si alguien puede ayudar ...
No estoy seguro si pasar el texto cambiante a través de la variable global es la forma "correcta" de hacer esto ... ¿alguien puede decirme si / cómo podría ser una mejor manera de actualizar la pantalla en pantalla usando estos 2 hilos?
Me gustaría la acción que ocurre cuando se acaba el tiempo (la parte que muestra "Game Over" - para ejecutar algunas funciones en el hilo principal (¿estoy diciendo esto bien?)
Por ejemplo: cuando se acaba el tiempo, ejecuta una función que compara puntajes de 2 jugadores y declara un ganador. - ¿Cómo puedo hacer que "thread 2" (el temporizador) vuelva a llamar a una función en "thread 1" (el resto del juego)?
Por último, busco la manera de "reiniciar" el reloj sin reiniciar todo el programa. Cuando presiono "t" nuevamente, aparece el error de que no puedes volver a iniciar un hilo. ¿Alguien puede ofrecer una sugerencia sobre cómo reiniciar mi reloj?
¡Muchas gracias!
Arrendajo