Brettspieloberfläche erstellen

Plattformunabhängige GUIs mit wxWidgets.
Antworten
cromsche
User
Beiträge: 6
Registriert: Freitag 21. September 2007, 12:44

Hallo alle zusammen,

ich bastele seit geraumer Zeit an einem Abalone Spiel [1]. Das habe ich mit Python verknüpft, um die Sprache zu lernen. Das Spielf funktioniert, aber es auf einer TextKonsole zu spielen macht einfach keinen Spaß. Deshalb möchte ich mit wxPython eine Oberfläche erstellen. Zu wxPython habe ich schon einiges gelesen und auch schon ein wenig rumgespielt. Nur weiß ich noch nicht so recht wie ich das eigentliche Brett erstellen soll. Wie das Brett aussehen soll könnt ihr unter [2] sehen.

Mein Ansatz wäre das das Brett zu zeichnen und es in Felder zu unterteilen. Dabei wäre ein Feld so eine Stelle für die Spielkugeln.
Beim StandardAbalone sind es somit 61 Felder.
Ich würde dann die Spielffläche mit einem Mouseevent verbinden, um herauszufinden in welchem Feld ich mich befinden. Da weiß ich momentan noch nicht wie das gehen soll.

Meine Frage wäre ob man das so machen kann und was man am besten dafür benutzt? Ich schätze mal wxPaint.

Oder ist es besser das Spielfeld mit Hilfe von Bildern auf zu bauen?

[1] http://de.wikipedia.org/wiki/Abalone_(Spiel)
[2] http://de.wikipedia.org/wiki/Bild:Abalone.JPG
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hallo cromsche!

Willkommen im Python-Forum!

Es gibt natürlich (wie immer) mehrere Möglichkeiten. Da ich so etwas noch nicht programmiert habe, kann ich dir nur zeigen, wie ich es mit wxPython angehen würde. Das bedeutet aber nicht, dass es nicht bessere Möglichkeiten gibt.

Ich würde das Spielfeld als Bild hinterlegen (PNG) mit Transparenz für die Löcher. Damit kann man den Hintergrund frei wählen und unter das Spielfeld legen. Damit lässt sich so etwas http://upload.wikimedia.org/wikipedia/d ... ellung.JPG ziemlich leicht nachmachen.

Die Kugeln würde ich in ein wx.Window-Objekt zeichnen. Eine Farbe wird dabei verwendet um die Randflächen (außerhalb der Kugel) als transparent zu markieren. Wie das mit der Transparenz funktioniert? --> wxPython-Demo; suche nach "ShapedWindow". Dort wird auch aufgezeigt, wie man das Objekt mit der Maus verschieben kann.
Hier noch ein Beispiel: http://www.python-forum.de/topic-10260.html

Wenn das Window mit der Kugel verschoben wurde, dann musst du noch ausrechnen, ob der Mittelpunkt der Kugel sich in einem Feld befindet. Das ist dann das Zielfeld. -- Das eben verschobene Window wird im Zielfeld positioniert und die evt. verschobenen Kugeln werden nachgeführt. Das kannst du ja, wenn du Zeit hast, in mehreren Schritten erledigen. Dann sieht das wirklich so aus, als ob die Kugeln verschoben werden.

- Ganz unten ein Frame
- Dann ein Panel in welches das Hintergrundbild gezeichnet wird. Hintergrundbild als PNG, welches im Paint-Ereignis des Panels auf das Panel gezeichnet wird. Damit es schneller geht, solltest du hierfür den wx.BufferedPaintDC einsetzen.
- Darauf kommt dann ein Panel in welches das Spielbrett gezeichnet wird. Gleich wie beim Hintergrundbild gilt hier auch wieder: Bild als PNG; im Paint-Ereignis mit Hilfe des wx.BufferedPaintDC in das Panel zeichnen. Nicht vergessen, eine Farbe für die Transparenz angeben.
- Jede Kugel in ein Window zeichnen und auf dem obersten Panel (Spielfeld) verteilen. Je eine schwarze und eine weiße Kugel als Bitmap im Speicher hinterlegen. Je nach Farbe der Kugel wird im Paint-Ereignis mit wx.BufferedPaintDC in das Windows gezeichnet. Farbe für die Transparenz nicht vergessen.
- Die Windows (Kugeln) jeweils so programmieren, dass man sie mit der Maus verschieben kann. Siehe oben genanntes Beispiel.
- Nach dem Verschieben, die Kugeln neu positionieren. Evt. Kugeln neu anordnen.

Hier wird noch über die Schwierigkeiten mit der Transparenz diskutiert: http://www.python-forum.de/topic-11508.html
Vielleicht kannst du daraus etwas mitnehmen.

Mehr fällt mir im Moment dazu nicht ein.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
cromsche
User
Beiträge: 6
Registriert: Freitag 21. September 2007, 12:44

Hallo gerold und danke für die Antwort
gerold hat geschrieben:Darauf kommt dann ein Panel in welches das Spielbrett gezeichnet wird. Gleich wie beim Hintergrundbild gilt hier auch wieder: Bild als PNG; im Paint-Ereignis mit Hilfe des wx.BufferedPaintDC in das Panel zeichnen. Nicht vergessen, eine Farbe für die Transparenz angeben
Also muss ich erstmal das Spielfeld ausserhalb mit einem anderen Programm erstellen?! Wie meinst du das mit der Transparenz.
gerold hat geschrieben: Hier wird noch über die Schwierigkeiten mit der Transparenz diskutiert: http://www.python-forum.de/topic-11508.html
Vielleicht kannst du daraus etwas mitnehmen.
Irgendwie verstehe ich das Beispiel nicht so ganz. Zum Beispiel: was ist denn da transparent?
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

cromsche hat geschrieben:Irgendwie verstehe ich das Beispiel nicht so ganz. Zum Beispiel: was ist denn da transparent?
Hallo cromsche!

Es sind da noch ein paar Probleme zu lösen, aber so in etwa habe ich mir das vorgestellt:
http://gerold.bcom.at/bilder/spiel_beispiel.zip
Ich habe es gezippt, da auch Bilder enthalten sind.

Allerdings muss man sich im Beispiel noch mit dem Transparenz-Problem beschäftigen. :roll:
Dafür weiß ich im Moment keinen Rat.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
cromsche
User
Beiträge: 6
Registriert: Freitag 21. September 2007, 12:44

Gut das scheint bei mir nicht zu klappen, da Transparenz nur unter Windows funktioniert und ich mit linux arbeite. Hier dein Programm bei mir ausgeführt.

http://img236.imageshack.us/img236/8424/beispielmq4.png

Das werde ich mir etwas anderes überlegen. Ich habe mir schon überlegt das Spielfeld aus Kacheln zusammenzubauen. Also eine Kachel ohne Kugel, eine Kachel mit schwarzer Kugel, eine Kachel mit weißer Kugel. Wenn ein Spieler nun Kugeln verschieben will, klickt er auf die neue Position und es werden nur die Kacheln ausgetauscht, die auch verändert werden.
Nur hierbei stellt sich dann die Frage wie man es schafft, dass die Kacheln versetzt angeordnet werden wie man ermittelt in welche Kachel man gerade geklickt hat.

Eine andere Frage habe ich noch. Du verwendet in deinem Beispiel
die Funktion OnInit. Ich habe das immer in __init__() reingeschrieben. Ist das das gleiche?
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

cromsche hat geschrieben:die Funktion OnInit. Ich habe das immer in __init__() reingeschrieben. Ist das das gleiche?
Hallo cromsche!

OnInit ist der in wxPython vorgesehene Platz für die Programmlogik. Darin muss man sich nicht darum kümmern, dass die Applikation korrekt initialisiert wird und auch übergebene Parameter müssen nicht weitergegeben werden. Es macht die Sache also einfacher, wenn du OnInit und nicht __init__ für die Programmlogik heran ziehst.

Ansonsten gibt es, glaube ich, keinen relevanten Unterschied.

Was die Transparenz unter Linux betrifft: Das sollte eigentlich funktionieren. Nur habe ich keine Erfahrung damit und weiß jetzt nicht auf was man dabei aufpassen muss. Vielleicht funktioniert es unter Linux nur, wenn man eine "Farbe" für die Transparenz deklariert. Aber das müsste man ausprobieren.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
cromsche
User
Beiträge: 6
Registriert: Freitag 21. September 2007, 12:44

gerold hat geschrieben: Was die Transparenz unter Linux betrifft: Das sollte eigentlich funktionieren. Nur habe ich keine Erfahrung damit und weiß jetzt nicht auf was man dabei aufpassen muss. Vielleicht funktioniert es unter Linux nur, wenn man eine "Farbe" für die Transparenz deklariert. Aber das müsste
:-)
Irgendwie sprichst du hier von bömischen Dörfern für mich ;)

Ich habe mir jetzt mal wx bitmap anschgeschaut und das kann man eine maske setzen
wxpython hat geschrieben:This class encapsulates a monochrome mask bitmap, where the masked area is black and the unmasked area is white. When associated with a bitmap and drawn in a device context, the unmasked area of the bitmap will be drawn, and the masked area will not be drawn.
ist es dass was du mit farbe für die transparenz meinst?
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

cromsche hat geschrieben:da Transparenz nur unter Windows funktioniert
Hallo cromsche!

Ich muss noch einmal darüber nachdenken. wx.TRANSPARENT_WINDOW scheint wirklich nur unter Windows zu funktionieren.

Das ist zwar kein Problem für den Hintergrund und das Spielfeld. Die zeichnet man einfach in *ein* Panel zusammen. Mehr Probleme macht mir dabei die Kugel.
Das mit dem Verschieben ist so nicht mehr programmierbar. Es wäre kein Problem, wenn es ein Rechteck wäre, aber eine Kugel... :K

Vielleicht könnte man es so machen, dass man zuerst auf die Kugel klickt, den Mauscursor ändert und dann auf die Zielposition klickt.

...

Ich muss noch nachdenken.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

gerold hat geschrieben:Ich muss noch nachdenken.
Hallo cromsche!

http://gerold.bcom.at/bilder/spiel_beispiel2.zip

Es funktioniert hoffentlich jetzt auch unter Linux. Allerdings weiß ich noch nicht, wie man das Flackern beim Verschieben weg kriegt. Aber wie gesagt: ich habe mich noch nie mit so etwas befasst. Wo sind die Leute, die bessere Konzepte dafür haben.

Das sind nur mal ein paar Versuche von mir. Es gibt natürlich noch einige Probleme die gelöst werden müssen, wenn man das Spiel so erstellen würde. Es wird zum Beispiel schon viel komplizierter, wenn mehrere Kugeln im Spiel sind. Diese würde im Beispiel nicht unter der Kugel auftauchen die gerade verschoben wird, da ich ja nur das Spielfeldbild unter die Kugel blitte (mit dc.Blitt).

Wahrscheinlich geht so etwas mit pygame http://www.pygame.org/news.html einfacher. Damit habe ich allerdings keine Erfahrung. Vielleicht kann man dort im Tutorial nachlesen, wie man so etwas besser macht und vielleicht kann man das dann in wxPython auch ohne pygame so machen...

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
cromsche
User
Beiträge: 6
Registriert: Freitag 21. September 2007, 12:44

Hi gerold,

ich werde erstmal bei wxpython bleiben. pygame sieht nett aus, doch da fehlt mir die möglichkeit eine menubar zu nutzen. Jedenfalls habe ich auf die schnelle nichts davon gesehen.

Dein kleines Programm funktioniert bei mir noch nicht, da wxMemoryDC bei dir einen Wert übergibt, es aber keinen haben möchte. War bis jetzt aber zu faul mich mit dem Problem auseinander zu setzen.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

cromsche hat geschrieben:Dein kleines Programm funktioniert bei mir noch nicht, da wxMemoryDC bei dir einen Wert übergibt, es aber keinen haben möchte.
Hallo cromsche!

In wxPython 2.6 kann man an den MemoryDC das Bitmap noch nicht beim Initialisieren übergeben. Da läuft das so:

Code: Alles auswählen

dc = wx.MemoryDc()
dc.SelectObject(bmp)
Aber das Beispielprogramm läuft unter Linux sowiso noch nicht so wie es sein soll... und zum Experimentieren habe ich im Moment keine Zeit.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
cromsche
User
Beiträge: 6
Registriert: Freitag 21. September 2007, 12:44

Plattformunabhängigkeit wär mal so klasse :(
Antworten