Space Invader

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Hallo,

Spielen ist schon möglich - Menu fehlt noch. Wenn die Feinde in die Schutzwand laufen, gibt es eine Fehlermeldung, doch eigentlich ist das Spiel in dem Moment vorbei - oder ?

http://www.python-forum.de/pastebin.php?mode=view&s=128

Gruß Frank

edit: Zeile 108 muss auf 5 gesetzt werden und nächste Zeile auf 11
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Wow, ich bin erstaunt, das du das mit diesem Spaghetticode, tatsächlich noch durchgehalten hast. :)
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Benutzeravatar
HerrHagen
User
Beiträge: 430
Registriert: Freitag 6. Juni 2008, 19:07

Bevor die Kritiker mit den Anmerkungen zum Code kommen: Cool. Es funktioniert und spielt sich gar nicht mal schlecht.
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Hallo Herr Hagen,

danke für das Lob !

gestartet wurde das Projekt hier: http://www.python-forum.de/viewtopic.php?f=18&t=25050
danke für den Tip von Xynon1 !

Gruß Frank
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Benutzeravatar
HorstJENS
User
Beiträge: 123
Registriert: Donnerstag 9. Februar 2006, 21:41
Wohnort: Wien, Österreich
Kontaktdaten:

nicht schlecht, gratuliere !
http://spielend-programmieren.at
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

So viel Spaghetti ist das gar nicht. Allerdings sind schon ein paar verbesserungswürdige Sachen drin. Zum Beispiel sollten die ganzen Eigenschaften der Gegner in *einer* Datenstruktur, zum Beispiel einem Dictionary oder Klasseninstanzen, gespeichert werden.

Und die ganzen Irgendwas-Berechnen-Monster versteht natürlich kein Mesch. Versuch mal, das noch auszulagern. Vielleicht hilft es, sich selbst ein Maximal-Einrückungs-Limit von 4 (inklusive Methoden-Einrückung) zu setzen.

``InvadersGui.run`` ist auch so ein Monstrum, das man lieber ganz schnell aufräumen sollte. Da ist auch ganz viel relativ ähnlicher Code, das könnte man vielleicht etwas abstrahieren und somit 80% der Zeilen sparen.

So jetzt werd ich das ganze mal spielen. :)
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Hallo !

@HorstJENS: Danke !

@Dauerbaustellle: Die Berechnungen waren nur zur Kollisionserkennung und ich habe eine Klasse daraus gemacht. Die Gui.run() ist oft gleich, da ich nur neu benötigte Images zeichne. Würde ich alles löschen und komplett neuzeichnen, dann würde die Performance leiden. Bei dieser Vorgehensweise könnte man alles zusammen zeichnen.

nächste Version --> http://www.python-forum.de/pastebin.php?mode=view&s=135

Gruß Frank
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

kaytec hat geschrieben:@Dauerbaustellle: Die Berechnungen waren nur zur Kollisionserkennung und ich habe eine Klasse daraus gemacht. Die Gui.run() ist oft gleich, da ich nur neu benötigte Images zeichne. Würde ich alles löschen und komplett neuzeichnen, dann würde die Performance leiden. Bei dieser Vorgehensweise könnte man alles zusammen zeichnen.
Das hat überhaupt nichts mit Performance zu tun. Ich spreche ja nicht davon, dass du das Verhalten des Programms an sich ändern sollst, sondern nur den Code einfacher machen.

``check_collision`` ist ein totales Monster. Das versteht kein Mensch. Teile das in mehrere, logisch zusammengehörende Teile auf. Ich verstehe zwar nicht, was genau das Ding macht, aber angenommen, es würde zwei Rechtecke auf Kollision überprüfen, dann könnte man das aufteilen in die vier Ecken des einen Rechtecks. Ein anderer Trick, um sowas lesbarer zu machen, ist auf Einrückung zu verzichten. Außerdem kann man

Code: Alles auswählen

if a and b or c .... usw: return True
auch schreiben als

Code: Alles auswählen

return a and b or c .... usw
.

Kann es sein, dass ``check_collisions`` bzw das Closure ``check`` in selbigem sich überschneiden mit dem Inhalt von ``check_collision``? Wenn ja, würde man das auch irgendwo auslagern.
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Hallo Dauerbaustelle,

danke für Deine Anregungen - nur vertsehe ich sie gerade nicht so. Habe auch gerade keine Zeit, deswegen mache ich mir Gedanken und mache mal ein abgespecktes Beispiel für die Kollisionsabfrage. WIe ich die Gui.run() verkleinern soll ist mir auch noch rätselhaft ?

Gruß Frank
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Code: Alles auswählen

if self.invaders.base.next_base == False:
    self.delete(BASE_TAG)
    self.create_image(self.invaders.base.position[0], 
        self.invaders.base.position[1], 
            image = self.invaders.base.img, 
                tag = BASE_TAG)
else:
    self.delete(BASE_TAG)
    self.create_image(self.invaders.base.position[0], 
    self.invaders.base.position[1], 
        image = self.invaders.base.hit_imgs[
            self.invaders.base.hit_img_index], tag = BASE_TAG)
lässt sich z.B. ausdrücken als

Code: Alles auswählen

if not self.invaders.base.next_base:
    image = self.invaders.base.img
else:
    image = self.invaders.base.hit_imgs[self.invaders.base.hit_img_index]
self.delete(BASE_TAG)
self.create_image(self.invaders.base.position[0], 
    self.invaders.base.position[1], image=image, tag=BASE_TAG)
was sehr viel deutlicher ist, weil man verseht, welchen Zweck die Bedingung hat (nämlich das anzuzeigende Bilde auszuwählen und sonst nichts).
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

@Dauerbaustelle
Wieso "if not ...: else:" ?

Und für "self.invaders.base.position[0], self.invaders.base.position[1]", sollte eigentlich auch "*self.invaders.base.position", wenn es eine Sequenz ist.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
BlackJack

@kaytec: Die `run()` kürzer zu schreiben muss auch nicht bedeuten, dass das Programm insgesamt kürzer wird. Ich würde den Inhalt zum Beispiel auf mehrere Funktionen verteilen, denn da gibt es ja mehrere logische Abschnitte die jeweils eine unabhängige Teilaufgabe verrichten.

Das oft so tief in Datenstrukturen durchgegriffen wird und dann auch noch in jedem logischen Abschnitt der gleiche Präfix bei diesen Durchgriffen steht, legt auch nahe, dass der Code wahrscheinlich in der falschen Klasse steht.

In dem Stückchen was Dauerbaustelle da eben zitiert beziehungsweise modifiziert hat, steht zum Beispiel viel zu oft ``self.invaders.base``. Das sieht so aus als wenn das was da an Code steht, eher in die Verantwortung von was immer auch `base` ist, gehört.
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Hallo !

@ Dauerbaustelle: Ja, ok - das könnte auch so gehen und sieht auch schöner aus.
@ Xynon!: Die einzelnen Objekte haben verschiedene Eigenschaften und die ersten beiden Positionen sind die Koordinaten - deswegen lese ich sie über den Index aus.
@BlackJack: next.base ist der Player und dieses Verhalten hat natürlich Auswirkungen auf das ganze Spiel. Daher der tiefe Eingriff - war halt meine Lösung zur Kontrolle des Spieles.

irgendwie bin ich ja Masochist - gebe es für die "Codefledder" frei und komme nicht mit den Antworten bzw. Lösungen nach :-)

Gruß Frank
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Hallo !

Hatte mal wieder Zeit und habe eine Beispiel zur Kollisionsabfrage gebastelt.

http://www.python-forum.de/pastebin.php?mode=view&s=137

Mit "space" start und mit <- & -> lenken.

Gruß Frank
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Niemals __magische_methoden__ manuell aufrufen. (``self.test.__init__``)
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

Hallo Dauerbaustelle !

Was sind __magische_methoden__ ?

Gruß Frank
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

kaytec hat geschrieben:Was sind __magische_methoden__ ?k
Alles mit zwei Unterstrichen vor und nach dem eigentlichen Namen, also z.B. ``__init__``, ``__len__`` usw. http://docs.python.org/reference/datamo ... thod-names

Die werden von Python selbst (also dem Interpreter) benutzt und sind nicht dazu gedacht, in Python-Code aufgerufen zu werden.
Benutzeravatar
kaytec
User
Beiträge: 608
Registriert: Dienstag 13. Februar 2007, 21:57

@ Dauerbaustelle danke - also besser ist in diesem Fall self.test = Test() oder öfters aufrufen ist auch nicht gut ?

Gruß Frank
Antworten