hackfleisch89ru - ein OpenSource 2D shooter

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Antworten
SyrischerRaubelefant
User
Beiträge: 14
Registriert: Sonntag 7. Januar 2007, 20:59

Hallo allerseits,

mit diesem Thread möchte ich mein kleines Spiel vorstellen: hackfleisch89ru

Es handelt sich hierbei um einen einfachen 2D shooter. Als Grafikausgabe verwende ich pygame. Das Spiel beinhaltet einen "Zufalls-Level-generator", auch wenn die generierten levels noch recht chaotisch aussehen.
Außerdem besteht die Möglichkeit, levels aus Textdateien zu laden.
(Jedoch habe ich, nur einein einzigen level mitgeliefert, welcher kaum was enthält. Der Schwerpunkt des Spiels liegt auf den zufällig generierten maps)

Hier ein screenshot für den Vorgeschmack:
http://img88.imageshack.us/img88/1930/screenshotiw7.jpg

Das Spiel (also auch den Quellcode) kann man hier runterladen (*.tar.gz):
http://rapidshare.com/files/181792820/h ... ar.gz.html

oder alternativ(*.tar.gz):
http://www.speedshare.org/download.php?id=D19CDA5112

oder alternativ (*.7z):
http://www.speedshare.org/download.php?id=EA41149813

Steuerung:
ESCAPE: Hauptmenü
W,A,S,D = Bewegen
Rechte Maustaste: gehe zu cursor
Linke Maustaste: normal schiessen (schnell)

linke STRG taste: 3er Schuss
LEERTASTE: explosiver Schuss.

Ich möchte mich im vornherein über die niedrige FPS rate entschuldigen :(

Ich würde mich über ernst gemeinte Kritik freuen :)
(sowohl auf das gameplay bezogen als auch auf den code)

MfG, alex89ru
Zuletzt geändert von SyrischerRaubelefant am Samstag 10. Januar 2009, 21:36, insgesamt 5-mal geändert.
Besuch uns im euIRC:
server: irc.euirc.net
channel: #alle_in_den_chat
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Also ich bekomme den Download da nicht hin ... schade, hätte da gerne mal reingeguckt!
SyrischerRaubelefant
User
Beiträge: 14
Registriert: Sonntag 7. Januar 2007, 20:59

Hyperion hat geschrieben:Also ich bekomme den Download da nicht hin ... schade, hätte da gerne mal reingeguckt!
Wie? Also be mir geht die rapishare-url. Komisch. Wo liegt denn das Problem?

Gehe auf den link.
Klicke auf "Free User".
Warte die Angegebene zeit ab (45 sec ?!?)
Klicke dann auf den runden Button "Download".

:)
Besuch uns im euIRC:
server: irc.euirc.net
channel: #alle_in_den_chat
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hi

Benutz doch andere Filesharer ohne Wartezeit.
Z.B. box.net oder filesavr.com

Gruss
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Jetzt geht es ... allerdings *****lahm ;-)

Wieso ist das ganze denn so groß bitte schön? (31.2MB!)
SyrischerRaubelefant
User
Beiträge: 14
Registriert: Sonntag 7. Januar 2007, 20:59

Hyperion hat geschrieben:Jetzt geht es ... allerdings *****lahm ;-)

Wieso ist das ganze denn so groß bitte schön? (31.2MB!)
Das ist so groß & lahm wegen der großen Hintergrunddateien.
Besuch uns im euIRC:
server: irc.euirc.net
channel: #alle_in_den_chat
lunar

Ich würde mal schätzen, dass da ein paar Graphiken und Sounddateien dabei sind.

@alex89ru
Verständlicherweise mag nicht jeder Rapidshare. Wenn du dir einen anderen Hoster suchst, findest du bestimmt ein größeres Publikum (mich z.B. auch).
SyrischerRaubelefant
User
Beiträge: 14
Registriert: Sonntag 7. Januar 2007, 20:59

Okay. Ich werde es mal bei einem anderen hoster hochladen. Kann ein bisschen dauern.
Besuch uns im euIRC:
server: irc.euirc.net
channel: #alle_in_den_chat
SyrischerRaubelefant
User
Beiträge: 14
Registriert: Sonntag 7. Januar 2007, 20:59

Okay, eben nochmal hochgeladen:

http://www.speedshare.org/download.php?id=D19CDA5112

EDIT: Wer Performanceprobleme hat, kann die Auflösung ändern. Leider hab ich für das Ändern der Auflösung kein user-interface beereitgestellt.
Die Auflösung kann man folgendermaßen ändern:
Öffne "main.py" mit ner IDE/Texteditor und editiere in Zeile 26:

Code: Alles auswählen

w, h = 1024, 768
in

Code: Alles auswählen

w, h = 800, 600
Das dürfte schon einiges mehr an Performance bringen (bei mir steigt die FPS von 30 auf 50 an)

:)
Besuch uns im euIRC:
server: irc.euirc.net
channel: #alle_in_den_chat
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Also sieht schon ganz nett aus!

Allerdings emfpinde ich die Steuerung als unintuitiv. Damit komme ich nicht wirklich klar. Außerdem bleibt die Spielfigur oft an Wänden hängen.

Die Hintergrundbilder sehen zwar ganz nett aus, aber farblich sind die Kontraste nicht so gut gelungen. Außerdem könntest Du die Bilder doch ein wenig mehr packen - es will ja niemand den Hintergrund irgend wo ausdrucken ;-)

Evtl. würde ich den Background auch aus Tiles aufbauen - das würde auch noch Ressourcen sparen.

In den Code habe ich noch nicht viel reingeguckt.
Grober
User
Beiträge: 2
Registriert: Samstag 10. Januar 2009, 23:09

Hallo,

die kotzende Hackfleischfresse (der Spezialmodus) gefällt mir extrem gut^^
SyrischerRaubelefant
User
Beiträge: 14
Registriert: Sonntag 7. Januar 2007, 20:59

Hyperion hat geschrieben:Also sieht schon ganz nett aus!

Allerdings emfpinde ich die Steuerung als unintuitiv. Damit komme ich nicht wirklich klar. Außerdem bleibt die Spielfigur oft an Wänden hängen.

Die Hintergrundbilder sehen zwar ganz nett aus, aber farblich sind die Kontraste nicht so gut gelungen. Außerdem könntest Du die Bilder doch ein wenig mehr packen - es will ja niemand den Hintergrund irgend wo ausdrucken ;-)

Evtl. würde ich den Background auch aus Tiles aufbauen - das würde auch noch Ressourcen sparen.

In den Code habe ich noch nicht viel reingeguckt.
Erstmal danke für die Kritik :)

Zur Steuerung: Diese WASD-Steuerung ist angelehnt an Spiele wie cs2d, bei denen ego-shooter-artige Steuerung zum Einsatzkommt, wobei die jeweilige Bewegungsichtung von der Blickrichtung abhängt. Alternativ kann man auch die rechte Maustaste benutzen, jedoch wird dann das Ausweichen der Kugeln schwieriger.
Ich muss mir überlegen wie ich die Steuerung verbessern könnte, aber im Moment fällt mir nicht ein, wie ich die Steuerung so verändern könnte und gleichzeitig das Ausweichen der Geschosse möglich sein soll.

@Grafiken: Die PNG Dateien sind bereits auf dem höchsten Kompressionsgrad (in GIMP erstellt, Kompressionsgrad 9). Tiles wären natürlich eine gute Idee, jedoch habe ich von Anfang an einfachheitshalber darauf verzichtet, da das Spiel einfach gehalten werden sollte. Leider sind die CPU/RAM Anforderungen jetzt entsprechend hoch.
Besuch uns im euIRC:
server: irc.euirc.net
channel: #alle_in_den_chat
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Grober hat geschrieben:Hallo,

die kotzende Hackfleischfresse (der Spezialmodus) gefällt mir extrem gut^^
*g* Stimmt ;-)

Was mir noch auffiel:
Die Level sind ... naja, relativ wenig mit Hindernissen gesäht! Also da sehe ich keine große Stärke drin - auch wenn Du das angepriesen hast ;-)
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Horst Schluchts hat geschrieben:Meine Meinung dazu:
http://www.youtube.com/watch?v=ZnJg7QQIlU4
Als Startbeitrag im Forum nicht gerade optimal. Naja, wer weiß, vielleicht ist es ja auch dein letzter Beitrag ...
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

numerix hat geschrieben:Als Startbeitrag im Forum nicht gerade optimal. Naja, wer weiß, vielleicht ist es ja auch dein letzter Beitrag ...
Den musst du aber dann nicht zitieren, da jetzt der Spam auch noch in deinem Posting steht. Da das ein Spammer war, habe ich den Beitrag auch gelöscht, das wäre schon der dritte den ich aus diesem Thread gelöscht habe.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Jetzt wollte ich doch tatsächlich die Spielbedingungen etwas anpassen und hab die <game>.player.hp's auf 1000 hochgesetzt und siehe da:
Traceback (most recent call last):
File "main.py", line 127, in <module>
g.draw(screen)
File "/media/Daten/Projects/hackfleisch89ru/hackfleisch89ru/pyage.py", line 1287, in draw
self.draw_player_panel(dest)
File "/media/Daten/Projects/hackfleisch89ru/hackfleisch89ru/pyage.py", line 1275, in draw_player_panel
surf = self.font.render(render_string, True, player_panel_color)
TypeError: Invalid foreground RGBA argument
Cheater's always get their Punishment? :D

Also rein äusserlich super! Zum Code:

1. Der Traceback: Du benutzt an der Stelle im Code die hp Anzahl um die Farbe zu berechnen. Wo ist da die Logik? Das hat doch gar nichts miteinander zu tun.

2. Du hast keinen einzigen Docstring benutzt. Unglaublich praktische Dinger das sind.

3. Dein Code ist sehr zentralistisch angelegt. Du machst bis auf 4 Callback Funktionen absolut alles in den Klassen, von Datei laden bis "eigenes Animationsformat parsen". Du hast auch viele lose Methoden an die Klassen gebunden, die sogar sehr allgemein gehalten sind (load_image). Die Klassen sind total überladen und haben zig Methoden, "game" ist ein richtiges Gottobjekt. Die Klassen kennen sich untereinander sehr genau und benutzen sich in den unterschiedlichsten Teilen des Codes. Wenn man Klassen mehr als einmal initialisieren muss sollte man imho eine klassenglobale Referenz erstellen anstatt jedesmal direkt drauf zu referieren oder den entsprechenden Code in allgemeine Funktionen auslagern.

4. Überall irgendwelche Zahlen und Rechenoperationen, Strings mit denen man auf scheinbar wichtige Zustände und Objekte referiert. Sollte man in globale Konstanten umwandeln und solche kleineren Rechnereien auf das Minimum beschränken und nicht unkommentiert stehen lassen. Auch greifst du einfach mal über den Index auf eine Sequenz zu, die du aus einer Datei geholt hast. Kann man natürlich machen, aber solche hardkodierten Werte vermeidet man besser oder sagt was dazu. (Es sei denn man nutzt einen Tupel als "Struct", sowas sollte aber transparent sein - Listen würde ich prinzipiell nur mit dynamisch generierten Index Werten behandeln, wenn überhaupt)

5. Generell Duplikation. Da ist dein Code schon deutlich besser im Gegensatz zu dem, was ich schon gesehen habe, aber es sind immernoch einige drin. Zum Beispiel die Rechnenoperationen. Jede Ecke an der ein längerer Codeteil sitzt zusammen mit if / elif's oder auch allein riecht schon nach besserer Aufteilung.

6. Du benutzt Strings um auf Klassen in Dicts zuzugreifen. Python ist eine sehr dynamische Sprache, du kannst die Klassen direkt referieren. Du kannst in Python absolut jedes Objekt (und alles ist ein Objekt) herumreichen, irgendwo eintragen, in eine Liste stecken und darüber gemeinsam iterieren etc. (Außer natürlich die eines der entsprechenden Objekte erlaubt das nicht; Also, daß man beispielsweise in Dict's keine Listen als Keys verwenden kann ist so eine Einschränkung, die hat aber auch einen Grund).

7. Deine Klassen sind alle Oldstyle Klassen.

8. Ein paar Kommentare mehr schaden nie.

9. Trennung von Logik und GUI ist nicht gegeben. Du hast wie gesagt auch eine sehr starke Bindung zwischen den einzelnen Komponenten. Kapselung einzelner Verantwortlichkeiten nur durch Methoden.

10. Du hast an manchen Stellen komplett toten Code rumliegen, was sich in trivialen Syntaxfehlern äussert. In Zeile 1222 steht zum Beispiel "vec,y".

11. Die Exceptions, die du abfängts, lassen die Methoden frühzeitig zurückkehren oder setzen einen Parameter auf None. Was soll das? Wenn du eine Exception nicht sinnvoll behandeln kannst, dann lass sie durch und schreib einen Kommentar in den Code, der erläutert warum. Wenn du in load_image() einen Fehler hast, wird self.image auf None gesetzt und dein rect bekommt nichtmal einen ordentlichen size Parameter. Wenn es dann 500 Meter weiter deswegen kracht, bekommst du einen AttributeError auf None oder schlimmer, einen Fehler wegen einer falschen Rect Size, und du wunderst dich erstmal woher das nun kommt.

12: Den Code in main würde ich in eine main() Funktion stecken. Dann wird der Code nicht direkt ausgeführt und du hast einen einheitlichen Startpunkt. Moduleebenen Code ist meist unschön. Damit bei einem direkten Start main() ausgeführt wird, trage das am Ende von main.py ein:

Code: Alles auswählen

if __name__ == "__main__":
    main()
__main__ ist der Name eines Modules, das direkt gestartet wird.

13. Du solltest Pygame Images mit convert() konvertieren, sonst wird immer die PNG Datei angesprochen. Dadurch wird dein Code nur langsamer.

14. Du benutzt pygame.display.flip(). Damit wird dein Display in jedem Durchlauf der Schleife komplett geupdatet. Das ist natürlich langsam. Schau dir mal auf pygame.org unter Tutorials die 12 Tipps oder wie es hieß an. Du kannst dir auch mal meinen Tetris Klon Tetrix0r anschauen, da arbeitet ich mit einer Liste, die die zu aktualisierenden Rect's enthält. (Der Code ist aber schon älter und nicht der schönste; findest du hier im Forum).

15. Warum benutzt du die Event Schleife und xyz.get_pressed()?

So, das wäre das gröbste - Schlussendlich mein Rat: PEP8 lesen, import this ausführen und Single Responsibility beachten ^_^

Achja; schau dir mal das Tool Pylint an. Das zeigt dir sehr viele, vor allem stylistische, Problematiken automatisch an. Sollte dir helfen. Aber Achtung, du wirst bei deiner pyage.py fast erschlagen vor Meldungen.
SyrischerRaubelefant
User
Beiträge: 14
Registriert: Sonntag 7. Januar 2007, 20:59

Also erstmal danke für alle Tips :)
Du benutzt an der Stelle im Code die hp Anzahl um die Farbe zu berechnen. Wo ist da die Logik? Das hat doch gar nichts miteinander zu tun.
Die HP-Anzeige oben links im Bild ändert ihre (Vordergrund-) Farbe je nach HP Anzahl.
Bei vollem HP ist die Schrift weiß. Je mehr man getroffen wird, also je weniger HP man hat, desto "roter" wird die Schrift, bis es schließlich blutrot bei "HP = 0 = tot" wird. Damit wollte ich dem user die Möglichkeit geben, frühzeitig gewarnt zu werden, wenn die HP niedrig ist ohne dass der user direkt auf die HP-Anzeige schauen muss. (Falls man mit den Gegnern beschäftigt ist und gerade nicht von einer HP-Zahl abgelenkt werden will, fällt einem das rote im oberen Bildbereich gewiss auf)

Woher der Fehler jetzt herkommt, muss ich mir später genauer anschauen, bin grad zu müde.
Besuch uns im euIRC:
server: irc.euirc.net
channel: #alle_in_den_chat
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Das sollte man aber nicht direkt über die hp Anzahl regeln, sonst wird sowas total untransparent. Du könntest zum Beispiel einen Tupel anlegen, der die einzelnen Untertupel mit den Farben enthält. Dann berechnest du einfach "round(start_hp / jetzige_hp)" und benutzt den herauskommenden Wert als Index für den Tupel und Ende. Für solche Zwecke sind Tupel mitunter auch gedacht, als eine Art "struct". Hast du Beispielsweise nur noch 200 HP, kommt der Wert 3 raus -> Sollte dann natürlich schon recht rot sein.

Werde übringens eine Woche vermutlich nicht antworten können, nur damit du dich nicht wunderst.

EDIT: Gut, strebt so natürlich etwas stark gegen große Zahlen, insofern müsstest du das noch etwas einschränken oder einfach auf 25 % usw überprüfen, aber war der erste Gedanke.
Antworten