pygame, fehler nach levelladen

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
Gertodunk
User
Beiträge: 11
Registriert: Freitag 8. Februar 2013, 17:41

Hallo,
ich mach gerade mit einem Freund ein pygame projekt für unser abi. Es is im Mario style und funktioniert auch ganz gut, nur hab ich ein problem:
In unserem spiel giebt es links, die verschiedene figuren /blöcke verbinden, doch wenn ich ein level speicher und wieder lade funktionieren diese nicht mehr und das obwohl alle bedingungen zu stimmen scheinen.

Code: Alles auswählen

    def effekt(self):
        if self.done == 0:
            print self.effect
            if self.effect == "destroy":
                for sprite in ALLSPRITES:
                    if sprite.number == self.number2:
                        sprite.kill()
                        done = 1
                        break
            elif self.effect == "create":
                for sprite in ALLSPRITES:
                    if sprite.number == self.number2:
                        sprite.spawned = 1
                        sprite.alive = 1
                        for enemy in DEADENEMIES:
                            if enemy.number ==self.number2:
                                enemy.add(ENEMIES)
                                enemy.remove(DEADENEMIES)
                        if DEADOBJECTS.has(sprite):
                                sprite.add(OBJECTS)
                                sprite.remove(DEADOBJECTS)
                        self.done = 1
                        break
            else:
                print "fehler"
wenn ich mir nun in der schleife self.effect printen lasse, gibt es "destroy" aus, trotzdem wird die destroy schleife nicht ausgeführt...
den Wert hat die Klasse davor durch einen import aus der leveldatei erhalten, die sie als text speichert. könnte es daran liegen, dass der wert irgendwie nicht als string anerkannt wird?
ich hab keine ahnung, wie ich hier weiterkommen soll und würde mich sehr über tipps freuen :)

danke im Vorraus
Max
Zuletzt geändert von Hyperion am Montag 1. April 2013, 11:49, insgesamt 1-mal geändert.
Grund: Code in Python-Code-Tags gesetzt.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Du könntest Dir ja mal *in* der Schleife den Wert von ``sprite`` ausgeben lassen oder direkt davor - im ``if`` - den Wert von ``ALLSPRITES`` (komischer Name btw!). Evtl. ist dieses Iterable einfach leer und deswegen passiert nichts.

Generell ist der Code wenig aussagekräftig - wir kennen den Aufbau drum herum nicht und können den Code auch nicht laufen lassen. Insofern kann man dazu wenig sagen.

Der Aufbau der ``effekt``-Methode ist auch suboptimal; es verstößt gegen das "Open Closed"-Prinzip. Du könntest Dir diese ``if...elif...else``-Kaskade ersparen, indem Du ein Mapping definierst, welches einen Effekt auf eine Methode (oder allgemein ein Callable) mappt:

Code: Alles auswählen

# als Klassenattribut oder Exemplarattribut (in __init__)
effect_dispatching = {
    "destroy": self.destroy,
    "create": self.create
}
# und die neue ``effekt``-Methode
def effekt(self):
    if not self.done:
        self.effect_dispatching[self.effect]()
Ich würde ggf. die Methoden (oder Funktionen) auch aus der Klasse auslagern, denn das riecht nach dem God-Class Anti-Pattern. Allerdings kenner ich die Klasse ja nicht und evtl. ist es auch sinnvoll, wenn ``create`` und ``destroy`` *in* der Klasse platziert sind.

Die Namensgebung ist übrigens krude... mal "effekt" mit "k" und mal ohne als Attribut... hm... das schreit geradezu nach Tippfehlern!

Zudem sollten Methode Namen haben, die auf Verben basieren; es soll ausgedrückt werden, *was* die Methode tut - ``effekt()`` klingt eher nach Susbstantiv...

Es gibt in Python einen Booleschen Typen, der ``True`` oder ``False`` sein kann. Nutzt den und nicht ``0`` und ``1`` in ``done``.

Namen mit Großbuchstaben weisen auf Modul globale Konstanten hin. Ich bezweifel, dass ``ALLSPRITES`` modul global sein soll. Und wenn ja, wäre das eher schlimm :-D

Alles in allem solltet Ihr euch mehr an PEP8 halten diesbezüglich und inhaltlich an Euren Namen feilen.

Last but not least: In Python spielt die EInrückung eine wichtige semantische Rolle. Wenn Du Code hier postest, dann benutze bitte die dafür vorhandenen Code-Tags! Ich konnte Deinen Beitrag oben "reparieren", so dass man sich das nun vernünftig angucken kann. Bitte denke da in Zukunft selber dran :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Gertodunk
User
Beiträge: 11
Registriert: Freitag 8. Februar 2013, 17:41

Also ersteinmal vielen dank für die ausführliche Antwort ! :)
ALLSPRITES ist eine group in der alle objekte, sowie Gegner gesammlt werden, und ja, die ist global, was ist daran so schlimm? :D
wir machen das alles noch nicht so lang, deshalb halten wir uns auch noch nicht so viel an das PEP schema, daran müssen wir noch arbeiten...
mein großes Problem ist noch, dass die schleife, auch, wenn ich noch vor dem for n in Allsprites... ein print einfüge nicht ausgeführt wird, es liegt also nicht daran, dass die schleife leer ist, das programm geht überhaupt nicht in die schleife rein...
Auch würde ich mich sehr freuen, wenn du mir noch einmal kurz das "open-closed-prinzip" und das "god class pattern" erklären könntest, so ganz verstanden hab ich das noch nicht ...

vielen Dank für die Schnelle Antwort !!
Max
BlackJack

@Gertodunk: Das die Schleife nicht leer ist sehen wir ja (ganz leer geht in Python syntaktisch sowieso nicht, da müsste mindestens ein ``pass`` drin stehen), aber was ist mit `ALLSPRITES`? Sind da zu dem Zeitpunkt überhaupt Objekte enthalten?
Gertodunk
User
Beiträge: 11
Registriert: Freitag 8. Februar 2013, 17:41

ja, aber er führt die schleife überhaupt nicht aus, wenn ich in die schleife z.B. print "test" einfüge, dann wird das nicht ausgeführt und das obwohl die bedingung dafür eigentlich erfüllt wäre, ich hab mir die condition ja vorher ausgeben lassen...
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Gertodunk hat geschrieben: Auch würde ich mich sehr freuen, wenn du mir noch einmal kurz das "open-closed-prinzip" und das "god class pattern" erklären könntest, so ganz verstanden hab ich das noch nicht ...
Äh...nö :-D Das sind schon fortgeschrittene Themen, die ich hier "nur" erwähnt habe, um das ganze mit gängigen Konzepten aus dem OOP Bereich zu untermauern.

Ich hatte - genau wie BlackJack - schon auf ``ALLSPRITES`` hingewiesen; evtl. ist dieses Iterable einfach *leer* und deswegen wird der Schleifenrumpf *nie* durchlaufen?

Und ja, globale Variablen sind grundsätzlich schlecht. Da gibt es nur wenige Ausnahmen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Gertodunk hat geschrieben:ja, aber er führt die schleife überhaupt nicht aus, wenn ich in die schleife z.B. print "test" einfüge, dann wird das nicht ausgeführt und das obwohl die bedingung dafür eigentlich erfüllt wäre, ich hab mir die condition ja vorher ausgeben lassen...
Die Bedingung für das if mag ja erfüllt sein, aber wenn ALLSPRITES leer ist, dann wird die darüber iterierende for-Schleife natürlich nicht durchlaufen. Mach doch einfach mal außer print "test" auch noch print ALLSPRITES und schau mal was dabei herauskommt.
Gertodunk
User
Beiträge: 11
Registriert: Freitag 8. Februar 2013, 17:41

danke, problem gelöst !
in der string variable, die die schleife gesteuert hat war beim speichern durch nen fehler noch \n am ende drin, deshalb wurde die schleife nicht ausgeführt, ich hab das aber nich sehen können, weil mir cmd \n als zeilenumbruch angezeigt hat, für mich sah das so aus, als sei die bedingung erfüllt

vielen dank für die vielen Antworten !

max
Antworten