Seite 1 von 1

UnboundLocalError

Verfasst: Sonntag 26. Mai 2013, 21:37
von Hall9000
hey, ich bin neu hier, hab schon ein wenig mit Python gearbeitet und trotzdem ein kleines Problem ...

Code: Alles auswählen

    def Jumping(self,manX,manY):
		keys = pygame.key.get_pressed()
		if keys[K_UP]:
			self.jumping = True
			jumpingStart = pygame.time.get_ticks()
		if self.jumping:
			self.t = pygame.time.get_ticks() - jumpingStart
		if self.t > self.JUMPING_DURATION:
			jumping = False
			jumpHeight = 0
		else:
			jumpHeight = self.jumpHeightAtTime(self.t)
			manY = 450 - jumpHeight
		self.screen.blit(self.man,(manX, manY))
die Methode soll soll eine Figur (man) "springen" lassen, allerdings bekomm ich beim Ausführen der Methode folgenden Fehler:
File "Character.py", line 39, in Jumping
self.t = pygame.time.get_ticks() - jumpingStart
UnboundLocalError: local variable 'jumpingStart' referenced before assignment

obwohl die Deklaration von jumpingStart ein paar Zeilen früher erfolgt

ich habe bereits das Forum durchsucht, zwar ähnliches gefunden, jedoch nichts, dass mir konkret weiterhelfen konnte (da zB Methoden/Variablen aus anderen Klassen/Dateien importiert wurden, was bei mir nicht der Fall ist)
bin für jede Hilfe dankbar :)

Re: UnboundLocalError

Verfasst: Sonntag 26. Mai 2013, 22:05
von Sirius3
In Python werden keine Variablen deklariert. Es werden nur Werte an Namen gebunden. Das binden an »jumpingStart« und das Benutzen dieser Variable findet in zwei verschiedenen if-Abfragen statt. Es ist also nicht zwingend, dass immer »keys[K_UP]« wahr ist wenn »self.jumping« wahr ist.

Re: UnboundLocalError

Verfasst: Sonntag 26. Mai 2013, 22:19
von Hall9000
wenn ichs richtig verstanden habe verhält es sich mit 'jumpingStart' also zur Zeit wie mit Schrödingers Katze, dass die IDE nicht weis ob sie wahr/falsch ist und gibt deswegen die Fehlermeldung ?

Re: UnboundLocalError

Verfasst: Sonntag 26. Mai 2013, 22:27
von Sirius3
Nein! Python weiß sehr wohl, ob es durch einen Zweig gelaufen ist, in dem die lokale Variable »jumpingStart« gesetzt wurde oder nicht. Wenn die Fehlermeldung auftritt, dann ist eindeutig und ohne Unschärfe »keys[L_UP]« nicht wahr, und somit wurde der erste if-Block nicht durchlaufen.

Re: UnboundLocalError

Verfasst: Sonntag 26. Mai 2013, 22:35
von Hall9000
gut, ich habs falsch verstanden...
ich denke ich muss diesenn

Code: Alles auswählen

if self.jumping:
    self.t = pygame.time.get_ticks() - jumpingStart
Block weiter einrücken, damit er erst durchlaufen wird wenn 'keys[K_UP]' wahr ist ?

Re: UnboundLocalError

Verfasst: Sonntag 26. Mai 2013, 22:39
von Hall9000
hab den Block eingerückt und es funktioniert wie ich es mir vorgestellt habe :)

Code: Alles auswählen

def Jumping(self,manX,manY):
	keys = pygame.key.get_pressed()
	if keys[K_UP]:
		self.jumping = True
		jumpingStart = pygame.time.get_ticks()
		if self.jumping:
			self.t = pygame.time.get_ticks() - jumpingStart
	if self.t > self.JUMPING_DURATION:
		jumping = False
		jumpHeight = 0
	else:
		jumpHeight = self.jumpHeightAtTime(self.t)
		manY = 450 - jumpHeight
	self.screen.blit(self.man,(manX, manY))
danke, für den Denkanstoß :)

Re: UnboundLocalError

Verfasst: Sonntag 26. Mai 2013, 22:43
von Sirius3
was Du machen mußt, mußt Du selbst wissen, weil ich nicht weiß was Du machen willst. Jedenfalls hat der von Dir gezeigte Code noch einige Fehler: die beiden Zeilen »jumping = False« und »jumpHeight = 0« binden Werte an lokale Variablen, die nicht weiter verwendet werden.
Wenn Du die von Dir erwähnten Zeilen einrückst, kannst Du sie genausogut gleich ganz weglassen, da »self.jumping« dann immer wahr ist und somit »self.t« immer auf 0 gesetzt wird.

Re: UnboundLocalError

Verfasst: Sonntag 26. Mai 2013, 23:07
von Hall9000
Ich habs so versucht und vorerst funktioniert der Code ausreichend.
Natürlich muss und wird er noch weiter bearbeitet werden :D

Re: UnboundLocalError

Verfasst: Montag 27. Mai 2013, 09:16
von EyDu
Nur weil der Code ohne einen Fehler durchläuft heißt das nicht, dass dieser funktioniert. Lediglich, dass es keine Syntax-Fehler gibt. Und da "jumping" so frei durch die Gegend schwirrt, ohne das es bentutz wird, kann man hier von einem Fehler ausgehen.

Die Berechnung des Sprungs finde ich auch etwas seltsam. Normalerweise löst man das über die Momentangeschwindigkeit und die einwirkenden Beschleunigungen (typischerweise der Sprung nach oben und die Gravitation). Damit ist das System viel allgemeiner (falls zum Beispiel noch andere Kräfte hinzu kommen) und viel einfach zu implementieren.

Re: UnboundLocalError

Verfasst: Montag 27. Mai 2013, 09:45
von BlackJack
@Hall9000: Wenn man die Methode vereinfacht, kommt das hier dabei heraus:

Code: Alles auswählen

    def Jumping(self, manX, manY):
        if pygame.key.get_pressed()[K_UP]:
            self.jumping = True
            self.t = pygame.time.get_ticks() - pygame.time.get_ticks()
        if self.t <= self.JUMPING_DURATION:
            manY = 450 - self.jumpHeightAtTime(self.t)
        self.screen.blit(self.man, (manX, manY))
Insbesondere die Berechnung von `self.t` erscheint mir verdächtig falsch zu sein.

Re: UnboundLocalError

Verfasst: Montag 27. Mai 2013, 10:07
von Hall9000
@BlackJack ja 't' sollte eigentlich die Differenz zwischen zwei verschiedenen Zeitpunkten sein, weswegen ich 'jumpingStart = pygame.time.get_ticks()' und 'self.t = pygame.time.get_ticks() - jumpingStart' verwendet habe und diese in verschidenen Blöcken aufrufe
@EyDu andere Kräfte wolte ich vorerst vernachlässigen und evtl ganz weg lassen, ausserdem war meine Hauptintention Gestern Nacht dass die Fehlermeldung ausbleibt :D

Re: UnboundLocalError

Verfasst: Montag 27. Mai 2013, 10:14
von BlackJack
@Hall9000: Das was ich da gepostet habe ist *Dein* Quelltext vereinfacht, der tut also genau dasselbe wie Deiner. Wenn Du also meinst, das mein Quelltext nicht das richtige tut, dann macht Deiner das auch nicht. Du hast die Berechnung von `self.t` ja eben nicht in zwei verschiedenen Blöcken, sondern in einem. Das innere ``if`` wird hier *immer* ausgeführt wenn der Programmablauf bis dorthin gekommen ist.

Re: UnboundLocalError

Verfasst: Montag 27. Mai 2013, 10:24
von Hall9000
ich hab auch nie behauptet dass dein Sourcecode etwas Falsches täte sondern einfach nur gepostet, was ich ursprünglich mit 't' vorhatte, um zu zeigen wie ich zu meinem Problem kam

Re: UnboundLocalError

Verfasst: Montag 27. Mai 2013, 10:56
von snafu
EyDu hat geschrieben:Und da "jumping" so frei durch die Gegend schwirrt, ohne das es bentutz wird, kann man hier von einem Fehler ausgehen.
Ich könnte mir das so erklären, dass die Methode wohl mehrmals aufgerufen wird und einfach eine Art von Markierung setzt, wenn mit einem Sprung begonnen wurde. Und nach einer gewissen Zeit wird diese Markierung in einem erneuten Methodenaufruf wieder entfernt. Wir kennen ja den Rest des Quelltextes nicht. Und eigentlich ist das auch relativ egal. Wenn es ins Konzept des Threaderstellers passt, ist es doch in Ordnung. Ich sehe hier jedenfalls keinen klaren Anhaltspunkt, als dass man von einem Fehler sprechen könnte. Ich würde nur sagen, dass man auf lange Sicht überprüfen sollte, ob die Methode wirklich soviele verschiedene Fähigkeiten haben sollte, oder ob man lieber Teile davon auf andere Stellen auslagert.

Re: UnboundLocalError

Verfasst: Montag 27. Mai 2013, 11:59
von Hall9000
ich habe versucht alle Vorschläge zu beherzigen und die Methode umgeschrieben

Code: Alles auswählen

def Jumping(self,manX,manY):
	keys = pygame.key.get_pressed()
	if not self.jumping:
		if keys[K_UP]:
			self.jumping = True
			jumpingStart = pygame.time.get_ticks()
	if self.jumping:
		self.t = pygame.time.get_ticks() - jumpingStart
		if self.t > self.JUMPING_DURATION:
			self.jumping = False
	else:
		jumpHeight = jumpHeightAtTime(t)
	manY = 450 - jumpHeight
	self.screen.blit(self.man,(manX, manY))
'jumping' sollte jetzt besser verwendet werden, es wird keine Fehlermeldung ausgegeben und ob ich Teile auslagern muss, werd ich noch sehn

Re: UnboundLocalError

Verfasst: Montag 27. Mai 2013, 11:59
von EyDu
Es geht nicht um "self.jumping", sondern um "jumping". Und das sieht mir eher nach einem Fehler aus. Sei es, dass nur das "self" vergessen wurde.

@Hall9000: Ich wiederhole mich gerne noch einmal: steige auf Geschwindigkeiten und Beschleunigungen um ;-) Dein Ansatz ist wirklich sehr fragil und schreit gerade danach, dass der Spieler irgendwo in der Luft hängen bleibt. Und ich möchte mir gar nicht ausmalen wie schlimm es wird, falls du es doch mal erweitern willst. Die Umstellung ist zu diesem Zeitpunkt wirklich einfach und du gewinnst enorm an Flexibilität.

Re: UnboundLocalError

Verfasst: Montag 27. Mai 2013, 18:41
von Hall9000
@EyDu gut werd ich versuchen :) Die Bewegung des Spielers auf der x-Achse hab ich in die Levels gepackt (also dass sich der Hintergrund bewegt), sollte ich da dann auch umsteigen, dass sich der Spieler in x-/y- Richtung bewegt anstatt nur auf der y-Achse ?