verdammt, ich kapier es einfach nicht

Fragen zu Tkinter.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

BlackJack hat geschrieben:@numerix: Ohne mir den Frosch jetzt angeschaut zu haben: Kann es sein, dass der *absichtlich* langsam ist, damit man ihm beim Zeichnen zuschauen kann? Das ist doch im Grunde so'n "Lerndingens" wie die Schildkröten, oder?
Ja und nein.

Das frog Modul ist vergleichbar mit dem xturtle Modul. Beiden gemeinsam ist die Idee einer Figur (Frosch/Kröte), die Zeichenoperationen vornimmt. Zielgruppe dürften vor allem Jugendliche/Schüler sein. Also: "Lerndingens" ja.

Allerdings bietet frog (und xturtle auch) die Möglichkeit, die Geschwindigkeit des Froschs einzustellen, damit man zuschauen kann oder eben nicht (man kann den Frosch auch unsichtbar machen). Im Fall des Hexagon-Spielfeldes braucht der Frosch aber auch bei maximaler Geschwindigkeit auf meinem (nicht sehr modernen) Rechner > 10 sec für den Spielfeldaufbau ...
derkai
User
Beiträge: 169
Registriert: Montag 12. Mai 2008, 11:43

also, die Geschwindigkeit auf speed ="max" zu setzen bringt bei
mir leider gar nix. das ist noch viel viel langsamer als die Annimation komplett auszuschalten.

Tja, das Spielbrett muss noch ganz viele Dinge können. Machen wir
einfach einmal damit weiter, dass ich auf die einzelnen Felder wieder zugreifen muss. Ebenso muss die Farbe später ausgelsenen werden.

Ich habe nun eine Methode "lastitem" gefunden. Damit kann man
jeweils immer die Kennunz des letzten Feldes auslesen. Ziel soll wohl sein, dass man dann jeweils das letzte Element wieder löschen kann.

Kann man mit dieser Kennung nicht dann sonst noch etwas tun ?

Falls nein, dann müßte ich irgendwie ein "NETZ" über die Felder legen, um die Position jedes einzelnen später wieder bestimmen zu können.

___

Frage 2 :

Man kann den Pool wiederum auch einer Tkinter GUI übergeben.
Lt. Anweisung : teich = Pool(root=frame)

Was beduetet das genau, und welchen Vorteil habe ich dadurch ?

Nehmen wir an, ich erzeuge eine Instanz der Klasse Canvas.
Was bringt es ?

Kai
imac
20 Zoll
2,4 ghz
derkai
User
Beiträge: 169
Registriert: Montag 12. Mai 2008, 11:43

.. die Positionierung der Panzer,
aber auch die Methode distanceto wären in Frog schon sehr hilfreich.

Deswegen auch meine Frage, ob es dann nicht sinnvoll wäre
es in Tkinter gui einzubinden ?

Kai
imac
20 Zoll
2,4 ghz
derkai
User
Beiträge: 169
Registriert: Montag 12. Mai 2008, 11:43

ich habe es auch noch einmal umgesdtellt :

Code: Alles auswählen

from frog import *
from random import *

size = 20                               #Groesse Hexfeld

pool = Pool(width=1024,height=768) #Groesse Pool Spielflaeche
frog = Frog(pool)

level1=182,116,23                       #braun = Boden                
level2=13,166,20                        #gruen = Wald
level3=53,66,244                        #blau  = Wasser

Level = (level1,level1,level2,level1,
         level1,level1,level3,level1,
         level1,level1,level1,level1,
         level2,level1,level1,level1,
         level1,level1,level1,level1,
         level1,level1,level1,level1)   #Random Mischer

frog.animate = False
frog.visible=False
frog.width=1
frog.fill=True

y = 345

for k in range(1,43):
        
        if k in (1,3,5,7,9,11,13,15,17,19,21,23,
                 25,27,29,31,33,35,37,39,41) :
                
                x = -490
                y = y - 17
                frog.pos = x,y

                for k in range(17):
                               
                           
                        for k in range(6):
                                
                                frog.move(size)
                                frog.turn(60)
                                frog.fillcolor = choice(Level)
        
                        frog.jump(60)
                        
        else :
                x = -460
                y = y - 17
                frog.pos = x,y
                
                for k in range(16):
                        
                        for k in range(6):
                                frog.move(size)
                                frog.turn(60)
                                frog.fillcolor = choice(Level)
                        frog.jump(60)         
                
pool.ready()

Ich dachte, dass wenn die Reihen zeilenweise erstellt werden und man mit lastitem einen Zugriff bekäme, dann könnte man während jedes Schleifendurchlaufs vielleicht eine Liste oder Dictionary um die Koordinaten des jeweils letzten Elemets erweitern.

Kai
imac
20 Zoll
2,4 ghz
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Also die *-Importe sind natürlich schon mal ganz böse :twisted:

Diese level1, leve2, level3 schreien geradezu nach Listen oder richtigen Namen. Es wäre auch sinnvoller das Level aus Elementen wie "wood" und "water" aufzubauen, welche als Attribut eine Farbe haben.

Das "if k in (..........)" kan man auch als "if k in range(1,42,2)" schreiben. Außerdem lassen sich der if- und der else-Teil sehr gut zusammenfassen, der Code ist nahezu identisch.

Den ganzen Code auf Modulebene sollte man durch ein "if __name__ == '__main__'" schützen, dann kann man das Modul auch vernünftig importieren.

Dann treiben sich dort noch sehr viele magische Konstanten rum und viel zu viel Whitespace. Nach PEP8 benutzt man auch nur 4 Leerzeichen für eine Einrückungsebene.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Viiiieeele Fragen auf einmal ... :roll:

Ob du mit frog arbeiten willst oder nicht, solltest du am besten bald entscheiden; davon hängt ja ab, wie es weitergeht.

Ein Vorteil - neben anderen schon genannten - könnte sein, dass es eine m.E. gute und ziemlich ausführliche deutschsprachige Anleitung dazu gibt. Entsprechendes zu Tkinter kenne ich nur englischsprachig.

Nochmal zu speed = "max": Das Attribut animate gibt es in der aktuellen Version 0.75 nicht mehr. Es bringt also gar nichts, wenn du es verwendest. Schneller als mit speed = "max" wird der Frosch halt nicht.

Meine in einem früheren Post geschilderte Idee mit der sechseckigen Frosch-Form macht das ganze (geschätzt) doppelt so schnell, was aber immer noch langsam ist. Du müsstest dir also überlegen, ob du damit leben kannst.

Sonst versenke den Frosch im Teich und mach es allein mit Tkinter.

-------------

Ob du eine Pool()-Instanz eigenständig verwendest oder in eine Tkinter-GUI einbindest, hängt davon ab, wie deine Oberfläche später aussehen soll. Eigentlich geht so ziemlich alles auch mit einem reinen Pool soweit ich das sehe, bis auf ein Menü ala Menu-Widget.

In deinem Fall füllt das Spielfeld ja eigentlich alles aus, so dass es wohl wenig Sinn macht, den Pool/Canvas in eine Tkinter-GUI einzubetten.

---------------

Die Koordinaten der einzelnen Felder hast du schon.
Du musst sie nur in einer geeigneten Datenstruktur speichern. Hier wäre nochmal als Stichwort "Trennung von Spiellogik und Darstellung" zu nennen.

Du brauchst die Koordinaten nur jedesmal, bevor du ein Sechseck zeichnest, vom Frosch abzufragen:

pos = frog.pos (das dürfte dann wohl die linke untere Ecke des Sechsecks sein).

Das Ändern der Farbe ist auch kein Problem, wenn du diese Koordinaten geeignet speicherst. Du brauchst dann an dieser Stelle ja nur ein neues Sechseck mit der Wunschfarbe drüber zeichnen zu lassen.

Das Attribut lastitem brauchst du nicht unbedingt. Der Frosch benutzt diese ID nur zum Löschen von Objekten. Natürlich kannst du beim Neuzeichnen eines Sechsecks mit geänderter Farbe das darunterliegende auch löschen, damit die Gesamtzahl der Items nicht unnötig steigt und die Performanz dadurch weiter sinkt.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

EyDu hat geschrieben:Also die *-Importe sind natürlich schon mal ganz böse :twisted:
Immer in das alte Horn blasen ...

Hast du dir das frog-Modul mal angesehen?
Das einzige, was es da auf Modul-Ebene gibt, sind drei Klassendefinitionen.
Keine globalen Funktionen etc. Warum soll dann der * beim Frosch böse sein?
derkai
User
Beiträge: 169
Registriert: Montag 12. Mai 2008, 11:43

die Spielfäche muss noch ein bischen größer werden, nicht viel,
aber ein wenig.

Daher kam die Idee dies in eine gui Umgebung einzuarbeiten, da dort die
Möglichkeit bestünde mit einem Scrollbalken zu arbeiten. Das geht nur unter
frog wohl nicht ?

Kai
imac
20 Zoll
2,4 ghz
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

derkai hat geschrieben:die Spielfäche muss noch ein bischen größer werden, nicht viel,
aber ein wenig.
:?:

Wovon hängt denn die Größe des Spielfeldes ab?
Brauchst du eine festgelegte Zahl an Sechsecken?
Dann mach doch die Sechsecke ein bisschen kleiner.

Ich stelle mir ein gescrolltes Spielfeld auch nicht gerade praktisch vor.

Auf jeden Fall: Nein, scrollbar ist ein Pool nicht.
Entweder bettest du dann einen Pool in eine Tkinter-GUI und hängst Scrollbalken dran oder zu verwendest xturtle statt frog - da sind Scrollbalken standardmäßig schon dran.
BlackJack

Also wenn das wirklich in Richtung BattleTech geht, dann haben die meisten Umsetzungen Karten, die deutlich grösser als der Bildschirm sind. Obwohl -- die Bildschirme werden ja auch immer grösser. :-)

Allerdings würde ich bei einer wirklich grossen Karte, diese auch nicht komplett auf ein wirklich grosses Canvas malen; das dürfte irgend wann mit allen Hexagon-Feldern, Einheiten, Geländegrafiken usw. wirklich zu langsam beim Neuzeichnen werden. Obwohl -- die Rechner werden ja auch immer schneller. :-)

Damit wären wir dann wieder bei der Trennung von interner und grafischer Darstellung. So eine Karte mit Scrollbalken wird normalerweise so implementiert, dass immer nur der angezeigte Aussschnitt der Karte aus der internen Darstellung generiert wird.
derkai
User
Beiträge: 169
Registriert: Montag 12. Mai 2008, 11:43

eigentlich sollte das mal battletech werden, aber so langsam schwindet mir der Mut ....

Ich verstehe einfach nicht, was ihr mit dieser Trennung meint ?
Logik, Gui, intern, usw...

Könnt Ihr das nicht mal ein wenig plastischer Ausdrücken ?
Vor allem an Hand eines Beispiels ?

Kai
imac
20 Zoll
2,4 ghz
derkai
User
Beiträge: 169
Registriert: Montag 12. Mai 2008, 11:43

in der deutschen Anleitung zu Frog steht, dass man folgendes
Format zur Übergabe des pools an eine GUI verwenden soll

teich = Pool(root=frame)

Dazu muss ich ja erst ein GUI Fenster erstellen und ein Widget FRAME.

Das hatte ich folgendermaßen versucht :

Code: Alles auswählen

from Tkinter import *

fenster = Tk()
fenster.config(width=900,height=900)

test = Frame(fenster,relief=GROOVE,bd=2,padx=100,pady=100)
test.pack()

fenster.mainloop(
Leider ohne Erfolg
imac
20 Zoll
2,4 ghz
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

derkai hat geschrieben:Leider ohne Erfolg
Der Erfolg sollte sich einstellen, wenn du in der letzten Zeile die Klammer schließt ... :D

Oder was meinst du mit "kein Erfolg"?
BlackJack

@derkai: Mit der Trennung von GUI und Logik ist gemeint, dass die Logik ohne GUI implementiert werden sollte. Das heisst, Du musst auch ohne GUI eine Datenstruktur haben, welche die Karte und die ganzen Einheiten usw. enthält und die man nach den Regeln des Spiels manipulieren kann. Die GUI setzt man dann da drauf. Die Eingaben vom Spieler über eine GUI rufen die Methoden auf der Logik auf und bei Veränderungen fragt die GUI neue Werte ab, die dann dargestellt werden. Oft kann man dem Logikteil auch "Callback"-Funktionen geben, die bei bestimmten Ereignissen dann aufgerufen werden.

Für Dein Spiel bedeutet dass, Du bräuchtest so etwas wie eine `Map`-Klasse, die weiss wie gross sie ist, und bei der man jedes Feld durch irgendwie geartete Koordinaten eindeutig ansprechen kann, erfragen kann welches die sechs Nachbarfelder für eine gegebene Koordinate sind und so weiter. Da sind hexagonale Felder zum Beispiel etwas aufwändiger als quadratische Felder.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

@derkai (ergänzend zum Post von BlackJack):
Deine Vorgehensweise findet man leider häufig bei Programmieranfängern:
Man will (meistens) ein Spiel programmieren und fängt damit an, die Spieloberfläche (irgendwie) zusammenzubasteln und hält das für das Schwierigste an der Sache. Sobald die Oberfläche steht, tritt dann die große Ernüchterung ein und man stellt fest, dass es (im günstigsten Fall) zwar schick aussieht, aber es sich nicht spielen lässt.

Bei solchen (einfachen) Spielen ist das anspruchsvollste in der Regel nicht die graphische Umsetzung, sondern die Spiellogik dahinter. Dazu gehören - das hat BlackJack mit der Klasse schon angesprochen - vor allem (ggf. lange) Überlegungen zur Datenstruktur.

Empfehlung: Eine Hand voll Blätter und einen Bleistift nehmen und eine Datenstruktur entwerfen: Welche Informationen werden von welchen Elementen/Objekten/Spielfiguren etc. gebraucht und in welcher Art von Datenstruktur kann man diese speichern.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo derkai

Das frog-Modul würde ich in den Sumpf zurückgeben. Versuche dein Projekt wie schon erwähnt wurde mit reinen Tkinter-Widget zusammen zu bauen. Da muss man sich sukzessive einarbeiten. Es gibt es sicher genügend Mitglieder in diesem Forum die dich dabei irgendwie in einer Form unterstützen werden.

Aller Anfang ist die Zeugung eines Haupfensters. Da gibt es sicher hunderte Ansichten wie dies gemacht werden sollte (muss)..

Hier ist mein Weg um dieses Hauptfenster zu erstellen:

Code: Alles auswählen

import Tkinter as tk

#~~ Konstanten die Hauptfenster-Geometrie
MAIN_WIN_XPOS   = 0     # X-Position
MAIN_WIN_YPOS   = 0     # Y-Position
MAIN_WIN_WIDTH  = 900   # Hauptfenster-Breite
MAIN_WIN_HEIGHT = 900   # Hauptfenster-Höhe

#--- Erstelle ein Tk-Hauptfenster ----
fenster = tk.Tk()

#~~ Geometrie für das Hauptfentser
fenster.geometry("%dx%d+%d+%d" % (
    MAIN_WIN_WIDTH,
    MAIN_WIN_HEIGHT,
    MAIN_WIN_XPOS,
    MAIN_WIN_YPOS)
    )

fenster.title('Mein Hauptfenster')

fenster.mainloop()
Experimentiere mit den Konstanten für die Fenster-Abmessung

Gruss wuf :wink:
Take it easy Mates!
derkai
User
Beiträge: 169
Registriert: Montag 12. Mai 2008, 11:43

ok, jetzt habe ich neuen Mut.

Ich habe nun auch einmal versucht, das Hefeld (noch nicht die gesamte Spielfläche) in Tkinter umzusetzen. Hier schon einmal mein Ergebnis :

Code: Alles auswählen

from Tkinter import *
from math import *
from random import *

master = Tk()
spiel = Canvas(master, width=1024, height=768)
spiel.pack()

laenge = 20

x1 = 20
y1 = 10
x2 = 40
y2 = 10
x3 = x2 + (laenge/2.0)
y3 = y2 + ((laenge * sqrt(3)/2))
x4 = x2
y4 = (sqrt(3) * laenge) + y2
x5 = x1
y5 = y4
x6 = x1 - (laenge / 2.0)
y6 = y3

farbe = ("black","green")

spiel.create_polygon(x1,y1,x2,y2,x3,y3,x4,y4,x5,y5,x6,y6,outline="black",fill=choice(farbe))
master.mainloop()

print x1,y1
print x2,y2
print x3,y3
print x4,y4
print x5,y5
print x6,y6
Mehr, bzw mehr Zeit um dies schön zu programmieren hatte ich leider noch nicht :

ich brauche ne Mütze Schlaf

Kai
imac
20 Zoll
2,4 ghz
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo derkai

Das ist doch schon ein schönes Sechseck was du da auf die Canvas-Fläche zauberst. Was ich als nächstes versuchen würde ist, dass sich das Sechseck beim ändern der variable 'länge' von deinem jetztigen Wert 20 auf einen neuen Wert z.B. 50, proportional richtig vergrössert.

Für mich ist 'choice' etwas neues. Du siehst jeder Fetzen Code in diesem Forum hinterlässt neues Wissen. :lol:

Über die Darstellung des Codes gibt es so etwas wie PEP8, da würde ich Tag für Tag einen Abschnitt durchlesen und übernehmen was für die gute Lesbarkeit des Codes zu gebrauchen ist.

OK. Gruss wuf :wink:
Zuletzt geändert von wuf am Mittwoch 9. Juli 2008, 10:02, insgesamt 1-mal geändert.
Take it easy Mates!
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

@derkai:

Ja, das ist gegenüber dem ersten Code ein echter Fortschritt!
Jetzt ist schonmal die erforderliche Mathematik enthalten und die Eckpunkte werden berechnet.
Zeile 13/14 sollten dann auch entsprechend geändert werden.

Nochmal zum Frosch, falls du ihn noch nicht ganz beerdigt hast:
Du kannst den Frosch auch mit Tkinter kombinieren, da die Klasse Pool nichts weiter als ein erweitertes Canvas-Widget ist, d.h. du kannst aus spiel eine Instanz von Pool statt von Canvas machen.

Unterschied ist dann allerdings ein geändertes Koordinatensystem:
Der Nullpunkt ist dann nicht linksoben, sondern stets in der Mitte (d.h. er wandert bei Größenänderungen durch den Anwender auch mit) und der y-Achsenvektor ist nach oben hin ausgerichtet, also wie das aus der Mathematik bekannte (cartesische) Koordinatensystem.

Möglicherweise ist gerade der wandernde Mittelpunkt etwas, was dir entgegenkommt, weil du ja so eine Art "wanderndes Spielfeld" brauchst, wenn ich das richtig verstanden habe.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo numerix

Deine Idee mit dem Frosch ist sicher einen Versuch wert in einem späteren Stadium, sobald ein grösserer Array von Sechsecken auf der Canvasfläche verfügbar ist. Dann werden wir den Frosch noch einmal aus dem Sumpf locken. :lol:

Eventuell kann dies auch mit einer Kombination Canvas und Ziehleisten oder der move-Methode automatisiert werden ohne den Frosch als weiteres Modul reinzuziehen. Vielleicht ist es ja auch möglich in dieser Hinsicht im Froschmodul etwas brauchbares herauszulesen.

Gruss wuf :wink:
Take it easy Mates!
Antworten