Animierte Tiles "synchronisieren"

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

M0rgenstern

Betreff: Animierte Tiles "synchronisieren"

BeitragDo, März 08, 2012 15:29
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo Leute,
Ich habe mir zwei kleine Klassen gebastelt um Tiles einer Tilemap besser zu verwalten.
Unter anderem beseitzt eine der Klassen (TTileSet) ein Array für das komplette Tileset, das für die Animation der Tiles zuständig ist.
Das ganze funktioniert relativ einfach: In dem Array von 0 bis AnzahlDerTiles steht jeder Index für ein Tile auf dem Tileset. Und der Inhalt des Arrays an der Stelle gibt das darauffolgende Tile an. Wenn das Tile nicht animiert ist, dann ist der Inhalt einfach nochmal der Index.
Damit das Tile auch animiert wird hat es eine Methode Update() in der geprüft wird ob bereits genug Zeit abgelaufen ist und wenn ja, dann wird einfach der Index geändert.

Mein Problem ist jetzt:
Ich berechne bei einer Tilemap ja nur die sichtbaren Tiles.
Das heißt, alle Tiles die außerhalb des Bildschirms liegen werden weder gezeichnet noch sonst wie verarbeitet.
Scrollt man also von einem animierten Tile weg und später wieder zurück, dann hat es noch den alten Zustand und wird von da an animiert. Das ist unproblematisch bei unzusammenhängenden Tiles.
Aber bei größeren animierten Flächen wie z.B. Wasser sieht das sehr komisch aus, da das Muster ja dann überall anders ist.
Ich habe mir überlegt, diese Tiles einfach zu synchronisieren, aber ich wüsste nicht wie.
Da es ja 1. nicht alle Tiles betrifft die animiert sind und 2. kann es ja verschiedene Wasserflächen etc geben, die nicht zusammen synchronisiert werden müssen.

Kann mir da jemand weiterhelfen bitte?

Lg, M0rgenstern

Xeres

Moderator

BeitragDo, März 08, 2012 15:45
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn es keinen Unterschied zwischen zwei Wassertiles geben muss, kannst du ein und das selbe Tile überall wieder verwenden.
Ansonsten Update und Draw von einander trennen.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)
 

PhillipK

BeitragDo, März 08, 2012 15:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich würde das relativ dirty lösen.
Zuersteinmal ein Zeitverwaltungsobjekt - "TTileTimer" oder so n quatsch.
Dieses wird in jedes Tile reingelinkt, das synchron sein soll. Ich denke hierbei an zb Wasser - jedes wasserteil der selben fläche kriegt das selbe TTileTimer.

TTileTimer hält immer den aktuellen Array index, einen Timestamp, eine updatemethode.
Nun wird jedes tile in der Methode Update() lediglich den aktuellen Array-index holen.
Vor jedem drawAufruf muss allerdings jede TTileTimer instanz geupdatet werden. (am besten kriegt TTileTimer eine global "List" als TList, jede TTileTimer instanz wird dort eingespeist und einmal zusammen überarbeitet.

Bedingungen für diesen Ansatz:
1) Die kannst feststellen, welche tiles zusammen gesyncht werden sollen
2) Du solltest TTileSet extenden, um die momentane methode (jedes tile prüft sobald es gezeichnet wird) für unsynchrone teile beizubehalten, aber den Syncrhonen den TTileTimer raufzudrücken
3) Du kannst dich damit anfreunden, das auch evtl momentan nicht genutzt TTileTimer geupdatet werden (alle bezugs-tiles liegen ausserhalb, werden nicht gezeichnet, aber sind trotzdem "up to date")

M0rgenstern

BeitragDo, März 08, 2012 17:55
Antworten mit Zitat
Benutzer-Profile anzeigen
Vielen Dank Leute.

@Xeres: Ich habe jetzt einfach Update und Draw getrennt.
Hätte nicht gedacht, dass es funktioniert. Aber es läuft bis zu 20000 Tiles flüssig. Bei etwa 5000 mehr brechen die FPS langsam ein.

@PhillipK:
Sorry, aber so 100% habe ich nicht verstanden was du meinst.

Lg, M0rgenstern

Xeres

Moderator

BeitragDo, März 08, 2012 18:03
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn die Tiles synchron sein sollen, macht es kaum Sinn, jedem einen eigenen Timer zu geben. Stattdessen kann das einer erledigen und die Tiles fragen beim Zeichnen den Timer, was sie zeichnen sollen. Einen Timer updaten ist sicher besser als 20000 Tiles.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)
 

PhillipK

BeitragDo, März 08, 2012 18:43
Antworten mit Zitat
Benutzer-Profile anzeigen
@Xeres:
Genau so hatte ich es gemeint.
Ein Timer für 1000 identische wassertiles. Der Timer bestimmt, welches Frame dran ist und prüft auch nur einmalig die Zeit.

Dieser Timer wird nun in jedes tile gelinkt, das synchron sein soll^^

Tiles die einen eigenen, einzelnen timer hätten, können bei der alten methode bleiben.

@M0rgenstern:
Update und draw trennen, hättest nicht gedacht, das das funktioniert? Very Happy
Klingt eigentlich logisch, solange nur beim Drawen die tiles geskippt werden. Denn, wenn dort das Update passiert, kriegen nur die sichtbaren tiles ein update. Wenn beim updaten im allgemeinen jedes Tile berücksichtig wird, läufts synchron.

M0rgenstern

BeitragDo, März 08, 2012 19:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey.

@Xeres:
Jetzt verstehe ich das mit dem Timer.
Ich denke ich werde das einbauen. Dafür muss ich dann die Klassen erstmal ein gutes Stück umschreiben.

@PhillipK:
Doch, dass man Update und Draw trennen kann habe ich gedacht.
Aber ich war verwundert darüber, dass selbst bei einer Kartengröße von 100*200 Tiles kein Leistungsunterschied vorliegt, wenn man dann in Update das komplette Array durchgeht.
Also ich war einfach nur (mal wieder) überrascht wie zeitintensiv die Zeichnbefehle doch sind.

Lg, M0rgenstern

AnniXa

BeitragSo, März 11, 2012 11:09
Antworten mit Zitat
Benutzer-Profile anzeigen
vieleicht solltest du einfach ein type schreiben welches die anationen verwaltet.
so das du nurnoch die animationen updaten musst, und so alle wasser tiles sich auf die selbe beziehen.
wenn das nicht geht weil du z.b 3 verachiedene wasser animationen hast und moechtest das diese synchron laufen kannst du es so machen das jeses tile ein field "frame" hat und ein field mit den animations type.
das anim type wiederum hat ein field "frameshift".
beim updaten des anim types wird frameshift verarbeitet entsprechend wie du die animation willst bei 3 frames nimmt es werte von 0 bis 2 an.
beim zeichnen des tiles brauchst du dann nurnoch
tile.frame + tile.anim.frameshift zu machen um das zu zeichnende frame zu bekommen.

dies spart speicher da jede wasser tile das selbe animtype nutzen kann und trotzdem individuell und synchron animiert ist.
und du sogar nur soviel wasser tiles brauchst wie du auch hast und nicht zig tiles die alle gleich sind bis auf einen wert fuer das zu zeichnende frame
und vorallem cpu zeit weil du nur einen wert anpassen must und alle tiles machen mit.

diese waere meib ansatz dafuer.
|moonForge|
Ich bin Pokémon Meisterin seit 1998!

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group