verdammt, ich kapier es einfach nicht

Fragen zu Tkinter.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

PNG ist ein Bildformat, was ein Webbrowser anzeigen kann und das Transparenz und Transluzenz unterstützt.

Stefan
derkai
User
Beiträge: 169
Registriert: Montag 12. Mai 2008, 11:43

ok, dank Eurer Hilfe bin ich nun einen Schritt weiter :

Code: Alles auswählen

from frog import *
from random import *

size = 20                               #Groesse Hexfeld

pool = Pool(width=1024,height=768,bgcolor="black") #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.speed = 10
frog.width=2
frog.fill=True


y =  370
for k in range(20):
        x = - 490
        y = y - 36
        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)

y =  352
for k in range(20):
        x = -460
        y = y - 36
        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()
... aber warum dauert der Aufbau soooooo lange ?

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

Glückwunsch, das ist doch mal ein Erfolg!

Das dauert so lange, weil du
a) eine Riesenmenge an Zeichenoperationen vornimmst (die aber auch nötig sind)
b) das frog-Modul nicht unbedingt auf höchste Performance ausgerichtet ist
c) das darunter liegende Tkinter dies ebenfalls nicht ist

Darüber hinaus ist anzumerken:
a) Jedes gezeichnete Element auf einem Tkinter-Canvas wird als Item geführt; dein Spielfeld bringt es auf 660 Items (kannst du mit frog.items abfragen) und mit steigender Zahl an items werden die Grafikoperationen immer langsamer
b) Das frog-Attribute animate ist veraltet (es bewirkt einfach gar nichts mehr); um die max. Geschwindigkeit zu erreichen, setzt man frog.speed = "max".
c) Eine deutliche Geschwindigkeitssteigerung könnte man dadurch erreichen, dass man eine neu frog-Shape in Gestalt eines Sechsecks definiert und dann mittels der Methode stamp() Abbilder dieses "Froschs" setzt. Allerdings ist man dann nicht mehr in der Größe der Sechsecke flexibel. Wie viel schneller das geht, habe ich aber nicht ausprobiert.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Ergänzung / Präzisierung / Korrektur zum letzten Post:

Die Idee mit dem Ansatz über die shape()-Methode des Froschs bringt keinen nennenswerten Geschwindigkeitsvorteil.

Der Verzicht auf das frog Modul bringt einen ganz erheblichen Geschwindigkeitsvorteil! Ich habe das ganze gerade mal mit "Tkinter pur" umgesetzt und - :shock: :shock: :shock: - das gesamte Spielfeld ist mit einem Schlag sofort sichtbar!

Die benötigte Mathematik hält sich auch in Grenzen, wenn du es geschickt anstellst; der Satz des Pythagoras genügt, Trigonometrie brauchst du nicht.

Allerdings wäre auch weiter zu überlegen, was dein künftiges Spiel sonst noch so leisten soll und ob man dann nicht ggf. die schlechte Performance des Froschs in Kauf nimmt, um weitere Elemente des Spiels dann ggf. in gut lesbarem Code und unter Verwendung einiger komfortabler Frosch-Methoden umzusetzen.
BlackJack

@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?
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.
Antworten