Die gute alte Tile engine, diesmal aber mit Arrays
Übersicht

![]() |
NeoxitBetreff: Die gute alte Tile engine, diesmal aber mit Arrays |
![]() Antworten mit Zitat ![]() |
---|---|---|
Heydiho meine lieben, lange nichts mehr geschrieben ![]() Nach meiner längeren Pause, habe ich mir vorgenommen mein altes Projekt "Grabber" wieder aufzunehmen und von Grund auf neu zu gestalten. Da es dort massige performanceverluste gab, da ich Types genutzt habe für jeden Tile und diese auch jedesmal auf kollision überprüft habe. Nun möchte ich es besser machen, heißt also ich möchte Arrays nutzen, nur habe ich wirklich keine ahnung wie genau ich Arrays in Kombination mit Types am besten nutzen kann. So, das ich sie später allerdings auch Präzise ansprechen kann, es mehr Tiles gibt als das Level auf einer Bildschirmgröße von 1600x900 anzeigt allerdings das was gesehen wird, über einen Array abgerufen wird. Ich habe hier bereits mal einen kleinen versuch gemacht was dies angeht. Jedoch möchte ich von euch vorher wissen, wie ich das alles nachher wirklich am schnellsten (im sinne von rechenleistung) umsetzen kann. Code: [AUSKLAPPEN] ;Der Init part ;Types Type TTile Field id,x,y,img,name$,desc$,passierbar,sammelbar End Type ;Globals Global tile_x = 32 ;Tile Weite Global tile_y = 32 ;Tile Höhe Global map_x = 51 ;Map weite Global map_y = 51 ;Map höhe ;Array Dim map.TTile(map_x-1,map_y-1) Code: [AUSKLAPPEN] ;Der "Füllpart" For x = 0 To screen_x/tile_x For y = 0 To screen_y/tile_y map.TTile(x,y) = New TTile map(x,y)\x = (x*tile_x) map(x,y)\y = (y*tile_y) map(x,y)\id = 1 map(x,y)\img = img_block_01 Next Next Code: [AUSKLAPPEN] ;Der Hauptschleifen Drawing Part ;LEVEL ZEICHNEN For x = 0 To screen_x/tile_x For y = 0 To screen_y/tile_y DrawImage map(x,y)\img,map(x,y)\x,map(x,y)\y Next Next Ich nehme mal stark an das ich hier was die Koordinaten angeht, etwas doppelt gemoppelt habe. Wie wäre eure Idee dazu? Wie gesagt, es geht mir hauptsächlich um präzision was die Tileansprache angeht (da diese im Spiel nachher abänderbar sein sollen) und auch sehr sehr wichtig um performance. Falls ihr nicht wisst / nicht mehr wisst, was Grabber mal war auf http://neoxit.tumblr.com könnt ihr ein wenig weiter unten dies nachlesen ![]() Vielen Dank im Vorraus! |
||
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Die Reihenfolge, wenn du das Array durchgehst, könntest du noch optimieren:
Code: [AUSKLAPPEN] For y = 0 To
Dann kann der Speicher linear abgearbeitet werden, ohne hin und her zu springen.
For x = 0 To Koordinaten sind in der tat doppelt, eigentlich sollte sich alles über die Array ansprechen lassen. Einen Eintrag über die Koordinaten zu suchen ist nicht so prickelnd auf die Dauer. Ansonsten nur zeichnen was im sichtbaren Bereich liegt... aber ich schätze, das weißt du. ![]() |
||
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 THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
![]() |
Neoxit |
![]() Antworten mit Zitat ![]() |
---|---|---|
Danke dir Xeres ![]() Wie schaut das denn aus ich habe wie gesagt vorher nicht mit Arrays gearbeitet (Schande über mein Haupt ![]() Bei Code: [AUSKLAPPEN] DrawImage map(x,y)\img,map(x,y)\x,map(x,y)\y spreche ich ja nun den Array an und die Koordinate des jeweiligen Type eintrages (der doppelte part).
Ich habe mir zwar gestern ca. 10 mal den Part mit Arrays und Types hier im Forum durchgelesen, aber irgendwie fällt mir das schwer das nur das Array anzusprechen. Im prinzip könnte ich doch auch den x,y wert von dem MapArray direkt auslesen können und dann mit der Tile länge / höhe multiplizieren oder so ähnlich? Nur wie würde ich das nun meinem kleinen Programm sagen? Ich hab mich in dem ganzen Type / Array kram glaube ich nämlich ein wenig verheddert :X |
||
![]() |
das wurgel |
![]() Antworten mit Zitat ![]() |
---|---|---|
Im Prinzip ist dein System genau richtig. Die Performance wird auch bei nahezu beliebig großen Karten gering bleiben, wenn du es richtig anstellst.
Das Problem mit den Kooridinaten ist zimlich einfach zu lösen, vielleicht hast du dich verheddert, weil es eigentlich garncicht zum Aspekt Array-Type-Kombi gehört, sondern eher zu tilemaps allgemein. So grob ohne Scrolling: Code: [AUSKLAPPEN] DrawImage map(x,y)\img, x*tilesize, y*tilesize
Die x- und y- koordinate in dem Type schmeißt du am besten direkt raus, die wirst du eh nicht brauchen. Versuche nur dann die ganze Map durchzugehen wenn es unbedingt nötig ist, beim zeichnen brauchst du nur den ausschnitt der Karte zu zeichnen der im Bild liegt, bei Kollision noch weniger. |
||
1 ist ungefähr 3 |
![]() |
Neoxit |
![]() Antworten mit Zitat ![]() |
---|---|---|
okay das leuchtet mir nun alles noch besser ein ![]() Vielen dank ich werde mal schauen. Wenn ich dich richtig verstanden habe nutze ich einfach die Positionen unabhängig von dem Array/Type index sondern rechne sie simpel runter und greife somit auf diese zu? Ich werde das mal so ausprobieren wie gesagt klingt logisch. Vielen Dank bis hierin ersteinmal =) |
||
![]() |
ToeB |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich würde außerdem bei den Tiles nicht die Tatsächliche X/Y-Position speichern, sondern den Platz im Array. Somit kann man auch schneller auf angrenzende Tiles zurückgreifen und das vereinfacht das ganze wieder etwas. Weiterhin wäre es auch sinnvoll, vor dem Malen zu prüfen ob das Tile an dem Punkt X/Y überhaupt <> Null ist. Denn so kannst du Tiles, die sowieso nur "Luft" darstellen sollen, direkt beim erstellen weglassen und hast somit keine Performance Probelme mehr ![]() mfg ToeB |
||
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt! |
![]() |
Neoxit |
![]() Antworten mit Zitat ![]() |
---|---|---|
Danke auch für deine Rückmeldung !
Die luft werde ich nachher allerdings als Block benötigen. Da auch dieser verschiedene Eigenschaften besitzen wird. Und zum thema Tiles meinst du denke ich das er bei dem array Map(x,y) bspw: Map(2,3) wäre also bei einer Tilegröße von 32x32 der Tile auf x=64,y=96. So nehme ich an meintest du das, und ja das würde in der Tat noch einges vereinfachen und eine Rechnung entsprechend entfernen aus der Schleife. Weitere Ideen bitte immer zu mir =) Achja um kurz Rückmeldung zu geben, das was bisher gepostet wurde wurde umgesetzt und funktioniert nun auch ohne x,y in den Types. Und ansprechen kann man sie dann ja direkt über bspw Code: [AUSKLAPPEN] map(15,15)/id = 0 ;du bist jetzt ein luftblock :D
|
||
![]() |
BladeRunnerModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Wenn Du nur zeichnen willst was zu sehen ist musst Du wissen an welcher Position der Karte deine 'Kamera' sitzt und wieviele Tiles sie erfassen kann. Dann ist der Rest reine Mathe.
Beispiel: Deine Kamera sitzt über Tile 10,10. Sichtbar sind 5*7 Tiles. Dann sind die Tiles 10-2.5 bis 10+2.5 auf der X-Achse und 10-3,5 bis 10+3.5 auf der Y-Achse zu berechnen. Da Brüche in Schleifen nicht funktionieren, rundest Du das Ganze noch. Damit werden eventuell eine Handvoll Tiles unnötigerweise berechnet, aber das ist zu verschmerzen. |
||
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3 Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64 B3D BMax MaxGUI Stolzer Gewinner des BAC#48, #52 & #92 |
![]() |
Neoxit |
![]() Antworten mit Zitat ![]() |
---|---|---|
Okay ich verstehe schon wie du das meinst, meine frage dazu wäre nun eigentlich noch (da eine bildschirmgröße zu wenig ist für das spiel (definitiv zu wenig!)) wie ich nachher die Abfrage dafür mache was gezeichnet werden soll.
Vor allem wird die Mapgröße ja im Array gespeichert, und abgefragt wird sie dann denke ich mal durch 2 schleifen á X und Y. Wie sieht das nachher für die Schleife aus? Und an Blade, ich denke ich verstehe dich da schon ganz gut, habe dafür auch eine kleine veranschaulichung gemacht: Also nehme ich an ich muss auch den Map array so groß machen wie die map ansich ist heißt bspw. map(300,200) und dann auf den arraybereich zugreifen der relevant ist um diesen zu zeichnen. Heißt, wo meine Kamera ist in deinem Beispiel auf 10,10 |
||
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hier mal ein Beispiel, wie man einen "Kamera-Ausschnitt" eines 90x90 Tiles großen Spielfeldes auf einen 400x400pix Bildschirm bringt. Du bewegst das ganze mit den Pfeiltasten. Jedes Tile ist 30x30pix groß.
Was in dem Beispiel fehlt, ist die Map[] selbst. Aber das kannst Du ganz leicht ergänzen. Eigentlich läuft die gesamte Kamerasteuerung immer ohne Berücksichtigung der Map[]. Die Map[] wird beim Zeichnen nur benötigt, um herauszubekommen, welches Image an der Zeichenposition zu zeichnen ist. (siehe auskommentierte Zeile) BlitzBasic: [AUSKLAPPEN] Graphics 400,400 In diesem Beispiel wird sogar darauf verzichtet schon auszurechnen, ab welcher Tile-Reihe die Tiles überhaupt erst in die Nähe des Bildschirms kommen. Vielmehr werden einfach alle 8100 Tiles in der FOR/NEXT aufgerufen, die sich aus der Position und der Kamera ergebenden realen Koordinaten erechnet. Und wenn die innerhalb des "Bildschirms" liegen wird gezeichnet: BlitzBasic: [AUSKLAPPEN] For j=0 To 90 Die Performance bricht dadurch nicht ein. |
||
![]() |
Neoxit |
![]() Antworten mit Zitat ![]() |
---|---|---|
Sooooooo zurück aus Kiel ![]() Also hier haben wir mal meinen derzeitigen Fortschritt was die HAUPTSCHLEIFE angeht (also das Drawen ansich) BlitzBasic: [AUSKLAPPEN]
Und hier hab ich noch ein ganz besonderes Herzstück, es wird für viele vllt sehr interessant sein was eine Rnd Levelgeneration angeht, ich weiß das es nicht die beste ist, aber meine Erste. Was sagt ihr dazu? Sollte man das etwas anders machen? (Daten werden später noch aus dateien automatisch ausgelesen) BlitzBasic: [AUSKLAPPEN]
[EDIT] Achja, Performance bei einer Map mit einem Array von 1000-x und 1000-y einträgen, 3-5 % auslastung. |
||
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Du generierst viele male die gleichen Daten - das würde ich in eine Klasse/Extra Type umlagern:
BlitzBasic: [AUSKLAPPEN] Type TTile_Class Die Referenz sollte deutlich weniger Speicher brauchen. Alles, was nur diesen einen Block betrifft, bleibt in TTile aber Dinge wie "Erde" und ob sie flüssig ist, sollten sich eigentlich nicht für Blöcke unterscheiden -> übergeordnete Struktur. |
||
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 THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
![]() |
Neoxit |
![]() Antworten mit Zitat ![]() |
---|---|---|
Okay mit Klassen in diesem sinne habe ich irgendwie noch nie gearbeitet, aber man ist ja willig zu lernen nich wahr? =D
Ich werds mir mal anschauen und rumprobieren wie das genau funktioniert, gibts genau zu diesem bereich vllt eine richtig gute Erklärung? Ich meine Grundlegendes darüber? |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group