Zu berechnende Tiles bestimmen

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

 

Krischan

Betreff: Zu berechnende Tiles bestimmen

BeitragDo, Feb 26, 2009 17:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich häng mal wieder an einer kniffeligen Sache fest, daher die Frage an Euch ob Ihr mir helfen könnt. Es geht um folgendes: ich habe eine 8192x4096 grosse Map, die in 32x16 Tiles à 256x256 Pixel zerschnibbelt ist. Eine Funktion kann anhand der X/Y-Position eines Tiles dieses gezielt als Bild berechnen. Jetzt bin ich an dem Punkt, an dem diese riesige Karte auf dem Bildschirm dargestellt werden soll. Da die wenigsten einen 8192x4096er Bildschirm haben nehmen wir mal beispielsweise eine Auflösung von 800x600 an.

Zur Veranschaulichung habe ich dazu mal eine kleine Animation gebastelt:
user posted image

Das violette Rechteck ist der aktuell sichtbare Teil auf dem Bildschirm (die 800x600). Wir nehmen an, dass sich der Bildschirm nach unten rechts bewegen wird. Grün sind alle Tiles, die bereits berechnet sind, Blau sind die Tiles, die daher berechnet werden müssen, bevor der sichtbare Teil dorthin gelangt und rot sind die Tiles, die überflüssig geworden sind (ausserhalb der Sichtweite/Richtung) und aus dem Speicher gelöscht werden können (oder man lässt sie dort als Cache wenn genug RAM da ist).

Die erste Frage dazu ist: wie finde ich heraus, welche Tiles sich innerhalb dieses 800x600 Ausschnitts befinden, also schon berechnet sein müssen, damit dieser Ausschnitt der Karte angezeigt wird und vollständig durch Tiles abgedeckt ist?

Die zweite Frage dazu ist: wie stellt man anhand einer Bewegung/Vektors fest, welches die nächsten Tiles in der Bewegungsrichtung sind, die berechnet werden müssen (also die, die dann vom Screen ziemlich sicher abgedeckt werden)?

Die dritte Frage dazu ist: wie stelle ich es an, dass die Karte tiletechnisch rechts/links nicht aufhört, sondern die linken/rechten Tiles in diese Berechnungen miteinbezieht aber hingegen oben und unten begrenzt ist? Hintergrund: diese Karte stellt einen Planeten dar, auf dem nachher ein Fahrzeug herumfahren soll. Da der Planet rund ist kann man also ringsherum drauf fahren (dass man Richtung Pole die Karte anhalten muss lässt sich dann halt nicht vermeiden, sonst müsste man eine 3D- Lösung bauen, auf der man direkt auf der Kugel herumfährt).


Ich habe dazu einen Beispielcode gebaut, an dem Ihr ein wenig herumspielen könnt:
Code: [AUSKLAPPEN]
scrw=512         ; Kartengrösse X
scrh=256         ; Kartengrösse Y

sw=80            ; Bildschirmgrösse X
sh=60            ; Bildschirmgrösse Y

tw=16            ; Tilegrösse X
th=16            ; Tilegrösse Y

Graphics scrw,scrh,32,2

tx=scrw/tw         ; Anzahl Tiles X
ty=scrh/th         ; Anzahl Tiles Y

Dim tiles(tx,ty)   ; Tilefeld

; Bildschirm erstellen
screen=CreateImage(sw,sh)
SetBuffer ImageBuffer(screen)
Color 255,0,255
Rect 0,0,sw,sh,1
SetBuffer BackBuffer()

; leeres Rasterfeldimage erstellen
rasterleer=CreateImage(tw,th)
SetBuffer ImageBuffer(rasterleer)
Color 0,255,0
Rect 0,0,tw+1,th+1,0
SetBuffer BackBuffer()

; fertig berechnetes Rasterfeldimage erstellen
rasterfertig=CreateImage(tw,th)
SetBuffer ImageBuffer(rasterfertig)
Color 0,255,0
Rect 0,0,tw,th,0
Color 0,128,0
Rect 1,1,tw,th,1
SetBuffer BackBuffer()

; zu berechnendes Rasterfeldimage erstellen
rasterberechnen=CreateImage(tw,th)
SetBuffer ImageBuffer(rasterberechnen)
Color 0,255,0
Rect 0,0,tw,th,0
Color 0,0,255
Rect 1,1,tw,th,1
SetBuffer BackBuffer()

; zu löschendes Rasterfeldimage erstellen
rasterloeschen=CreateImage(tw,th)
SetBuffer ImageBuffer(rasterloeschen)
Color 0,255,0
Rect 0,0,tw,th,0
Color 255,0,0
Rect 1,1,tw,th,1
SetBuffer BackBuffer()

Color 255,255,255

MoveMouse scrw/2,scrh/2

While Not KeyHit(1)
   
   Cls
   
   ; Mausposition
   mx=MouseX()
   my=MouseY()
   
   ; Tileposition der Maus
   xx=mx/tw
   yy=my/th
   
   ; Bildschirm begrenzen Y
   If my<(sh/2) Then my=(sh/2)
   If my>scrh-(sh/2) Then my=scrh-(sh/2)
   
   ; Bildschirm einzeichnen
   DrawImage screen,mx-(sw/2),my-(sh/2)
   
   ; Alle Tiles durchgehen
   For x=0 To tx-1
      
      For y=0 To ty-1
         
         ; das  Tile ist erst einmal leer / unbenötigt
         image=rasterleer
         
         ; es sei denn es ist schon berechnet
         If tiles(x,y)=1 Then image=rasterfertig
         
         ; oder ist ist noch zu berechnen
         If tiles(x,y)=2 Then image=rasterberechnen
         
         ; oder ist ist ueberfluessig und kann gelöscht werden
         If tiles(x,y)=4 Then image=rasterloeschen
         
         ; Tile einzeichnen
         DrawImage image,x*tw,y*th
         
      Next
      
   Next
   
   ; Ausgabe Mausposition
   Text 0,0,mx+","+my
   
   ; Ausgabe Tileposition der Maus
   Text 0,15,xx+","+yy
   
   Flip 0
   
Wend

End


Ich hänge seit Tagen an diesem Problem fest, zu Hilfe!!!

BladeRunner

Moderator

BeitragDo, Feb 26, 2009 17:45
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
Die dritte Frage dazu ist: wie stelle ich es an, dass die Karte tiletechnisch rechts/links nicht aufhört, sondern...

Wenn Du die Tiles in einem Array gespeichert hast:
gegeben sei Array(32,16) und zu berechnender Bereich(sx,sy,w,h)
zu prüfendes x ist (sx+w)mod 32.

Beispiel:
Kartenausscnitt ist (29,11 / 6,4). 29+6 ergibt 35, was ja größer als die Karte ist. Mod 32 ergibt 3, was auch stimmt, denn das Tile ragt ja 3 stellen von links wieder rein. Daher ist dies ein valides Tile zum einzeichnen, wenn der Kartenausschnitt bei x=29 beginnt.
Die Position auf dem Bildschirm musst du allerdings noch anhand der Ausschnittswerte ohne mod lassen:

Ausgabe:
Code: [AUSKLAPPEN]
for breite = sx to sx+w
    X = (breite*256)-(sx*256)
   ...
...
drawimage tile(breite mod 32,y),X,Y
next

Ich hoffe das hilft.
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

hectic

Sieger des IS Talentwettbewerb 2006

BeitragDo, Feb 26, 2009 18:24
Antworten mit Zitat
Benutzer-Profile anzeigen
Zur ersten Frage: Man zeichnet immer nur ''direkt auf dem Bildschirm'' und lediglich der Datenzugriff wird variiert. Siehe dazu Code unten.

Zur zweiten Frage: Hab ich erst nach dem 5. lesen verstanden, was gemeint ist. Dazu einfach den ''sichtbaren Breich'' vergrößern. Dieser schliesst dann bereits kommende Dateninhalte mit ein.

Zur dritten Frage: Hat bereits BladeRunner geklärt. Ich habe es allerdings in den Code mit eingebaut. Sonst hätte ich einfach auf die FAQ verlinkt, da aus disem der Code verändert werden mußte.

Code: [AUSKLAPPEN]
Graphics 600,600,0,2
SetBuffer BackBuffer()

Const TILESIZE=40

Local Timer=CreateTimer(60)
Local GetX,GetY
Local X,Y,Block
Local MapXPos
Local MapYPos
Dim Map(9,9)

;EINE ZUFALLS-MAP ERSTELLEN
For Y=0 To 9
   For X=0 To 9
      Map(X,Y)=Rand(X)
   Next
Next


While Not KeyDown(1)
   
   MapXPos=MouseX()
   MapYPos=MouseY()
   
   ;DIE SICHTBARE MAP EINGRENZEN
   For Y=1 To 14
      For X=1 To 14
         
         ;DIE TILE-ID (HIER FARBE) ZWISCHENSPEICHERN
         GetX=(X+MapXPos/TILESIZE) Mod 10
         GetY=(Y+MapYPos/TILESIZE) Mod 10
         Block=Map(GetX,GetY)
         
         ;WENN DIE TILE-ID GÜLTIG IST (ALSO VORHANDEN)
         If Block>0 Then
            
            ;IN DIESEM FALL (WEIL KEIN BILD GELADEN) DIE FARBE ANPASSEN
            Color Block*20,0,0
            
            ;IN DIESEM FALL (WEIL KEIN BILD GELADEN) EIN RECT EINZEICHNEN
            Rect (Int(MapXPos/TILESIZE)*TILESIZE)-MapXPos+X*TILESIZE,(Int(MapYPos/TILESIZE)*TILESIZE)-MapYPos+Y*TILESIZE,TILESIZE,TILESIZE,1
            
         End If
         
      Next
   Next
   
   WaitTimer Timer
   Flip 0
   Cls
Wend
End


Ich hoffe es hilft. Es ist - wie du sehen kannst - eine unendlich scrollende Map.
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D

SpionAtom

BeitragDo, Feb 26, 2009 20:14
Antworten mit Zitat
Benutzer-Profile anzeigen
Falls es noch aktuell ist, Beispiel 2 sollte ganz gut passen:
Steuern mit der Maus per Drag&Drop.
https://www.blitzforum.de/foru...829#310829


Sämtliche Werte am Anfang ließen sich anpassen.
os: Windows 10 Home cpu: Intel Core i7 6700K 4.00Ghz gpu: NVIDIA GeForce GTX 1080

DerHase

BeitragDo, Feb 26, 2009 20:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Hier hat´s auch noch was von mir *Klick*. Leider geschlossen deshalb hab ich dit nicht weitergeführt.
Play Satyr!

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group