Salut à tous, je suis entrain de faire un jeu de labyrinthe et pour "pimenter" un peu le tout, j'aimerai qu'il y ai un temps impartis. Pour cela, je voudrais faire un compte à rebours, le problème, c'est que pour l'instant je ne suis arrivé qu'à lancer le jeu une fois que le temps était à 0 (code utilisé):
Mais ce que je veux c'est qu'on puisse jouer pendant que le temps diminue...
Un autre idée serait de faire incrémenter une variable dans ma boucle principale et une fois arrivée à un certain nombre, faire baisser le temps d'une unité et remettre la variable à 0, mais c'est pas très précis... Est-ce la seule solution ?
A+
[EDIT] Je m’aperçois que ma seconde solution fonctionne a merveille et qu'elle remplit parfaitement sa fonction. Si vous pensez avoir quelque chose de mieux à me proposer, je suis toujours preneur, mais sachez que je ne suis plus bloqué par ce problème. A+
Les threads ça me semble overkill. Au mieux il y a les timers.
Au cas ou : ta seconde solution ne fonctionne qu'à partir du moment ou tu régules le nombre de FPS. Sans ça, le temps passera plus vite sur un ordinateur plus rapide et plus lentement sur un ordinateur plus modeste.
Elle permet aussi de mettre simplement d'arréter le décompte du temps si le jeu est en pause. Avec les timers je pense qu'il faudrait les inclure dans une classe pour gérer ça.
Tu utilises une bibliothèques sans doute, elle ne propose pas déjà des outils pour ça ?
Sinon, si tu connais les classes en Python, reste à en créer une petite qui fait le boulot.
À l'utilisation ça pourrait donner quelque chose comme :
decompte = Decompte(30)
done = False
decompte.start()
while not done:
for e in events:
if e.type == QUIT:
done = True
elif e.type == SPACE:
decompte.pause()
temps = decompte.temps_restant()
if temps:
print 'temps restant : %d' : temps
else:
print 'temps écoulé ! Try again hahaha'
done = True
Merci pour la réponse mais j'ai quelques difficultés à voir comment ça marche, surtout avec des "pass" partout ^^.
En ce qui concerne le support, le jeu est destiné à une petite console portable, et bien qu'elle soit overlockable, je pense que le temps sera le même un peut partout.
Merci pour la réponse mais j'ai quelques difficultés à voir comment ça marche, surtout avec des "pass" partout ^^.
En ce qui concerne le support, le jeu est destiné à une petite console portable, et bien qu'elle soit overlockable, je pense que le temps sera le même un peut partout.
Les pass sont là pour dire que les méthodes de la classe restent à implémenter.
Du reste, ne trouves-tu pas dommage de coder un jeu en python qui est par nature un langage extrêmement portable et de le cibler uniquement pour un seul type d'architecture en sortie ?
Plus exactement, ce que je veux dire par là, c'est que python incorpore en standard des modules pour mesurer le temps (time, notamment), indépendamment de la plate-forme cliente. Ce serait quand même dommage de s'en passer alors que tu as la possibilité d'une solution propre, non ?
Va pour la solution time , mais je vois pas comment procéder: le code que j'ai utilisé plus haut faisait le décompte PUIS lançais le jeu. Chose que j'ai oublié de préciser, je suis débutant en python, de plus, je n'ai presque jamais touché au module time.
Le truc c'est qu'ici il n'est pas question de faire deux choses à la fois, tout est faisable séquentiellement... et tant mieux, quand on peut se passer des thread, on s'en passe.
Le sleep() ne sera pas présent dans la boucle principale de ton jeu, dans le code de Fred c'est juste un artifice nécessaire pour ne pas avoir 10000 "bonjour" qui s'affiche en 10s.
Dans ton jeu, le sleep() correspond en fait au traitement des évènements + temps de rendu + temps à ajouter pour réguler les FPS.
Un code testable avec pygame :
import pygame as pg
from time import time
pg.display.init()
screen = pg.display.set_mode((400,225))
fin_jeu = False
start = time()
duree_max = 10
while not fin_jeu:
# traitement evenements
for ev in pg.event.get():
if ev.type == pg.QUIT:
fin_jeu = True
# mise a jour du compteur
temps_ecoule = time() - start
if temps_ecoule > duree_max:
fin_jeu = True
# rendu
if temps_ecoule < duree_max:
print 'reste : %ds' % int(time() - start)
else:
print 'fin du temps !'
Rien n'est bloquant, pas besoin de thread.
C'est presque le même code que j'ai posté plus haut mais sans classe... c'est moins classe.
Du coup, créer un thread pour gérer le temps pendant que le principale s'occupe des évènements et de l'affichage ne serait peut-être pas tant overkill que ça, non ?
hm Je ne vois pas en quoi la création d'un thread soulagerait le CPU : la boucle évènement + affichage tournerait toujours à fond elle.
C'est donc de toute manière dans celle-ci qu'il faut réguler le nombre de FPS (vérifier combien de temps à pris l'exécution de la boucle, si inférieur à 1/fps, sleep(1/fps - temps_ecoule)
Par contre un timer pourquoi pas oui (mais ça serait juste une autre façon de faire et n'éviterait pas de limiter ces foutues FPS )
Oui d'où ma solution avec un sleep << à 1, cependant le PO parle d'un travail parallèle, si si et dans ce cas, c'est du thread qui nous intéresse, en tout cas c'est pas très complexe, j'ai jamais touché au module threading et je fais un petit code tout simple mais qui fonctionne.
import threading as th
from time import time, sleep
def countdown():
count = 0
start = time()
while time() - start < 10:
count += 1
print count
sleep(1)
def affichage():
count = 1
while count < 10:
print "bonjour"
count += 1
sleep(1)
th_1 = th.Thread(None, countdown, None)
th_2 = th.Thread(None, affichage, None)
th_1.start()
th_2.start()
[...] cependant le PO parle d'un travail parallèle, si si [...]
Il faudrait vraiment que tu m'expliques où Fred
Sa seconde solution est purement séquentielle et il dit que ça lui va très bien :
Citation : Monstercrunch
Un autre idée serait de faire incrémenter une variable dans ma boucle principale et une fois arrivée à un certain nombre, faire baisser le temps d'une unité et remettre la variable à 0, mais c'est pas très précis... Est-ce la seule solution ?
A+
[EDIT] Je m’aperçois que ma seconde solution fonctionne a merveille et qu'elle remplit parfaitement sa fonction. Si vous pensez avoir quelque chose de mieux à me proposer, je suis toujours preneur, mais sachez que je ne suis plus bloqué par ce problème. A+
Si c'est cette phrase qui te convainc de ça : « Mais ce que je veux c'est qu'on puisse jouer pendant que le temps diminue... », le but c'est que ce soit de cette façon que le joueur le ressente, mais à l'implémentation ça se fait très bien de calculer séquentiellement tout à chaque frame.
hm Je ne vois pas en quoi la création d'un thread soulagerait le CPU : la boucle évènement + affichage tournerait toujours à fond elle.
C'est donc de toute manière dans celle-ci qu'il faut réguler le nombre de FPS (vérifier combien de temps à pris l'exécution de la boucle, si inférieur à 1/fps, sleep(1/fps - temps_ecoule)
Par contre un timer pourquoi pas oui (mais ça serait juste une autre façon de faire et n'éviterait pas de limiter ces foutues FPS )
Si on cherche à avoir un grand nombre de FPS alors effectivement ce n'est pas très utile. Mais dans le cas d'un petit jeu style tetris, bomberman ou autres, le rafraichissement de l'écran n'a lieu que lors d'un évènement (input, bot, time, etc.), ainsi en plaçant la gestion de ces évènements dans des threads à part, le rôle du thread principal sera simplement de blitter à chaque évènement.
Au passage, les Timers sont des threads qui se lancent après un temps donné.
Si on cherche à avoir un grand nombre de FPS alors effectivement ce n'est pas très utile. Mais dans le cas d'un petit jeu style tetris, bomberman ou autres, le rafraichissement de l'écran n'a lieu que lors d'un évènement (input, bot, time, etc.), ainsi en plaçant la gestion de ces évènements dans des threads à part, le rôle du thread principal sera simplement de blitter à chaque évènement.
Quelque soit le nombre de FPS souhaité, je suis septique quand au fait qu'une solution à base de thread soit globalement plus économe qu'une solution séquentielle.
Dans la solution que tu proposes, chaque évènement engendrerait un rendu c'est bien ça ? Dans la solution séquentielle, on traite d'abord tous les évènements et ensuite on fait un seul rendu pour la frame. Du coup, je pense que tu es gagnant (et encore de peu je pense) quand il y a vraiment peu d'évènement, c'est à dire plus jeux de plateau basique ou jeux de cartes que Tetris et bonberman.
Un autre problème mais peut-être est-ce particulier à Pygame : avec cette lib on ne peut gérer l'affichage et les évènements que dans le thread principal.
Si jamais tu as un exemple sous le coude (« in code we trust »), n'hésites pas en tout cas
En faite, je ne sais pas pour ce qui est de pygame et je me rends compte que j'ai dit une grosse connerie aussi.
Ici, la réponse serai plutôt de définir un interval pour éviter que la boucle principale ne tourne trop dans le vide et de compter les tours de boucle.
interval = 0.1
maxtime = 120 // interval # 2 minutes
for i in range(maxtime):
last = time()
events()
blits()
split()
pause = interval - (time() - last)
if pause > 0:
sleep(pause)
Merci à tous pour vos suggestion, mais j'ai un peu de mal à comprendre ( et la flemme de me creuser la tête ).
Du coup, je demande juste votre avis sur le code suivant:
continuer = 1
x = 0
while continuer:
pygame.time.Clock().tick(30) # 30 frames par seconde
for event in pygame.event.get(): #Attente des événements
if event.type == QUIT:
continuer = 0
if event.type == KEYDOWN:
# mes trucs à faire
x+=1
if x == 30 #au bout de 30 frames (1s donc):
x = 0
refresh_time()
Voilà ! Sachez que je ne fais pas un jeu avec plein d'animations dans tous les sens ! 30 "images par seconde" suffisent largement !
en fait tu veux exceuter refresh_time() 30 fois par seconde ?
continuer = 1
clk = pygame.Clock()
tks = 0
laps = 1000/30
while continuer:
#temporisation du refresh()
tks += clk.tick()
if tks >= laps:
refresh_time()
tks -= laps
for event in pygame.event.get(): #Attente des événements
if event.type == QUIT: continuer = 0
if event.type == KEYDOWN: pass # mes trucs à faire
Nop, je veux juste le rafraichir une fois par seconde, comme dans mon code ^^. J'ai testé et ça marche, je voulais juste savoir si vous "approuviez" la méthode.
Nop, je veux juste le rafraichir une fois par seconde, comme dans mon code ^^. J'ai testé et ça marche, je voulais juste savoir si vous "approuviez" la méthode.
ben non,
suffit de remplacer la ligne 5 de mon code par
-> limite la boucle à 30 tours par secondes, donc au bout de 30 tours, ça fait une seconde et je rafraichit le temps.
pygame.time.Clock().tick(30) pause l'exécution pour que la laps de temps entre 2 appels fasse au minimum dans ce cas 1/30s.
donc oui, ça limite bien la boucle à 30 tours par secondes, mais ça limite aussi la boucle for ...
si ça correspond à tes besoins, alors c'est bien; sinon c'est pas le top comme méthode. amha.
[résolu]Programme avec un compte à rebours en prallèle
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Python c'est bon, mangez-en.
Python c'est bon, mangez-en.
Python c'est bon, mangez-en.
Python c'est bon, mangez-en.