# Theoretische Frage zu Tile Spielkarten



## Kenan89 (10. Jun 2012)

Hi, 
ich arbeite ja momentan an einem TileEditor.

Es funktioniert momentan folgendermaßen: Das Tile ist aus einer Grafik, mit jeweils Tiles, der Größe 32x32 pixel. Diese werden in mein Programm eingelesen und sind jeweils als Objekte der Klasse Tile gespeichert. Nun kann damit gezeichnet werden. Hierbei enthält das JPanel, worauf gezeichnet werden soll, ein 2d-Array, pro Layer. Es gibt insgesamt 3 Layer. Layer 1=Grass, ... Layer 2=Steine, Häuser, Objekte,... Layer 3=Alles was über allen Objekten erscheinen soll, z.B. Vögel, Wolken,...
Wurde auf ein Tile geklickt und auf dem Zeichenpanel gezeichnet, werden Positionen des 2d-Arrays des Zeichenpanels belegt, mit der TileID. 
Beim Speichern der Karte, geht das Programm jede im 2d Array gespeicherte Tile-ID durch und speichert sie in ein txt-File. Hierin steht die x,y-Koordinate des Tiles auf der Karte, auf welchem Layer es sich befindet und die tile ID. In der ersten Zeile steht noch der Name der Grafik-URL.
Soll nun die Karte in ein Spiel geladen werden. 

Die Text-Datei wird Zeile für Zeile ausgelesen. Das SPiel liest, die URL aus der ersten Zeile und teilt die Tiles der Grafik in gleicher Weise in ID`s wie mein TileEditor. So wird die Map gezeichnet.

Problem ist nur, dass wenn die Karte größer ist als der Spielbildschirm müssen sich ja alle Objekte mitverschieben, wenn der Player nach unten geht, z.B. In einer Karte mit sagen wir 20*20(also 20*32px horizontal und 20*32 pixel vertical) wären das schon 400 Tiles, deren x,y Werte verschoben werden müssten. Liege ich falsch, oder sind das nicht etwas zu viel Berechnung für den pc?

EDIT:
Also 400 x Aufrufe der Gameloop pro Sekunde. Das kommt dann schon auf 16 000, bei 20 Aufrufen pro Sekunde... Ich bin ja noch ziemlich neu in diesem Gebiet... Vielleicht liege ich ja voll daneben und der rechner schafft millionen berechnungen die sekunde


----------



## invalid (10. Jun 2012)

Du verschiebst nicht alle Objekte, sondern nur die 'View'.


----------



## Kenan89 (10. Jun 2012)

Wie meinst du "View"? Du musst doch z.B. die x-Koordinaten aller Objekte subtrahieren, wenn du die des Helden addierst.


----------



## Fu3L (10. Jun 2012)

Du zeichnest ja nie alles, sondern nur das, was du wirklich siehst:

Nur was dein View Rectangle schneidet ist im Spiefeld. Dann musst du die Position des Tiles auf dem Bildschirm berechnen. Dafür musst du die Position des Tiles minus die Position der linken oberen Ecke deines View-Rectangles rechnen. (und ja: bei jedem Zeichnen, aber das macht dem Rechner bei ein paar Hundert Tiles pro Loop nichts )


----------



## Kenan89 (23. Jun 2012)

Ich denke es gibt ein kleines Missverständnis.
Vielleicht hilft eine Grafik mehr:







Der grüne Bereich ist der Sichtbare Teil der Spielkarte.

Jedes Quadrat beinhaltet ein Objekt(Gras, Mensch, Stein, Baum, usw)... Ein TIleObjekt hat Eigenschaften, z.B. ob er begehbar ist.

Folgende Schritte müssen doch jetzt durchgeführt werden, wenn der Held die vertikale Mitte des sichtbaren Bereichs betritt.

Beispiel:
(Der Screen ist: 640 * 480 px)
(Die Spielkarte ist: 1500 * 1000 px)

1. Der Held hat 2 Koordinaten: lokal und global
2. Seine globale Koordinate gilt für die gesamte Karte, seine lokale nur für den Frame(640*480px)
3. Betritt er jetzt die vertikale Mitte des Screens, wird seine lokale Koordinate nach jedem move auf 240 zurückgesetzt und nur seine globale Koordinate verändert
4. Alle Objekte der Spielkarte bewegen sich dem Helden zu, wenn Held runterbewegt wird, bewegen sich alle Objekte nach oben usw... 
5. Kollisionsberechnung wird nur mit globalen Koordinaten durchgeführt

Das Problem ist nun denke ich erdenklich: Bewegt sich der Held über die vetikale Mittellinie(lokale y > 240 px), wird seine lokale Koordinate wieder auf 240 gesetzt. Nur die globale verändert sich.

Jetzt ist es ja, dass sich, alle Tiles, seien es Menschen, Gras, Bäume,... nach oben bewegen müssen, wenn der Held nach unten geht.

Die Methode zum zeichnen wird ca 50 x pro Sekunde aufgerufen. 
Die xy Koordinaten von jedem Tile müsste aktualisiert werden, falls sich der held bewegt. Bei einer Map von 20*20, wobei jedes Tile 32*32px groß ist, wären das 400 Tiles * 50 Aufrufe = 20 000 Berechnungen die Sekunde...

Ich hoffe es war einigermaßen verständlich.






(Nochmal zur Erläuterung: Der grüne Bereich ist der Screen. Bei Bewegung des Helden über die Mitte(vertikal/horizontal)), verschieben sich nur die Objekte auf dem grauen Bereich


----------



## Fu3L (23. Jun 2012)

Gehen wir mal davon aus, dass eine Berechnung 10 Nanosekunden braucht. (Was moderne Prozessoren bei weitem unterschreiten sollten).
10 ns * 20.000 = 200.000 ns = 200 µs = 0,2 ms = 0,0002 Sekunden.
Das heißt du kannst das ganze 5000 Mal pro Sekunde machen


----------



## Firephoenix (23. Jun 2012)

Hi,
ich hab das bei meiner Tilemap so gelöst:

Die obere linke Kartenecke hat irgend eine Koordinate (x,y) (damit kann ich auch mehrere karten aneinander hängen bei bedarf  ).

Der Spieler steht auf der postition (px,py).

Dein sichtbarer bereich hat die Maße width,height.

Willst du jetzt den Spieler in der Mitte zeichnen (immer) kannst du so vorgehen:

-verschiebe dein Graphics-Objekt (oder was auch immer du benutzt) fix um
(-px + width/2 (bei mir noch -spielerbreite/2) in x-richtung
und um
(-py + height/2 (bei mir noch -spielerhöhe/2) in y-richtung.

und zeichnest dann alle (sichtbaren) objekte einfach an ihren koordinaten (entsprechend um den faktor verschoben).

selbst wenn du die Verschiebung bei jedem Objekt einzeln abziehen musst sind das nur 2 subtraktionen pro gezeichnetem Objekt, die vorige berechnung um die verschiebung zu ermitteln musst du ja nur einmal machen).

Vielleicht hilft es dir ja weiter, gibt sicherlich noch bessere Ansätze  aber ein bisschen selbst knobeln macht auch manchmal spaß.

Gruß


----------



## Kenan89 (23. Jun 2012)

Meine Frage betraf ja auch die Belastung für den PC, bei 20 000 Berechnungen die Sekunde, da ich mich in diesem Thema noch nicht so gut auskenne(muss mich eh noch in Performance Themen einarbeiten )

Na gut dann werde ich das so lösen  Danke.

@Firephoenix
Ja, so ähnlich ist doch auch mein Ansatz?! Ich verschiebe auch alle Objekte um ein Faktor, wenn die Spielkarte scrollen soll.


----------



## Fu3L (23. Jun 2012)

Du musst dir immer klarmachen, dass ein moderner Prozessor mit 2 GHz alle 0,5 Nanosekunden einen Maschienenbefehl abarbeiten kann. Da auch zum Registerschieben und Speichern von Daten Takte gebraucht werden, braucht eine Subtraktion zwar länger als 1 Takt, aber das sollte immer noch (deutlich) unter 5 ns liegen 

Grafikkarten sind übrigends noch krasser. Die haben ein paar hundert Recheneinheiten, die auf bis zu 0,5-2 GHz getaktet sind, also auch ein paar hundert Milliarden Rechenoperationen pro Sekunde durchführen können


----------



## Kenan89 (24. Jun 2012)

gut, dass ich das jetzt gelernt habe  danke


----------

