canvas.coords funktioniert manchmal nicht? brauche Hilfe!

Fragen zu Tkinter.
Rene
User
Beiträge: 13
Registriert: Sonntag 2. September 2007, 14:22

canvas.coords funktioniert manchmal nicht? brauche Hilfe!

Beitragvon Rene » Sonntag 2. September 2007, 15:55

Hallo!

Ich bin seid einiger Zeit am programmieren eines computerspieles und bin schon relativ weit gekommen. Es geht darum das jeder spieler eine figur hat und versuchen muss seinen Gegner zu treffen. das schießen hab ich folgendermaßen gelöst:

Code: Alles auswählen

class Schuss:

        def fire(self,Sx,Sy,mousex,mousey):
                self.berechnekugelflug(Sx,Sy,mousex,mousey)
                self.Kx=Sx+2*self.schrittx
                self.Ky=Sy+2*self.schritty
                print "da: ",Sx,Sy,self.Kx,self.Ky,feuerball
               
                try:
                        self.it=c.create_image(self.Kx, self.Ky, image=feuerball)
                        print "Kein Fehler im c.creat! it: ",self.it
                        c.after(15,self.movekugel)
                       
                       
                except ValueError:
                        print "kugelfehler im c.creat!",self.Kx,self.Ky,Sx,Sy
                        print feuerball
                       
        def movekugel(self):
                self.Kx+=self.schrittx
                self.Ky+=self.schritty
               
                c.coords(self.it,self.Kx,self.Ky) --> MANCHMAL FEHLER!
                if self.wall() and self.hitplayer() and self.inboard():
                        c.after(15,self.movekugel)
                else:
                        c.delete(self.it)

        def berechnekugelflug(self,Sx,Sy,mousex,mousey):
                wa=self.getwinkel(Sx,Sy,mousex,mousey)-math.pi/2
                self.schrittx=int(14*math.cos(wa))
                self.schritty=int(14*math.sin(wa))
                print "berechne KFlug: ",self.schrittx,self.schritty


Sx,Sy sind die koordinaten des spielers der schießt
mousex und mousey brauch ich um den schusswinkel zu berechnen
die funktion "movekugel" wird mit 15ms verzögerung immer wieder selber aufgerufen bis sie etweder auf eine mauer trifft oder auf einen spieler...
Jetzt zu meinem Problem: nach mittlerweile sehr langer fehlersuche wende ich mich euch und hoffe darauf dass mir hier wer weiterhelfen kann.
wenn ich das spiel teste und sehr viel schieße, so ca. nach dem 50ten- 150ten schuss bekomm ich eine fehlermeldung:

Code: Alles auswählen

Unhandled exception in thread started by <function clientthread at 0x014066B0>
Traceback (most recent call last):
  File "C:\Users\Rene\Desktop\Python 2.5\Programme\2D-Abenteuer\DVI_Client1.py",
 line 636, in clientthread
    board.spieler2.schiessen(mousex,mousey)
  File "C:\Users\Rene\Desktop\Python 2.5\Programme\2D-Abenteuer\DVI_Client1.py",
 line 304, in schiessen
    schuss.fire(self.sposx,self.sposy,mousex,mousey,self.spn)
  File "C:\Users\Rene\Desktop\Python 2.5\Programme\2D-Abenteuer\DVI_Client1.py",
 line 38, in fire
    c.coords(board.feuerball21.it,self.Kx,self.Ky)
  File "C:\Python25\lib\lib-tk\Tkinter.py", line 2134, in coords
    self.tk.call((self._w, 'coords') + args)))
ValueError: invalid literal for float(): None


also scheinbar hat er plötzlich bei dem c.coords einem fehler(in diesem fall beim 54 ten schuss) hat da vielleicht wer eine idee was ich da machen muss?

Anderes problem besteht wenn ich das programm mit F5 starte:
dann bekomm ich nach 3-5 bewegungen in eine Richtung folgenden Fehler:

File "C:\Pyton25\lib\lib-tk\Tkinter.py", line 1403,in __call__
return self.func(*args)
File "C:\Pyton25\lib\lib-tk\Tkinter.py", line 498, in callit func(*args)
File "C:\Pyton25\lib\idlelib\ColorDelegator.py", line 152, in recolorize
self.recolorize_main()
File "C:\Pyton25\lib\idlelib\PyShell.py", line 292, in recolorize_main
ColorDelegator.recolorize_main(self)
File "C:\Pyton25\lib\idlelib\ColorDelegator.py", line171, in recolorize_main
head, tail = item
ValueError:need more than 1 value to unpack

der code fürs bewegen schaut so aus:

Code: Alles auswählen

    def MoveDown(self):
        self.sposy+=self.tempo
        if board.feld[self.getfeld(self.sposy+self.abstand)][self.getfeld(self.sposx)]=='M':
            self.explode()
        try:
            c.coords(self.sp,self.sposx,self.sposy)
        except ValueError:
            print self.sposx

self.sposy ist die y koordinate vom spieler
self. tempo ist die größe des schrittes
self.sp ist das bild von der spielfigur

Leider bringen mich beide Fehlermeldungen einfach überhaupt nicht weiter. Ich weiß auch nicht ob die beiden fehlermeldungen etwas miteinander zu tun haben oder nicht aber für mich macht es den anschein als würde das bewegen von bildern ( coords(item, x, y) ) nicht richtig funktionieren aber das bringt mich auch nicht weiter.
Also wenn wer hilfe hat dann bitte nicht zögern und nur her damit, bin nämlich schon kurz vorm Fluchen.....

Lg, Rene
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Beitragvon schlangenbeschwörer » Sonntag 2. September 2007, 16:54

Hallo Rene!


1. Willkommen im Forum!

2. Dein Post ist etwas unübersichtlich mit den ganzen Codeteilen, Fehlermeldungen, usw.
Ich weiß ja nicht, wie lang dein gesammtes Programm ist, aber es wäre wohl hilfreich, wenn du den Code, der nicht geht, im Context (ganze Klasse oä) bei einem paste-dienst posten könntest.

3. Zu deinen Problemen/Fehlern: Ich kann das Programm ua. aus dem oben genannten Grund nicht komplett verstehen. Beide Fehler sind jedoch ValueErrors, da kannst du doch selbst erstmal forschen:
Die fehlerhaften Variablen (beim 1. Codestück "self.it","self.Kx","self.Ky") mit print ausgeben, evtl. auch den Type. Wenn du Canvas.coord nämlich "None" als Argument gibst, anstatt einer Zahl einer Koordinate, liegts wohl nicht an coords, das es nicht geht, sondern an dir, weil du was falsches übergibst!
Zum 2. Problem kann ich grad nix sagen, aber wenns an IDLE liegt, wirds schwierig, aber das is ja dann auch nicht so schlimm.

Gruß, jj
Zuletzt geändert von schlangenbeschwörer am Donnerstag 6. September 2007, 15:57, insgesamt 1-mal geändert.
BlackJack

Beitragvon BlackJack » Sonntag 2. September 2007, 17:44

Für so "lustige" Fehler gibt's meistens zwei Ursachen: Entweder mehrere `Tkinter.Tk`-Objekte in einem Programm oder es wird versucht aus verschiedenen Threads auf die GUI zuzugreifen. Beides darf man nicht machen.
Rene
User
Beiträge: 13
Registriert: Sonntag 2. September 2007, 14:22

Beitragvon Rene » Donnerstag 6. September 2007, 15:35

Also erstmal vielen dank für euer Hilfe!

Ja, stimmt ist mir etwas unübersichtlich geraten... werde das beim nächsten Fehler besser machen.
Das client-programm hat ca 500 zeilen und das serverprogramm nochmal so viele.
Wegen dem ValueError: ja er sagt zwar was von valueError, aber er will komischerweise float haben, was man aber bei dem aufruf von canvas.coord nicht verwendet.-->versteh nicht warum oder woher oder wohin ich eine float - zahl schreiben soll.
Wenn ich alles mit print ausgebe, dann sind immer alle werte korrekt, trotzdem bekomme ich so einen fehler.

BlackJack könnte dem Problem aber schon recht nahe gekommen sein....
Was meinst du mit: man darf nicht mehrere Tk-inter-Objekte haben? Ich mach nämlich für jeden schuss ein eigenes neues Objekt und man kann ja auch mehrere Kugeln hintereinander abfeuern und die fliegen dann hintereinander.... darf ich das nicht machen?
Außerdem starte ich in jedem client programm einen thread der dafür verantwortlich ist mit dem serverprogramm zu kommunzieren, jedoch greif ich in dem thread nicht direkt auf die GUI zu.

Grundsätzlich funktioniert das spiel ja schon und man kann auch fröhlich in der Gegend herum ballern, aber nach wie gesagt einigen schüssen(ca.70) bekomm ich so eine fehlermeldung wie obengeschrieben.

Von pase-dienst hab ich noch nichts gehört, werd mich aber mal im internet umsehen....

Ich programmiere noch nicht allzu lange, aber eine ander vermutung kommt mir auch gerade: könnte es sein das es ein speicher-problem ist? Denn ich erzeugefür jeden schuss ein neues objekt. naja und sobald diekugel gegen die eine wand fliegt delete ich zwar das bild aber das objekt gibt ja immer noch...
Kann es sein dasser deswegen erst nach vielen schüssen(erzeugte objekte) irgendwann verwirrt ist?

Ich bin ab samstag für 2 Wochen nicht im Lande, werde aber versuchen trotzdem ab und zu einen Computer zu finden.

Lg, Rene
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Beitragvon schlangenbeschwörer » Donnerstag 6. September 2007, 16:08

Rene hat geschrieben:Von pase-dienst hab ich noch nichts gehört, werd mich aber mal im internet umsehen....

oh, das ganze heißt natürlich Paste-Dienst. Da kannst du code hochladen, der dann nicht das Forum hier blockiert/bremst.
Ua. gibt es http://paste.pocoo.org, aber auch andere "Gemeinden", w.zB ubuntuusers usw. haben sowas.

BlackJack meinte, das es Probleme gibt, wenn du mehrere Tk-Objekte des Moduls Tkinter erzeugst (Hauptfenster).

Threads sind natürlich immer problematisch, wenn gleichzeitig ein tk-mainloop läuft, aber wenn du nicht direkt auf die Graphik zugreifst, liegt es vlt. doch nicht daran und ist es zudem schwierig, das ohne Threads zu machen. (wofür brauchst du den Thread denn? mit der after-Methode von Tkinter-Objekten kannst du sleep+thread ersetzen)

Speicherproblem könnte es natürlich geben, aber dann ist das Programm wohl eher nicht "verwirrt", sondern einfach langsamer. (Den Speicherbedarf kannste ja leicht testen.)

bin faul-> zitate dazudenken
Rene
User
Beiträge: 13
Registriert: Sonntag 2. September 2007, 14:22

Beitragvon Rene » Donnerstag 6. September 2007, 16:37

aja, den thread benötige ich eigentlich nur um mit dem serverprogramm zu kommunizieren. das programm läuft so ab, dass bei einem tastendruck (z.b.: linke pfeiltaste) diese info zuerst an den server geschickt wird der schickt dann anschließend an alle clients dass der spieler ein feld nach links geht diese bekommen diese info in ihren thead. und im thread hab ich dann "spieler1.linksmove()" , da greift er aber auf die Klasse Spieler zu, die allerdings nichtmehr im thread ist.
Ich wüsste nicht wie ich die kommunikation ohne thread machen sollte, da ja ständig informationen auch über die anderen spieler kommen deswegen brauch ich, denk ich, einen thread der immer bereit ist etwas zu empfangen und das programm nicht blockiert....

Aso, nein Hauptfenster hab ich nur eines....

wie testet man den Speicherbedarf?
immerhin beginnt das programm auch ein bisschen zu ruckeln wenn zu viel auf einmal geschossen und bewegt auf einmal wird....

werd gleich mal auf die paste-seite gehen....

Lg, Rene
Rene
User
Beiträge: 13
Registriert: Sonntag 2. September 2007, 14:22

Beitragvon Rene » Donnerstag 6. September 2007, 16:41

so habs jetzt gepastet....
auf http://paste.pocoo.org #3484
das ist aber jetzt nur das clientprogramm
wenn ich was vom serverprogramm auch pasten soll dann nur sagen
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Beitragvon schlangenbeschwörer » Donnerstag 6. September 2007, 16:48

Rene hat geschrieben:wie testet man den Speicherbedarf?

Wenn du unter Windows arbeitest, einfach mal Strg+Alt+Entf drücken. :wink:
Unter Linux gibts das auch, weiß aber grad nicht wie.
Rene
User
Beiträge: 13
Registriert: Sonntag 2. September 2007, 14:22

Beitragvon Rene » Freitag 7. September 2007, 10:49

aso...
ja hab ich gemacht aber da hab ich immer über 1000mb frei(bzw. im cache)
BlackJack

Beitragvon BlackJack » Freitag 7. September 2007, 12:38

Du greifst auf die GUI von verschiedenen Threads zu. Lass das.

Du startest einen Thread, in dem die `clientthread()`-Funktion ausgeführt wird, die dann auf die GUI zugreift, deren `mainloop()` aber im Hauptthread ausgeführt wird. Das führt zu nichtdeterministischen Problemen.
Rene
User
Beiträge: 13
Registriert: Sonntag 2. September 2007, 14:22

Beitragvon Rene » Freitag 7. September 2007, 18:48

ah ja, versteh was du meinst. Das wird wahrscheinlich der haken an der sache sein. Vielen dank. Ich werd das gleich wenn ich zurück bin von meiner reise ausprobieren. Ich werde dann berichten obs funktioniert hat.
Danke nochmal an euch beiden für eure Hilfen, bin begeistert von dem Forum hier ;-)

Lg, Rene

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder