Seite 1 von 1
Tilemaps
Verfasst: 20.11.2006 15:27
von a14xerus
Hi Leute, hat einer ein gutes Tutorial doer Beispiel für Tilemapping?
Ich will eine Scrollbare Map darstellen, dun zwar so, das (speichersparend) nur die tiles angezeigt werden die auch zu sehen sind
TIA
Verfasst: 20.11.2006 17:28
von a14xerus
also ich habe es bis jetzt schon selber geschafft tiles in ein array zu laden und anzuzeigen, auch zu scrollen
aber wie schaffe ich es, nur die tiles anzuzeigen, die auch nötig sind?
Code: Alles auswählen
Procedure error(info.s)
Protected Msg$
Msg$ + "Fehler bei der Initialisierung."
Msg$ + Chr(10)
Msg$ + "DirectX Vers. 7 oder höher wurde nicht gefunden."
Msg$ + Chr(10)
Msg$ + "Eine Neuinstallation sollte das Problem lösen."
MessageRequester("Fehler - "+info,Msg$,#MB_OK|#MB_ICONWARNING)
End
EndProcedure
Procedure ende()
End
EndProcedure
If Not InitSprite()
error("Screen")
EndIf
If Not InitSprite3D()
error("3D")
EndIf
If Not InitKeyboard()
error("Keyboard")
EndIf
If Not InitSound()
error("Sound")
EndIf
If Not InitMouse()
error("Maus")
EndIf
RandomSeed(Date())
Structure xy
x.d
y.d
EndStructure
Global Pos.xy
Pos\x = -100
Pos\y = -100
Global oldTime.f
Global time.f
Global xres = 1024
Global yres = 768
Global anzahlx = xres / 32 +2
Global anzahly = yres / 32 +2
OpenScreen(xres,yres,32,"Game")
Global schwarz = CreateSprite(#PB_Any,32,32)
Global weiss = CreateSprite(#PB_Any,32,32)
Global player = CreateSprite(#PB_Any,10,10)
StartDrawing(SpriteOutput(schwarz))
Box(0,0,32,32,0)
StopDrawing()
StartDrawing(SpriteOutput(weiss))
Box(0,0,32,32,$FFFFFF)
StopDrawing()
StartDrawing(SpriteOutput(player))
Box(0,0,10,10,$FF0000)
StopDrawing()
Global Dim map(1000,1000)
For i = 0 To 1000
For k = 0 To 1000
If Random(1)
map(i,k) = schwarz
Else
map(i,k) = weiss
EndIf
Next
Next
Repeat
Delay(1)
ClearScreen($C0C0C0)
ExamineKeyboard()
ExamineMouse()
mouseX = MouseX()
mouseY = MouseY()
DeltaX = MouseDeltaX()
DeltaY = MouseDeltaY()
If KeyboardPushed(#PB_Key_Up)
Pos\y + 1
ElseIf KeyboardPushed(#PB_Key_Down)
Pos\y - 1
EndIf
If KeyboardPushed(#PB_Key_Left)
Pos\x + 1
ElseIf KeyboardPushed(#PB_Key_Right)
Pos\x - 1
EndIf
StartDrawing(ScreenOutput())
DrawText(600,0,Str(DeltaX)+" - "+Str(DeltaY))
StopDrawing()
For i = 0 To 1000
For k = 0 To 1000
DisplaySprite(map(i,k),(i*32)+Pos\x,(k*32)+Pos\y)
Next
Next
If KeyboardPushed(#PB_Key_Escape)
ende()
EndIf
;[ FPS
oldTime = time
time = ElapsedMilliseconds()
frameTime.f = (time - oldTime) / 1000.0
fps.f = 1/frameTime
StartDrawing(ScreenOutput())
If fps < 5 Or fps > 60
fps_farbe = $0000FF
DrawText(800/2-20,600/2-20,"!!!",$0000FF,0)
ElseIf fps > 18
fps_farbe = $00FF00
Else
fps_farbe = 0
EndIf
DrawText(400,0,StrF(fps,2)+" fps ("+StrF(frameTime,2)+")",fps_farbe)
StopDrawing()
frameTime * 20
;]
FlipBuffers()
ForEver
Verfasst: 20.11.2006 18:39
von #NULL
man kann prüfen, ob die zeichenposition im screen liegt.
Code: Alles auswählen
For i=0 To mapMaxX
x=offX+i*64
If x > -65 And x < #sw
For k=0 To mapMaxY
y=offY+k*64
If y > -65 And y < #sh
DisplaySprite( map(i,k), x,y )
EndIf
Next
EndIf
Next
das ist aber bei deiner großen map nicht ausreichend, weil das riesen array trotzdem durchlaufen wird. also muß du für die For-schleifen start- und end-werte berechnen, und nur den sichtbaren teil der map überhaup durchlaufen. hier ist eine demo von Kaeru Gaman dazu (und überhaupt gibt es im forum mittlerweile einiges zum thema):
http://www.purebasic.fr/german/viewtopi ... ht=#116634
Verfasst: 20.11.2006 18:42
von a14xerus
Das ich die Strt- udn end-werte der Forschleife errechnen muss, ist mir klar, aber wie?
ich weiß auch, dass es dazu viels gibt, aber ich kontne mir nicht das passende dazu heraussuchen.
Trotzdem danke für den Link
Verfasst: 20.11.2006 19:55
von #NULL
KG hat das so gemacht:
er durchläuft in der breite immer nur 39 tiles des array, soviele wie auf den schirm passen. (analog dazu bezüglich der höhe)
bei der indexangabe des arrays addiert er aber immer noch ein MapX
. dieses MapX wird bei der rechts-/links-verschiebung der map verändert. das geschieht in den tastatur-abfragen, z.b. bei
Code: Alles auswählen
If KeyboardPushed(#PB_Key_Right)
FineX+2
If FineX > 14
FineX = 0
MapX+1
If MapX > 1023-50
MapX = 1023-50
FineX = 14
EndIf
EndIf
EndIf
wenn man nach rechts drückt, wird die map um zwei pixel verschoben (
Fine+2 ). diese zwei pixel werden in der display-funktion dann abgezogen. wenn Fine nun irgendwann die tile breite überschreiten, wird es wieder auf 0 gesetzt, aber dafür MapX um eins erhöht. dann wird noch aufgepasst, das MapX klein genug bleibt, damit später dann keine array-grenzen überschritten werden, denn das rechteste tile im screen hat ja den index MapX
+38.
zum testen kannst du das bild in seinem post auch einfach so benutzen ohne es zu zerplücken, wenn du im code diese stelle:
Code: Alles auswählen
For n=1 To 8
LoadSprite( 100+n, Right("00"+Str(n),3)+".bmp")
Next
durch diese ersetzt
Code: Alles auswählen
UsePNGImageDecoder()
LoadImage(0,"tileset01yi0.png")
For n=1 To 8
CreateSprite(100+n, 16,16)
StartDrawing(SpriteOutput(100+n))
DrawImage(ImageID(0), -(n-1)*18-2, -2)
;Circle(7,7,5,$00ff00)
StopDrawing()
Next
Verfasst: 20.11.2006 20:39
von a14xerus
cool danke