Seite 2 von 2

Re: [Pygame] Isometrische Engine

Verfasst: Mittwoch 28. März 2012, 09:48
von deets
Das mit den nicht-sichtbaren Kacheln solltest du tunlichst sein lassen. Dafuer ja mein Tipp mit BSPs/Quadtrees. Und du solltest dir die Arbeit mit dem Profiler angewoehnen - nur so erfaehrst du wirklich, was passiert.

Re: [Pygame] Isometrische Engine

Verfasst: Mittwoch 28. März 2012, 10:24
von webspider
Stichwort diesbezüglich wäre Culling, d.h. das Prüfen ob etwas gezeichnet werden muss anhand vereinfachter Bedingungen. Es ist eine verhältnismäßig schlichte Optimierung mit viel Performancegewinn im Gegensatz zu den Sachen, die man als Neuling sonst geneigt ist ohne jegliche Tests zu tun um das Programm auf Trab zu bringen.

Re: [Pygame] Isometrische Engine

Verfasst: Mittwoch 28. März 2012, 11:20
von glocke
Also sollten alle Kacheln die beim Bewegen vom Bildschirm verschwinden aus der SpriteGroup entfernt und alle Kacheln die dabei erscheinen hinzugefügt werden?

Re: [Pygame] Isometrische Engine

Verfasst: Mittwoch 28. März 2012, 11:21
von Hyperion
Wo ich da grad etwas von `SpriteGroup` gelesen habe... arbeitest Du ausschließlich mit Sprites? Ich habe das für die Tiles einer Engine noch nie gesehen - aber vielleicht ist das ja auch eine gute Idee.

Zumindest was das Hinzufügen zu / Wegnehmen von einer Gruppe anbelangt, kann Dich die Doku beruhigen:
The groups are designed for high efficiency in removing and adding Sprites to them.

Re: [Pygame] Isometrische Engine

Verfasst: Mittwoch 28. März 2012, 11:24
von webspider
Eigentlich sollte Culling ja im Renderer implementiert werden statt mit den Objekten zu hantieren. Wie gesagt wird vor dem Zeichnen geprüft ob das aktuell drankommende Objekt sichtbar wäre, wenn ja wirds gezeichnet, wenn nein, dann nicht. Profilen solltest du dennoch.

Re: [Pygame] Isometrische Engine

Verfasst: Mittwoch 28. März 2012, 18:16
von deets
glocke hat geschrieben:Also sollten alle Kacheln die beim Bewegen vom Bildschirm verschwinden aus der SpriteGroup entfernt und alle Kacheln die dabei erscheinen hinzugefügt werden?
Wozu brauchst du diese Group ueberhaupt? Ich wuerde die loswerden. Alleine schon, weil sie keine Ordnung beim zeichnen einhaelt - womit dir bei Kacheln die eine Hoehe haben das ganze Ding um die Ohren fliegt - du musst ja von hinten nach vorne rendern.

Sammel einfach ausgehend von der Kamerposition alle notwendigen Kacheln ein, und mal die. Punkt.

Re: [Pygame] Isometrische Engine

Verfasst: Donnerstag 29. März 2012, 12:44
von deets
Und noch ein Hinweis: habe mir gerade mal das hier angeschaut:

https://github.com/christiangloeckner/P ... /isomap.py

Und da hast du natuerlich einen gigantischen konzeptionellen Fehler drin. Um deine Bildschirmtransformation zu machen, veraenderst du die Koordinaten der Tiles!! Das ist natuerlich dramatisch, denn dadurch erzeugst du Komplexitaet proportional zur Groesse deines Levels! Das ist quadratisch, und damit algorithmisch unguenstig - und unnoetig!

Die Koordinaten haben natuerlich fest zu bleiben. Stattdessen waehlst du ausgehend von der Kameraposition alle sichtbaren Tiles - damit wird das Problem in der Groesse reduziert auf die Anzahl der *darstellbaren* Tiles. Und die blittest du dann an ihre entsprechende Position.

Re: [Pygame] Isometrische Engine

Verfasst: Donnerstag 29. März 2012, 14:03
von glocke
Hi, an der ganzen Sache bastel ich schon ne Weile ... hab gemerkt dass es absolut mistig ist, und bin gerade dabei das Modul neu zu schreiben. Allerdings habe ich bei der Umrechnung der Koordinaten einige Probleme.

Code: Alles auswählen

def map2screen(self, (x, y)):
        """Convert map coordinate to screen coordinate"""
        tw = self.tilesize
        th = tw / 2
        w  = self.mapsize.x * tw
        # convert
        x_ = w/2 + tw/2 * (x-y)
        y_ = th/2 * (1+x+y)
        return (x_, y_)
Die Methode klappt einwandfrei. Ich habe mir eine kleine Karte skizziert (0,0 dabei oben in der mitte) und eine Formel hergeleitete wie ich die Tile-Positionen auf dem Bildschirm berechne. Nur scheitere ich daran den Rückschluss von ScreenPosition auf MapPosition hinzubekommen. *rumgoogle* Das Umstellen der Formel ...

Code: Alles auswählen

def screen2map(self, (x, y)):
        """Convert screen coordinate to map coordinate"""
        tw = self.tilesize
        th = tw / 2
        w  = self.mapsize.x * tw
        # convert
        x_ = (tw * 2 * y - tw * th + 2 * th * x - th * w) / (2 * th * tw)
        y_ = (tw * th - 2 * y * th + 2 * th * x - th * w) / (2 * th * tw)
        return (x_, y_)
(mit wxMaxima, hoffentlich habe ich keine Tippfehler) ... wirkt bisschen derb und bringt auch falsche Ergebnisse. Beide Funktionen arbeiten nun unabhängig von der Kameraperspektive.

Bei map2screen ziehe ich danach noch die Kameraposition ab.

LG

Re: [Pygame] Isometrische Engine

Verfasst: Donnerstag 29. März 2012, 14:17
von EyDu
Wenn du die Transformation umkehren willst, musst du lediglich

Code: Alles auswählen

x_ = w/2 + tw/2 * (x-y)
nach x und

Code: Alles auswählen

y_ = th/2 * (1+x+y)
nach y auflösen und entsprechend einsetzen. Ich sehe gar nicht, was man da groß mit Google versuchen möchte, das lässt sich doch schon im Kopf lösen. Zur Not tun es auch drei Zeilen auf Papier.

Da du offensichtlich Python 2.x verwendest, solltest du auch mit den Divisionen vorsichtig sein. ``x/2`` ist eine ganzzahlige Division, wenn x ein Integer ist. Das könnte bei dir das eine oder andere Problemchen verursachen.

Sebastian

Re: [Pygame] Isometrische Engine

Verfasst: Donnerstag 29. März 2012, 14:23
von glocke
Umgestellt habe ich es (wie geschrieben mit wxMaxima, ich mach beim Umstellen sonst zu viele kleine Schusselfehler). Ich mag nur gerade nicht akzeptieren dass es damit gewesen sein soll O_o xD

Wegen der Divisions-Sache hast du Recht, hab die 2 im Divisor durch 2.0 ersetzt um explizit nen Float zu erzwingen. Damit müsste die Division imho im Float ausgeführt werden.
Wäre es ratsam

Code: Alles auswählen

from __future__ import division
zu verwenden? Ich würde ja Python 3 verwenden aber darauf möchte ich wegen http://www.pygame.org/wiki/FrequentlyAs ... ython%203? verzichten.

Den aktuellen Code hab ich mal hochgesynct damit alle das gleiche als Basis haben.

/EDIT: hatte 3 Tippfehler, die erklärten auch die Abweichungen xD Kamera auf ein Tile zentriert setzen (via Konstruktor) funktioniert auch. Dann kümmere ich mich jetzt wieder um das Selektieren der sichtbaren und unsichtbaren Kacheln.

/EDIT2: Erledigt (erstmal). Aber wahrscheinlich wäre es sinnvoller beim Bewegen der Kamera alle sichtbaren Tiles zu erfassen (und in einer Liste entsprechend der Renderreihenfolge einzuordnen) anstatt das beim Rendern jedes mal zu tun.... änder ich später.

/EDIT3: Hab den Repo-Namen gekürzt https://github.com/christiangloeckner/pare