Seite 1 von 2

Space Invader

Verfasst: Mittwoch 19. Januar 2011, 23:19
von kaytec
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

Re: Space Invader

Verfasst: Donnerstag 20. Januar 2011, 07:54
von Xynon1
Wow, ich bin erstaunt, das du das mit diesem Spaghetticode, tatsächlich noch durchgehalten hast. :)

Re: Space Invader

Verfasst: Donnerstag 20. Januar 2011, 19:19
von kaytec

Re: Space Invader

Verfasst: Freitag 21. Januar 2011, 00:03
von HerrHagen
Bevor die Kritiker mit den Anmerkungen zum Code kommen: Cool. Es funktioniert und spielt sich gar nicht mal schlecht.

Re: Space Invader

Verfasst: Freitag 21. Januar 2011, 08:58
von kaytec
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

Re: Space Invader

Verfasst: Freitag 21. Januar 2011, 12:47
von kaytec

Re: Space Invader

Verfasst: Samstag 22. Januar 2011, 22:41
von HorstJENS
nicht schlecht, gratuliere !

Re: Space Invader

Verfasst: Samstag 22. Januar 2011, 23:56
von Dauerbaustelle
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. :)

Re: Space Invader

Verfasst: Montag 24. Januar 2011, 13:35
von kaytec
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

Re: Space Invader

Verfasst: Montag 24. Januar 2011, 14:04
von Dauerbaustelle
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.

Re: Space Invader

Verfasst: Montag 24. Januar 2011, 15:35
von kaytec
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

Re: Space Invader

Verfasst: Montag 24. Januar 2011, 16:10
von Dauerbaustelle

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).

Re: Space Invader

Verfasst: Montag 24. Januar 2011, 16:28
von Xynon1
@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.

Re: Space Invader

Verfasst: Montag 24. Januar 2011, 16:37
von 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.

Re: Space Invader

Verfasst: Montag 24. Januar 2011, 19:20
von kaytec
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

Re: Space Invader

Verfasst: Donnerstag 27. Januar 2011, 20:51
von kaytec
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

Re: Space Invader

Verfasst: Donnerstag 27. Januar 2011, 21:25
von Dauerbaustelle
Niemals __magische_methoden__ manuell aufrufen. (``self.test.__init__``)

Re: Space Invader

Verfasst: Donnerstag 27. Januar 2011, 21:29
von kaytec
Hallo Dauerbaustelle !

Was sind __magische_methoden__ ?

Gruß Frank

Re: Space Invader

Verfasst: Donnerstag 27. Januar 2011, 21:42
von Dauerbaustelle
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.

Re: Space Invader

Verfasst: Donnerstag 27. Januar 2011, 21:46
von kaytec
@ Dauerbaustelle danke - also besser ist in diesem Fall self.test = Test() oder öfters aufrufen ist auch nicht gut ?

Gruß Frank