Seite 1 von 1
Programm nimmt nach einigen sekunden keine Klicks mehr an
Verfasst: Mittwoch 11. Mai 2005, 15:49
von Hangman
Hallo,
ich muss für die Schule ein Spiel in Python mit Pygame schreiben. Das Programm an sich läuft auch ganz gut, allerdings habe ich das Problem, dass nach einigen Sekunden zwar scheinbar noch registriert wird, dass die Maus bewegt wird, das Programm auf Maus-Klicks allerdings niocht mehr reagiert
Am Ende des Quellcodes wird die Funktion main() aufgerufen. Über diese wird dann eine andere Funktion runde() aufgerufen, die dann wiederum mehrmals die Funktion turn() aufruft. anschliessend wird wiederum die Funktion runde() aufgerufen. meine event abfrage steht nun in der Funktion turn() die für den Benutzer scheinbar ständig aktiv ist, da die Funktion runde() nur aufgerufen wird, um sofort wieder die Funktion turn() aufzurufen.
Hier der Code für turn():
Code: Alles auswählen
def turn(spieleramzug,aktuellerunde): #wird jedes mal ausgefuehrt, wenn ein Spieler am Zug ist
zeigeinfosspiel(spieleramzug,aktuellerunde)
nochdran=1 #Variable, die fuer die Begrenzung der event-schleife erforderlich ist
while nochdran==1: #so lange dauert ein Zug
if pygame.event.get([MOUSEBUTTONDOWN]): #eventabfrage
for i in planeten.keys(): #bei einem Klick auf einen Planeten soll etwas passieren
if planeten[i]["besitzer"] == spieleramzug:
planetkoordy = planeten[i]["koordy"]
planetkoordx = planeten[i]["koordx"]
if (pygame.mouse.get_pos()[0] > planetkoordx and pygame.mouse.get_pos()[0] < planetkoordx+29 and pygame.mouse.get_pos()[1] > planetkoordy and pygame.mouse.get_pos()[1] < planetkoordy+29) :
nochdran=0 #runde wird beendet
zeigeinfosplanet(planeten[i],"ja")
for i in planeten.keys(): #bei einem Klick auf einen Planeten soll etwas passieren
if planeten[i]["besitzer"] == spieleramzug:
planetkoordy = planeten[i]["koordy"]
planetkoordx = planeten[i]["koordx"]
if (pygame.mouse.get_pos()[0] > planetkoordx and pygame.mouse.get_pos()[0] < planetkoordx+29 and pygame.mouse.get_pos()[1] > planetkoordy and pygame.mouse.get_pos()[1] < planetkoordy+29) :
zeigeinfosplanet(planeten[i])
return()
ich vermute, der Fehler liegt darin, dass die while schleife nicht ständig aktiv ist. andererseits wäre das unlogisch, da sie ja, sobald sie nicht mehr aktiv ist, wieder aufgreufen wird
vielen dank für die hilfe im vorraus
re:
Verfasst: Donnerstag 12. Mai 2005, 07:32
von HarryH
Hi Hangman,
Teste mal, ob die while-Schleife auch wirklich unterbrochen wird (print-Befehl in die tiefste if-Abfrage einfügen). Vielleicht läuft sie sich tot und blockiert deswegen das gesamte Programm?
Verfasst: Donnerstag 12. Mai 2005, 07:51
von Hangman
nur die Klicks werden nicht mehr angenommen. die position der maus wird weiter erkannt und auf diese Art kann ich auch weiterhin funktionen ausführen. nur eben die klicks werden nicht mehr erkannt
re:
Verfasst: Donnerstag 12. Mai 2005, 08:31
von HarryH
Hi Hangman,
Schick doch mal die anderen dazugehörigen Funktionen die mit der Funktion turn in Verbindung stehen.
Verfasst: Donnerstag 12. Mai 2005, 14:54
von Gast
Code: Alles auswählen
if __name__ == '__main__': main(9000,100,["jkhsdfuihsk","Hangman"])
da wir die funktion main mit parametern aufgerufen....
Code: Alles auswählen
def main(anzahlplaneten,anzrunden,mitspieler):
spielererstellen(mitspieler) #erstellt ein Dictionary mit je einem Dictionary pro Spieler
planetenerstellen(anzahlplaneten) #erstellt ein Dictionary mit je einem Dictionary pro Planeten
startplanetenzuweisen() #weist jedem Spieler einen Planeten zu
pygame.display.update()
runde(mitspieler,1,anzrunden) #das Spiel selber beginnt mit der ersten Runde
das ist jetzt halt die funktion main.. in dieser werden erst diverse funktionen aufgerufen, die bestimmte einstellungen vornehmen etc. das wichtige ist die funktion runde:
Code: Alles auswählen
def runde(mitspieler,aktuellerunde,anzrunden): #rekursive funktion. bei jedem aufruf eine runde weiter
if anzrunden >= aktuellerunde:
for i in mitspieler: #alle spieler kommen nach einander dran
turn(i,aktuellerunde)
aktuellerunde += 1 #aktuelle runde wird um 1 erhoeht
runde(mitspieler,aktuellerunde,anzrunden)
in dieser wird dann mehrfach turn aufgerufen:
Code: Alles auswählen
def turn(spieleramzug,aktuellerunde): #wird jedes mal ausgefuehrt, wenn ein Spieler am Zug ist
zeigeinfosspiel(spieleramzug,aktuellerunde)
nochdran=1 #Variable, die fuer die Begrenzung der event-schleife erforderlich ist
while nochdran==1: #so lange dauert ein Zug
if pygame.event.get([MOUSEBUTTONDOWN]): #eventabfrage
for i in planeten.keys(): #bei einem Klick auf einen Planeten soll etwas passieren
if planeten[i]["besitzer"] == spieleramzug:
planetkoordy = planeten[i]["koordy"]
planetkoordx = planeten[i]["koordx"]
if (pygame.mouse.get_pos()[0] > planetkoordx and pygame.mouse.get_pos()[0] < planetkoordx+29 and pygame.mouse.get_pos()[1] > planetkoordy and pygame.mouse.get_pos()[1] < planetkoordy+29) :
nochdran=0 #runde wird beendet
zeigeinfosplanet(planeten[i],"ja")
for i in planeten.keys(): #bei einem Klick auf einen Planeten soll etwas passieren
if planeten[i]["besitzer"] == spieleramzug:
planetkoordy = planeten[i]["koordy"]
planetkoordx = planeten[i]["koordx"]
if (pygame.mouse.get_pos()[0] > planetkoordx and pygame.mouse.get_pos()[0] < planetkoordx+29 and pygame.mouse.get_pos()[1] > planetkoordy and pygame.mouse.get_pos()[1] < planetkoordy+29) :
zeigeinfosplanet(planeten[i])
return()
eigentlich sollte also immer, wenn turn() beendet ist turn sozusagen sofort wieder aufgerufen werden. scheinbar wird nur die annahme von Klicksbeendet
Verfasst: Donnerstag 12. Mai 2005, 21:33
von BlackJack
Hilft Dir nicht bei Deinem Problem: Aber `runde()` ist völlig unnötiger weise rekursiv. Das würde ich ändern.
Und man braucht am Ende einer Funktion kein ``return``. Die Klammern danach wären auch überflüssig.
Verfasst: Donnerstag 12. Mai 2005, 22:37
von Hangman
BlackJack hat geschrieben:Hilft Dir nicht bei Deinem Problem: Aber `runde()` ist völlig unnötiger weise rekursiv. Das würde ich ändern.
Wieso ist das unnötig? diese Funktion muss nachher wieder aufgerufen werden....
BlackJack hat geschrieben:Und man braucht am Ende einer Funktion kein ``return``. Die Klammern danach wären auch überflüssig.
in diesem fall brauchte ich es schon...frag mich nicht, warum....ohne das ging es nicht
edit: zum ersten: so wird geregelt dass nach der ersten runde die 2. kommt etc.
re
Verfasst: Freitag 13. Mai 2005, 09:48
von HarryH
Hi Hangman,
Probier mal die Funktion 'turn' folgendermaßen aufzurufen:
Code: Alles auswählen
import thread
thread.start_new_thread(turn, (i, aktuellerunde,))
Meiner Meinung nach blockiert nämlich die ständig laufende while-Schleife
den Hauptthread, so daß keine Benutzeraktion zugelassen werden kann.
Durch das Aufrufen der Funktion 'turn', in einem externen Thread wird die
verhindert.
Zusätzlich würde ich am Ende der while-Schleife noch folgendes einbauen:
Dadurch läuft die Schleife nicht ständig auf "Volltouren" sondern wird
jedesmal am Ende für eine 1\10 Sekunde angehalten, was für die
Benutzeraktionen noch relevant ist, aber die Systemleistung minimiert.
Und Übrigens:
Wie beendest du dein Programm? Ich habe keine Abbruchbedingung gefunden.
Edit (Leonidas): Code in Python-Tags gesetzt.
Verfasst: Freitag 13. Mai 2005, 12:24
von Hangman
danke für die hilfe
nun läuft das programm an sich zwar durch, allerdibngs bekommt man keine möglichkeit zur Aktion, da alles sofort hinter einander abläuft. die mainfunktion läuft weiter, wodurch turn() sofort wieder aufgerufen wird. das programm läuft also durch, bis es am ende angekommen ist.
Das ende wird durch die if bedingung
und durch das erhöhen von aktuellerunde erreicht.
edit: ich hab ent wirklich ahnung von threads...... gibts da irgendwo ne gute anleitung, wo man was dazu lernen kann?
Verfasst: Freitag 13. Mai 2005, 17:57
von Leonidas
Hangman hat geschrieben:edit: ich hab ent wirklich ahnung von threads...... gibts da irgendwo ne gute anleitung, wo man was dazu lernen kann?
Da wäre die Doku zum
thread und zum
threading-Modul, sowie das
Thread-Kapitel im Python Cookbook. Aber deutsche Doku zu dem Thema habe ich gerade nicht gefunden. Jedoch ist
thread.start_new_thread() recht einfach zu verstehen
Verfasst: Freitag 13. Mai 2005, 18:21
von Hangman
vom Prinzip her habe ich das glaube ich schon verstanden.. das problem ist nur, dass das hier etwas amcht, was gar nicht sein soll....
ich will ja nicht, dass das hauptprogramm weiter läuft, während das andere noch nicht fertig ausgeführt ist....
aber mich interessiert halt, was threads sind
deswegen thx für die tutorials
Verfasst: Samstag 14. Mai 2005, 00:27
von BlackJack
Hangman hat geschrieben:BlackJack hat geschrieben:Hilft Dir nicht bei Deinem Problem: Aber `runde()` ist völlig unnötiger weise rekursiv. Das würde ich ändern.
Wieso ist das unnötig? diese Funktion muss nachher wieder aufgerufen werden....
edit: zum ersten: so wird geregelt dass nach der ersten runde die 2. kommt etc.
Das ist unnötig weil man das viel einfacher und sauberer in einer Schleife ausdrücken kann:
Code: Alles auswählen
def runde(mitspieler, anzrunden):
for aktuellerunde in xrange(1, anzrunden + 1):
for i in mitspieler:
turn(i, aktuellerunde)
Verfasst: Samstag 14. Mai 2005, 12:42
von Hangman
stimmt auch...
wo is der unterschied zwischen range und xrange?
Verfasst: Samstag 14. Mai 2005, 12:46
von Leonidas
Hangman hat geschrieben:wo is der unterschied zwischen range und xrange?
Bei range bekommst du eine Liste, bei xrange einen Iterator. Iteratoren belasten den Speicher meist wesentlich weniger, da sie erst erstellt werden, wenn man sie benötigt.
Verfasst: Samstag 14. Mai 2005, 12:52
von Hangman
aso gut thx
Verfasst: Montag 16. Mai 2005, 13:04
von Hangman
nu versteh ich das gar nicht mehr
ich hab das ganze nu komplett geändert. Jetzt hab ich nur noch ne while schleife, die bei einem Mausklick die funktion mausklick aufruft und als parameter die koordinaten der maus übergibt
der gleiche fehler wie viorher bleibt
die while schleife:
Code: Alles auswählen
while 1:
if pygame.event.get([MOUSEBUTTONDOWN]):
mausklick(pygame.mouse.get_pos()[0], pygame.mouse.get_pos()[1])
und die funktion mauskilck:
Code: Alles auswählen
def mausklick(mausx, mausy):
for i in planeten.keys(): #bei einem Klick auf einen Planeten soll etwas passieren
if planeten[i]["besitzer"] == aktuell["spieler"]:
planetkoordy = planeten[i]["koordy"]
planetkoordx = planeten[i]["koordx"]
if (pygame.mouse.get_pos()[0] > planetkoordx and pygame.mouse.get_pos()[0] < planetkoordx+29 and pygame.mouse.get_pos()[1] > planetkoordy and pygame.mouse.get_pos()[1] < planetkoordy+29) :
if aktuell["aktion"]=="startausw":
aktuell["neueaktion"]={"startplani":i}
aktuell["aktion"]="zielausw"
if planeten[i]["besitzer"] != aktuell["spieler"]:
planetkoordy = planeten[i]["koordy"]
planetkoordx = planeten[i]["koordx"]
if (pygame.mouse.get_pos()[0] > planetkoordx and pygame.mouse.get_pos()[0] < planetkoordx+29 and pygame.mouse.get_pos()[1] > planetkoordy and pygame.mouse.get_pos()[1] < planetkoordy+29) :
if aktuell["aktion"]=="zielausw":
aktuell["neueaktion"]["zielplani"]=i
aktuell["aktion"]="ende"
elif aktuell["aktion"]=="ende":
beendeturn()
wäre nett, wenn mir jemand helfen kann
Verfasst: Montag 16. Mai 2005, 13:06
von Hangman
gut hab den fehler selber gefunden
die abfrage funktioniert so nicht... muss ein for event in pygame.get.event(): hin....
viele dank für eure hilfe