Große Iso Tiles langsam

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

 

AmenO

Betreff: Große Iso Tiles langsam

BeitragMo, Aug 31, 2009 9:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

ich versuche mich gerade an Iso Tiles. Im Prinzip funktioniert auch schon das Zeichnen und Scrollen. Soweit sogut... wenn ich jetzt eine Iso Karte mit 20 x 20 Kacheln zeichnen lasse (mit jeweils 32 x 32 px), dann ist die Geschwindigkeit (sprich die Framerate) noch annehmbar. Selbst wenn ich 40 x 40 Kacheln verwende geht das ganze noch, obwohl man langsam merkt, dass es langsamer wird. Wenn ich mir Spiele wie Sim City 2000 oder so ansehe, die verwenden jedoch nicht "nur" 40 x 40 Kacheln, sondern vielleicht 300 x 300 Kachel. Ungetestet kann ich sagen, dass solche Karten bei mir garantiert nicht mal 10 FPS erreichen würden.

In meinen bisherigen Spielen habe ich das Problem zwar gelöst, indem ich ganz einfach nur den sichtbaren Breich gezeichnet habe. Das hat auch wunderbar funktioniert... das Problem ist nur, dass ich auch die anderen Ecken meiner Karte ständig aktualisieren möchte. Wenn der Spieler beispielsweise an verschiedenen "Enden" der Karte etwas baut (z.B. ein bzw. mehrere Häuser) und dann wieder in die Mitte scrollt, wo kein Gebäude steht, würden die Ecken, an denen die Häuser stehen nicht aktualisiert werden. Erst wenn der Spieler es wieder in seinem Sichtbereich hätte.
Ich könnte das Problem zwar lösen, indem ich eine Schleife laufen lasse, die die entsprechenden Breiche auch aktualisiert, diese jedoch nicht zeichnet. Das Problem ist jedoch wieder, dass es halt wieder auf Kosten der Performance geht.

Vielleicht liegt das ganze ja auch an meinem Code...

Code: [AUSKLAPPEN]
; Auflösung und Farbtiefe
Global xMax = 640
Global yMax = 480
Global depth = 16

; Kartendetails
Global mapBreite = 40
Global mapHoehe = 40

; Scrollvariablen
Global offsetX = 0
Global offsetY = 0

Graphics xMax, yMax, depth, 2
SetBuffer BackBuffer()

Dim Karte$(mapBreite-1, mapHoehe-1)

Global tile = LoadImage("gras.png")

MaskImage tile, 255, 0, 255

Function scrolling()

   ; Links- und Rechts-Scrolling prüfen
   If KeyDown(203) And offsetX < (mapBreite * 64) * 0.6 Then
   
      offsetX = offsetX + 4 ; Nach Links
   
   ElseIf KeyDown(205) And offsetX > -(mapBreite * 64) * 0.6 Then
   
      offsetX = offsetX - 4 ; Nach Rechts
   
   EndIf
   
   ; Hoch- und Runterscrolling prüfen
   
   If KeyDown(200) And offsetY < 228 Then
   
      offsetY = offsetY + 4 ; Nach oben
   
   ElseIf KeyDown(208) And offsetY > -(mapHoehe * 64) * 0.4 Then
   
      offsetY = offsetY - 4 ; Nach unten
   
   EndIf

End Function

Repeat

   Cls

   scrolling()
   
   cX = xMax / 2 + offsetX
   cY = 0 + offsetY
   
   ClsColor 64, 64, 64
   
   For Zeile = 0 To mapHoehe - 1
   
      aktuelleTileX = cX
      aktuelleTileY = cY
   
      For Spalte = 0 To mapBreite - 1
      
         DrawImage tile, aktuelleTileX - 32, aktuelleTileY
         
         aktuelleTileX = aktuelleTileX + 32
         aktuelleTileY = aktuelleTileY + 16
      
      Next
      
      cX = cX - 32
      
      cY = cY + 16
   
   Next
   
   Flip(0)

Until KeyHit(1)

End


Wie gesagt... mit 40 x 40 Kacheln ist die Framerate noch eingermaßen annehmbar mit ca. 90 FPS auf der Kartenmitte. Wenn ich etwas bauen würde und noch ein paar Schleifen einbauen würde, dann wäre ich aber schnell bei 5 oder 10 FPS.

In diesem Sinne schonmal danke Smile
  • Zuletzt bearbeitet von AmenO am Mo, Aug 31, 2009 23:03, insgesamt einmal bearbeitet

Nicdel

BeitragMo, Aug 31, 2009 9:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Du könntest nur die Tiles zeichnen, die auch wirklich im Sichfeld (also im Fenster) liegen...

Edit: Mit dieser Abfrage:

Code: [AUSKLAPPEN]
If aktuelleTileX >= 0 And aktuelleTileX <= 672 And aktuelleTileY >= -32 And aktuelleTileY <= 480
Desktop: Intel Pentium 4 2650 Mhz, 2 GB RAM, ATI Radeon HD 3850 512 MB, Windows XP
Notebook: Intel Core i7 720 QM 1.6 Ghz, 4 GB DDR3 RAM, nVidia 230M GT, Windows 7
  • Zuletzt bearbeitet von Nicdel am Mo, Aug 31, 2009 9:36, insgesamt einmal bearbeitet

BladeRunner

Moderator

BeitragMo, Aug 31, 2009 9:29
Antworten mit Zitat
Benutzer-Profile anzeigen
Im Prinzip gibst Du Dir die Antwort schon selbst:
Zeichne nur was auch zu sehen ist, Berechne im Wesentlichen im Sichtbereich und wenn Du noch Rechenzeit übrig hast arbeite die nicht sichtbaren Teile häppchenweise ab ohne sie zu zeichnen. Auf diese Art und weise werden die Berechnungen im nicht sichtbaren Bereich eventuell ein wenig vereinfacht, aber selbst das muss nicht so sein, denn üblicherweise ist das Einzeichnen der Flaschenhals, zumindest wenn nicht hochkomplexe Berechnungen angestellt werden.
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
 

AmenO

BeitragMo, Aug 31, 2009 10:01
Antworten mit Zitat
Benutzer-Profile anzeigen
Nicdel hat Folgendes geschrieben:
Du könntest nur die Tiles zeichnen, die auch wirklich im Sichfeld (also im Fenster) liegen...

Edit: Mit dieser Abfrage:

Code: [AUSKLAPPEN]
If aktuelleTileX >= 0 And aktuelleTileX <= 672 And aktuelleTileY >= -32 And aktuelleTileY <= 480


Danke... hab ich auch eingebaut, allerdings mit aktuelleTileX >= -32, da sonst beim links-scrollen die Tiles immer so abgehackt wurden.

BladeRunner hat Folgendes geschrieben:
Im Prinzip gibst Du Dir die Antwort schon selbst:
Zeichne nur was auch zu sehen ist, Berechne im Wesentlichen im Sichtbereich und wenn Du noch Rechenzeit übrig hast arbeite die nicht sichtbaren Teile häppchenweise ab ohne sie zu zeichnen. Auf diese Art und weise werden die Berechnungen im nicht sichtbaren Bereich eventuell ein wenig vereinfacht, aber selbst das muss nicht so sein, denn üblicherweise ist das Einzeichnen der Flaschenhals, zumindest wenn nicht hochkomplexe Berechnungen angestellt werden.


Jetzt ist aber die Frage, wie ich rausbekomme, ob noch Rechenzeit übrig ist... - eventuell mit der Framerate bzw. mit den MilliSecs? Und wie würde man den nichtsichtbaren Bereich am besten häppchenweise abarbeiten?

theotheoderich

BeitragMo, Aug 31, 2009 10:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Die Frage ist doch, wie oft der nichtsichtbare Bereich aktualisiert werden muss.

Für ein Städtebauspiel wie z. B. SimCity würde es reichen, wenn diese Felder nur alle 30-60 Sekunden einmal aktualisiert würden, oder bei Bedarf per Trigger (Auslöser).
Gruß
TheoTheoderich
--
The box label said, "Requires Windows XP or better.", so I bought an Amiga Computer.
 

AmenO

BeitragMo, Aug 31, 2009 10:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Gut, dann müsste ich mich mal mit Tiggern beschäftigen *gg

Das werde ich dann heute oder morgen (je nachdem, wann meine Maussteuerung funktioniert) mal probieren Smile.
 

AmenO

BeitragDi, Sep 01, 2009 15:44
Antworten mit Zitat
Benutzer-Profile anzeigen
So... soweit sogut... eigentlich funktioniert auch schon alles, bis auf die Ermittlung, welche Teile der Karte nicht dargestellt werden müssen. Ich kann zwar den Anfang meiner Schleifen bestimmen, aber nicht das Ende bzw. andersrum gehts auch. Wenn ich eins von beiden festlege, wird noch alles normal dargestellt, allerdings werden die Schleifen dann immer noch relativ häufig durchlaufen. Wenn ich beispielsweise folgenden Code verwende:

Code: [AUSKLAPPEN]
   For Zeile = 0 + Abs(offsetX) / 64 To mapHoehe - 1
   
      aktuelleTileX = cX
      aktuelleTileY = cY
   
      For Spalte = 0 + Abs(offsetY + 18) / 32 To mapBreite - 1


user posted image

dann wird zwar bei jedem Kachel, den man auf der Y-Achse runtergeht ein neuer links und rechts hinzugefügt und das ganze auch richtig dargestellt (s.o). Das Problem ist jedoch, dass die Schleifen dann trotzdem noch länger laufen, als nötig. Wenn beispielweise bei Abs(offsetX) und Abs(offsetY + 18) - von der 18 nicht täuschen lassen... die kommt durch das Menü zustande - eine 1 rauskommt, dann beginnen beide Schleifen bei 1, enden aber trotzdem bei mapHoehe - 1 bzw. mapBreite - 1. Somit laufen die Schleifen trotzdem länger, als eigentlich notwendig. Ich dachte mir dann, dass ich ganz einfach z.B. die Schleifen bis 22 + Offset laufen lassen kann, allerdings wird dann meine Karte immer verkürzt dargestellt.

Code: [AUSKLAPPEN]
   For Zeile = 0 + Abs(offsetX) / 64 To 22 + (Abs(offsetX) / 64)
   
      aktuelleTileX = cX
      aktuelleTileY = cY
   
      For Spalte = 0 + Abs(offsetY + 18) / 32 To 22 + ((Abs(offsetY) +18) / 32)


Wenn ich das einbaue, dann sieht das in etwa wie folgt aus:

user posted image

PS: Bei dem Bild habe ich mal 16 statt 22 gewählt, damit man das Problem deutlicher sieht Wink - die Karte hat eigentlich eine größe von 150 x 150 Kacheln. Aber durch das Schleifenende werden immer nur die 16 bzw. 17 angezeigt und somit der Bildschirm nicht komplett ausgefüllt.
Mit den Zahlen am oberen Rand hab ich nur ein bisschen rumprobiert... was aber halt leider keinen Erfolg zeigte Sad.

Deshalb hoffe ich mal, dass ihr mir hier helfen könnt Smile
 

Kruemelator

BeitragDi, Sep 01, 2009 19:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Bei der oberen Bild werden die Felder in den Ecken des "Iso-Bereiches" mit gerechnet auch wenn sie nicht zusehen sind. Wenn du das verhinderst dann könnte es auch nochmal schneller laufen.
 

AmenO

BeitragDi, Sep 01, 2009 19:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja, das stimmt... das Problem ist aber momentan eher, dass ich das Festlegen des sichtbaren Bereichs nicht hinbekomme bzw. das ganze immer Verschoben dargestellt wird.

Oh man... jetzt sitz ich schon seit heute Vormittag an dem Problem und hab immer noch keine Lösung gefunden Sad. Ich bin zumindest soweit, dass ich untergefähr weiß wo das Problem liegt, aber ich weiß nicht 100%ig warum.
 

da_poller

BeitragDi, Sep 01, 2009 21:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Code: [AUSKLAPPEN]

for x=0 to sizex-1
for y=0 to sizey-1

px=x*tsize
py=y*tsize

if px>-tsize and px<screenx+tsize
if py>-tsize and py<screeny+tsize

;zeichne dein tile wie auch immer

endif
endif

next
next

verzeiht die mangelnde einrückung is hier nur mal eben getippt
so würd ich des machen..
fehler, die in der eile eben passiert sind bitte übersehen
 

AmenO

BeitragDi, Sep 01, 2009 21:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich hab den Code eben mal probiert, allerdings laufen die For-Schleifen ebenso wie meine zu lang bzw. länger als nötig, was ich ja eben verhindern möchte.

Momentan hab ich zumindest herausgefunden, dass ich die entsprechnede Schnittlänge in Kacheln brauche (also wenn die Karte bzw. die Anzeige bei 30 aufhört, dann müssten sich die beiden bei bei nach 30 Kacheln treffen). Soweit funktioniert das jetzt schon, allerdings rechnet mein Code noch ein bisschen falsch und er funktioniert auch nur, wenn man direkt nach unten scrollt - man darf also auf der x-Achse nicht hin- und herscrollen, sonst kann es sein, dass rechts oder links was abgeschnitten wird.
 

da_poller

BeitragDi, Sep 01, 2009 21:37
Antworten mit Zitat
Benutzer-Profile anzeigen
die schleifen zu lange? lass mal 1 schleifen ineinander bis 1 mio laufen und miss die zeit..

die schleifen sind kaum rechenzeit das ZEICHNEN frisst dir die performance
 

AmenO

BeitragDi, Sep 01, 2009 21:59
Antworten mit Zitat
Benutzer-Profile anzeigen
Der Arbeitsaufwand für die Schleifen ist zwar gering, dennoch haben zwei ineinander geschachtelte Schleifen eine quadratische Laufzeit Wink. - Naja, also ich habs jetzt mal mit Framerate getestet und wenn ich ein komplett bebautes Bild vor mir habe, also wo Häuse drauf sind, dann liegt die Framerate bei 35 bis 40.

Über einer leeren Baufläche bei ca. 60 FPS.
 

da_poller

BeitragDi, Sep 01, 2009 22:03
Antworten mit Zitat
Benutzer-Profile anzeigen
AmenO hat Folgendes geschrieben:
Der Arbeitsaufwand für die Schleifen ist zwar gering, dennoch haben zwei ineinander geschachtelte Schleifen eine quadratische Laufzeit Wink.


dessen bin ich mir bewust, jedoch macht es in meinen augen keinen sinn die schleifen (bei iso tiles) zu beschneiden.

du hast ne frage gestellt, ich hab dir meinen vorschlag zur lösung gegeben ob du ihn annimmst ist deine sache. jedenfalls viel erfolg bei.
 

AmenO

BeitragDi, Sep 01, 2009 22:06
Antworten mit Zitat
Benutzer-Profile anzeigen
da_poller hat Folgendes geschrieben:
AmenO hat Folgendes geschrieben:
Der Arbeitsaufwand für die Schleifen ist zwar gering, dennoch haben zwei ineinander geschachtelte Schleifen eine quadratische Laufzeit Wink.


dessen bin ich mir bewust, jedoch macht es in meinen augen keinen sinn die schleifen (bei iso tiles) zu beschneiden.

du hast ne frage gestellt, ich hab dir meinen vorschlag zur lösung gegeben ob du ihn annimmst ist deine sache. jedenfalls viel erfolg bei.


War ja nicht Böse gemeint Wink ... ich werde jetzt erstmal so wie bisher weitermachen Wink - also von 0 bis Kartengröße laufen lassen. Ich habe mir eben mal TheoTown angesehen und dort ist die Framerate auch in etwa so wie bei mir, wobei ich auch noch keine animierten Gebäude habe.

Wie gesagt... danke erstmal und deinen Vorschlage werde ich beherzigen Wink

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group