Seite 4 von 4

Verfasst: 14.10.2007 20:42
von #NULL
hier nochmal ein cödchen.
ohne scrolling.

Code: Alles auswählen

EnableExplicit

Define w.l            = 12 ; -- kartengoesse
Define h.l            = 9  ; _/

Define playerIndexX.l      ; -- player position (array-index)
Define playerIndexy.l      ; _/

Define offX.l         = 60 ; -- offset der gesamten darstellung (pixel)
Define offY.l         = 40 ; _/

Define i.l,k.l

InitSprite()
InitKeyboard()
OpenScreen(1024,768,32,"fllscrn")

Enumeration
  #sprPlayer
  #sprDunkel
  #sprHell
EndEnumeration

CreateSprite(#sprPlayer,64,64)
  StartDrawing( SpriteOutput(#sprPlayer) )
    Circle(32,32,16,$ff0000)
  StopDrawing()
CreateSprite(#sprDunkel,64,64)
  StartDrawing( SpriteOutput(#sprDunkel) )
    Box(2,2,60,60,$aa3333)
  StopDrawing()
CreateSprite(#sprHell,64,64)
  StartDrawing( SpriteOutput(#sprHell) )
    Box(2,2,60,60,$aa6666)
  StopDrawing()

Dim map.l(w,h)
For i=0 To w
  For k=0 To h
    If Random(3)
      map(i,k)=#sprHell
      playerIndexX = i  ; -- nur damit der spieler auch wirklich auf einem hellen feld steht
      playerIndexy = k  ; _/
    Else
      map(i,k)=#sprDunkel
    EndIf
  Next
Next



Procedure ERLAUBT(indexX.l, indexY.l)
  Shared map(), w, h
  If indexX>=0 And indexY>=0 And indexX<=w And indexY<=h And map(indexX,indexY)=#sprHell
    ProcedureReturn #True
  Else
    ProcedureReturn #False
  EndIf
EndProcedure




Repeat
  ExamineKeyboard()
  StartDrawing( ScreenOutput() )
    ;DrawText(100,100, Str(MouseDeltaX())+", "+Str(MouseDeltaY()) )
    ;Circle(MouseX(),MouseY(),5,$770000)
  StopDrawing()
  
  If KeyboardPushed(#PB_Key_Right) And ERLAUBT(playerIndexX+1, playerIndexY)
    playerIndexX+1
  EndIf
  If KeyboardPushed(#PB_Key_Left) And ERLAUBT(playerIndexX-1, playerIndexY)
    playerIndexX-1
  EndIf
  If KeyboardPushed(#PB_Key_Up) And ERLAUBT(playerIndexX, playerIndexY-1)
    playerIndexY-1
  EndIf
  If KeyboardPushed(#PB_Key_Down) And ERLAUBT(playerIndexX, playerIndexY+1)
    playerIndexY+1
  EndIf
  
  For i=0 To w
    For k=0 To h
      DisplaySprite( map(i,k),  offX+ i*64,  offY + k*64)
    Next
  Next
  DisplayTransparentSprite(0,  offX + playerIndexX*64,  offY + playerIndexY*64)


  FlipBuffers()
  ClearScreen(0)
  Delay(50)
Until KeyboardReleased(#PB_Key_Escape) 

Verfasst: 14.10.2007 20:51
von C4rizz
Heureka
Tausend Dank genau das war gesucht :allright:

Verfasst: 14.10.2007 20:57
von C4rizz
Obwohl sich jetzt noch die Frage stellt ist es denn auch bei dem andern code möglich?
Ich mein der andere code bietet viel mehr flexiblität, denn ich kann den player stufenlos lenken , ausserdem bleibt er stehts im Mittelpunkt.
Also perfekt wäre es wenn ich auf dem ersten code eine Kollision hinbekommen würde, aber ich hab kein plan wie :(
Kannst mir da vileicht auchnoch helfen??

Verfasst: 14.10.2007 21:39
von #NULL
also stufenlos ging es mit dem anderen code genausowenig wie mit dem letzten.
aber wenn du den spieler immer im mittelpunkt haben willst (beim letzten code):
die offX/Y variablen sind ja schon drin. mit denen versetzt du einfach alles
zusätzlich, wenn sich der spieler bewegt:

Code: Alles auswählen

  If KeyboardPushed(#PB_Key_Right) And ERLAUBT(playerIndexX+1, playerIndexY)
    playerIndexX+1
    offX-64
  EndIf
der spieler kommt am anfang in die mitte auf ein begehbares feld:

Code: Alles auswählen

;player kommt in die mitte..
playerIndexX = w/2
playerIndexy = h/2
;..und das feld muss weiß sein
map(playerIndexX,playerIndexy) = #sprHell
dann noch die karte am anfang mittig setzten..

das sieht dann so aus:

Code: Alles auswählen

EnableExplicit

Define w.l            = 16 ; -- kartengoesse
Define h.l            = 12 ; _/

Define playerIndexX.l      ; -- player position (array-index)
Define playerIndexy.l      ; _/

Define screenWidth  = 1024
Define screenHeight = 768

Define offX.l = screenWidth /2 - 64*w/2  ; -- offset der gesamten darstellung (pixel)
Define offY.l = screenHeight/2 - 64*h/2  ; _/ ..hier so gesetz, dass die karte mittig ist

Define i.l,k.l

InitSprite()
InitKeyboard()
OpenScreen(screenWidth,screenHeight,32,"fllscrn")

Enumeration
  #sprPlayer
  #sprDunkel
  #sprHell
EndEnumeration

CreateSprite(#sprPlayer,64,64)
  StartDrawing( SpriteOutput(#sprPlayer) )
    Circle(32,32,16,$ff0000)
  StopDrawing()
CreateSprite(#sprDunkel,64,64)
  StartDrawing( SpriteOutput(#sprDunkel) )
    Box(2,2,60,60,$aa3333)
  StopDrawing()
CreateSprite(#sprHell,64,64)
  StartDrawing( SpriteOutput(#sprHell) )
    Box(2,2,60,60,$aa6666)
  StopDrawing()

Dim map.l(w,h)
For i=0 To w
  For k=0 To h
    If Random(3)
      map(i,k)=#sprHell
    Else
      map(i,k)=#sprDunkel
    EndIf
  Next
Next


;player kommt in die mitte..
playerIndexX = w/2
playerIndexy = h/2
;..und das feld muss weiß sein
map(playerIndexX,playerIndexy) = #sprHell




Procedure ERLAUBT(indexX.l, indexY.l)
  Shared map(), w, h
  If indexX>=0 And indexY>=0 And indexX<=w And indexY<=h And map(indexX,indexY)=#sprHell
    ProcedureReturn #True
  Else
    ProcedureReturn #False
  EndIf
EndProcedure



Repeat
  ExamineKeyboard()
  StartDrawing( ScreenOutput() )
    ;DrawText(100,100, Str(MouseDeltaX())+", "+Str(MouseDeltaY()) )
    ;Circle(MouseX(),MouseY(),5,$770000)
  StopDrawing()
 
  If KeyboardPushed(#PB_Key_Right) And ERLAUBT(playerIndexX+1, playerIndexY)
    playerIndexX+1
    offX-64
  EndIf
  If KeyboardPushed(#PB_Key_Left) And ERLAUBT(playerIndexX-1, playerIndexY)
    playerIndexX-1
    offX+64
  EndIf
  If KeyboardPushed(#PB_Key_Up) And ERLAUBT(playerIndexX, playerIndexY-1)
    playerIndexY-1
    offY+64
  EndIf
  If KeyboardPushed(#PB_Key_Down) And ERLAUBT(playerIndexX, playerIndexY+1)
    playerIndexY+1
    offY-64
  EndIf
 
  For i=0 To w
    For k=0 To h
      DisplaySprite( map(i,k),  offX+ i*64,  offY + k*64)
    Next
  Next
  DisplayTransparentSprite(0,  offX + playerIndexX*64,  offY + playerIndexY*64)


  FlipBuffers()
  ClearScreen(0)
  Delay(50)
Until KeyboardReleased(#PB_Key_Escape)

Verfasst: 14.10.2007 21:43
von C4rizz
Ok alles klärchen Danke

Verfasst: 17.10.2007 10:13
von ZeHa
Meiner Meinung nach sollte der Code immer so aufgebaut sein:

- Eine Map, die aus Tiles besteht, in Form eines Arrays
- Jedes Objekt hat absolute X/Y-Koordinaten, die sich immer auf die tatsächliche Position beziehen, und nicht auf den Mittelpunkt des Bildschirms oder so etwas
- Es gibt eine "Kamera", die ebenfalls ein X und ein Y hat, das wäre im obigen Beispiel das "Offset"
- Die Kamera wird an ein Objekt gebunden, z.B. an den Spieler, sprich, nach jedem Update werden die Kamera-Koordinaten erstmal vom Spieler übernommen
- Vor demRendern wird von der Kameraposition noch entsprechend die Hälfte der Bildschirmbreite und die Hälfte der Bildschirmhöhe abgezogen
- Danach wird allerdings geprüft, ob die Kamera sich noch so auf der Karte befindet, daß der Bildschirm noch vollständig gefüllt ist. Wenn nicht, werden die Kamera-Koordinaten entsprechend korrigiert
- Nun wird alles gerendert, indem bei jedem Objekt, das auf den Schirm kommt, sei es ein Tile oder ein bewegliches Objekt, die Kamera-Koordinaten abgezogen werden

Mit dieser Vorgehensweise hat man a) den Vorteil, daß man die Kamera auch an andere Objekte binden kann, je nachdem, was man halt vorhat, und b) scrollt die Karte nur so lange, bis man am Rand ankommt. Wenn man sich also Richtung Rand bewegt, wird die Spielfigur letztendlich doch nicht mehr in der Mitte des Bildes angezeigt, sondern die Karte hört auf zu scrollen und die Figur läuft einfach noch bis an den Rand. Und das funktioniert dann auch problemlos bei jeder Map-Größe und bei jeder Bildschirm-Auflösung.