Tilemaps

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
a14xerus
Beiträge: 1440
Registriert: 14.12.2005 15:51
Wohnort: Aachen

Tilemaps

Beitrag 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
a14xerus
Beiträge: 1440
Registriert: 14.12.2005 15:51
Wohnort: Aachen

Beitrag 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
Benutzeravatar
#NULL
Beiträge: 2239
Registriert: 20.04.2006 09:50

Beitrag 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
my pb stuff..
Bild..jedenfalls war das mal so.
a14xerus
Beiträge: 1440
Registriert: 14.12.2005 15:51
Wohnort: Aachen

Beitrag 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
Benutzeravatar
#NULL
Beiträge: 2239
Registriert: 20.04.2006 09:50

Beitrag 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)

Code: Alles auswählen

For SY=0 To 38
bei der indexangabe des arrays addiert er aber immer noch ein MapX

Code: Alles auswählen

MapX+SX
. 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
my pb stuff..
Bild..jedenfalls war das mal so.
a14xerus
Beiträge: 1440
Registriert: 14.12.2005 15:51
Wohnort: Aachen

Beitrag von a14xerus »

cool danke
Antworten