Page 1 of 1

Scrolling and parallax

Posted: Tue Sep 22, 2009 11:15 pm
by Olliv
Hello!

Just a copy from here. It's an example of scrolling of two grounds ("planes").

Ollivier

Code: Select all

EnableExplicit

Macro DisplayP2()
      DisplaySprite(Page4, P2PosX, P2PosY)
      DisplaySprite(Page5, P2PosX - PageW, P2PosY)
      DisplaySprite(Page6, P2PosX, P2PosY - PageH)
      DisplaySprite(Page7, P2PosX - PageW, P2PosY - PageH)
EndMacro

Macro Display()
   DisplayP2()
   DisplayTransparentSprite(Page0, PosX, PosY)
   DisplayTransparentSprite(Page1, PosX - PageW, PosY)
   DisplayTransparentSprite(Page2, PosX, PosY - PageH)
   DisplayTransparentSprite(Page3, PosX - PageW, PosY - PageH)
   FlipBuffers()
EndMacro

Macro SpriteDrawing()
   
   For I = 0 To 3
      CreateSprite(#Syst + I, 16, 16)
      StartDrawing(SpriteOutput(#Syst + I) )
         DrawText(0, 0, "P" + Str(I) )
      StopDrawing()
   Next I
   
   CreateSprite(#Deco, TileSize, TileSize)
   StartDrawing(SpriteOutput(#Deco) )
      Box(0, 0, TileSize, TileSize, 0)
   StopDrawing()
   CreateSprite(#Deco + 1, TileSize, TileSize)
   StartDrawing(SpriteOutput(#Deco + 1) )
      Box(0, 0, TileSize, TileSize, 1)
      Box(1, 1, TileSize - 2, TileSize - 2, #Gray)
      Line(0, 0, TileSize, TileSize, 1)
      Line(TileSize - 1, 0, - TileSize, TileSize, 1)
   StopDrawing()

   CreateSprite(#Deco + 2, TileSize, TileSize)
   StartDrawing(SpriteOutput(#Deco + 2) )
      Box(0, 0, TileSize, TileSize, 1)
      Box(1, 1, TileSize - 2, TileSize - 2, RGB(0, 0, 255) )
      Line(0, 0, TileSize, TileSize, 1)
      Line(TileSize - 1, 0, - TileSize, TileSize, 1)
   StopDrawing()

   CreateSprite(#DispMask, DispW, DispH)
   StartDrawing(SpriteOutput(#DispMask) )
      Box(0, 0, DispW, DispH, #White)
      Box(1, 1, DispW - 2, DispH - 2, #Black)
   StopDrawing()
   
   For I = 0 To 7
      CreateSprite(I, PageW, PageH)
   Next I
EndMacro

Macro P2LevelLoading()
   For Y = 0 To P2LevelTileMaxY
      For X = 0 To P2LevelTileMaxX
         P2Tile(X, Y) = #Deco
      Next X
   Next Y   
   For Y = 0 To P2LevelTileMaxY
      P2Tile(0, Y) = #Deco + 2
      P2Tile(P2LevelTileMaxX, Y) = #Deco + 2
      For X = 0 To P2LevelTileMaxX
         P2Tile(X, 0) = #Deco + 2
         P2Tile(X, P2LevelTileMaxY) = #Deco + 2
         If Random(9) = 0
            P2Tile(X, Y) = #Deco + 2
         EndIf
      Next X
   Next Y
EndMacro

Macro LevelLoading()
   For Y = 0 To LevelTileMaxY
      For X = 0 To LevelTileMaxX
         Tile(X, Y) = #Deco
      Next X
   Next Y   
   For Y = 0 To LevelTileMaxY
      Tile(0, Y) = #Deco + 1
      Tile(LevelTileMaxX, Y) = #Deco + 1
      For X = 0 To LevelTileMaxX
         Tile(X, 0) = #Deco + 1
         Tile(X, LevelTileMaxY) = #Deco + 1
         If Random(9) = 0
            Tile(X, Y) = #Deco + 1
         EndIf
      Next X
   Next Y
   P2LevelLoading()
EndMacro

Macro GetPageNo(X, Y) ; Calcul de la page concernée
   ((X / PageW) & 1) + (((Y / PageH) & 1) << 1)
EndMacro

Macro GetXValue(X) ; Calcul de X dans la page
   ((X % PageW) - (X % TileSize) )
EndMacro

Macro GetYValue(Y) ; Calcul de Y dans la page
   ((Y % PageH) - (Y % TileSize) )
EndMacro

Macro P2GetTile(XX, YY)
   Tile = -1
   TempX = XX / TileSize
   If (TempX => 0)
      If (TempX <= P2LevelTileMaxX)
         TempY = YY / TileSize
         If (TempY => 0)
            If (TempY <= P2LevelTileMaxY)
               Tile = P2Tile(TempX, TempY)
            EndIf
         EndIf
      EndIf
   EndIf
EndMacro

Macro GetTile(XX, YY)
   Tile = -1
   TempX = XX / TileSize
   If (TempX => 0)
      If (TempX <= LevelTileMaxX)
         TempY = YY / TileSize
         If (TempY => 0)
            If (TempY <= LevelTileMaxY)
               Tile = Tile(TempX, TempY)
            EndIf
         EndIf
      EndIf
   EndIf
EndMacro

Macro P2UpdateTile(XX, YY)
   P2GetTile(XX, YY) ; Retourne le global Tile.I
   If Tile <> -1
      P = GetPageNo(XX, YY)
      UseBuffer(P + 4)
         DisplaySprite(Tile, GetXValue(XX), GetYValue(YY) )
      UseBuffer(-1)
   EndIf
EndMacro

Macro UpdateTile(XX, YY)
   GetTile(XX, YY) ; Retourne le global Tile.I
   If Tile <> -1
      P = GetPageNo(XX, YY)
      UseBuffer(P)
         DisplaySprite(Tile, GetXValue(XX), GetYValue(YY) )
      UseBuffer(-1)
   EndIf
EndMacro

Macro P2UpdateTileLeftBorder()
   For Y = (P2LevelY - TileSize) To (P2LevelY + PageH + TileSize) ; Rajouté +TileSize
      P2UpdateTile((P2LevelX - TileSize), Y)
      Y + TileSize
      Y - 1
   Next Y
EndMacro

Macro UpdateTileLeftBorder()
   For Y = (LevelY - TileSize) To (LevelY + PageH + TileSize) ; Rajouté +TileSize
      UpdateTile((LevelX - TileSize), Y)
      Y + TileSize
      Y - 1
   Next Y
EndMacro

Macro P2UpdateTileRightBorder()
   For Y = (P2LevelY - TileSize) To (P2LevelY + PageH)
      P2UpdateTile((P2LevelX + PageW), Y)
      Y + TileSize
      Y - 1
   Next Y
EndMacro

Macro UpdateTileRightBorder()
   For Y = (LevelY - TileSize) To (LevelY + PageH) ; Rajouté -TileSize
      UpdateTile((LevelX + PageW), Y)
      Y + TileSize
      Y - 1
   Next Y
EndMacro

Macro P2UpdateTileUpBorder()
   For X = (P2LevelX - TileSize) To (P2LevelX + PageW + TileSize) ; Rajouté +TileSize
      P2UpdateTile(X, (P2LevelY - TileSize) )
      X + TileSize
      X - 1
   Next X
EndMacro

Macro UpdateTileUpBorder()
   For X = (LevelX - TileSize) To (LevelX + PageW + TileSize) ; Rajouté +TileSize
      UpdateTile(X, (LevelY - TileSize) )
      X + TileSize
      X - 1
   Next X
EndMacro

Macro P2UpdateTileDownBorder()
   For X = (P2LevelX - TileSize) To (P2LevelX + PageW) ;Rajouté -TileSize
      P2UpdateTile(X, (P2LevelY + PageH) )
      X + TileSize
      X - 1
   Next X
EndMacro

Macro UpdateTileDownBorder()
   For X = (LevelX - TileSize) To (LevelX + PageW) ;Rajouté -TileSize
      UpdateTile(X, (LevelY + PageH) )
      X + TileSize
      X - 1
   Next X
EndMacro

Macro P2DrawVisibleTiles()
   For Y = P2LevelY To P2LevelY + PageH
      For X = P2LevelX To P2LevelX + PageW
         P2UpdateTile(X, Y)
         X + TileSize
         X - 1
      Next X
      Y + TileSize
      Y - 1
   Next Y
EndMacro

Macro DrawVisibleTiles()
   For Y = LevelY To LevelY + PageH
      For X = LevelX To LevelX + PageW
         UpdateTile(X, Y)
         X + TileSize
         X - 1
      Next X
      Y + TileSize
      Y - 1
   Next Y
EndMacro

Macro P2MoveLeft()
   P2VitX = VitX / 2
   If P2LevelX > 0           
      If P2LevelX - P2VitX < 0 ; "Sort" du niveau?
         P2VitX = P2LevelX
      EndIf               
      P2PosX + P2VitX
      If P2PosX => PageW
         P2ShiftX + PageW
         P2PosX - PageW
         Page4 ! 1
         Page5 ! 1
         Page6 ! 1
         Page7 ! 1
      EndIf
      P2LevelX = 0 - (P2ShiftX + P2PosX)
      P2OldLevelTileX = P2LevelTileX
      P2LevelTileX = P2LevelX / TileSize
      If P2LevelTileX <> P2OldLevelTileX
         P2UpdateTileLeftBorder()
      EndIf
      DisplayFlag = 1
   EndIf
EndMacro

Macro MoveLeft()
   If LevelX > 0           
      If LevelX - VitX < 0 ; "Sort" du niveau?
         VitX = LevelX
      EndIf               
      PosX + VitX
      If PosX => PageW
         ShiftX + PageW
         PosX - PageW
         Page0 ! 1
         Page1 ! 1
         Page2 ! 1
         Page3 ! 1
      EndIf
      LevelX = 0 - (ShiftX + PosX)
      OldLevelTileX = LevelTileX
      LevelTileX = LevelX / TileSize
      If LevelTileX <> OldLevelTileX
         UpdateTileLeftBorder()
      EndIf
      DisplayFlag = 1
      P2MoveLeft()
   EndIf   
EndMacro

Macro P2MoveRight()
   P2VitX = VitX / 2
   If P2LevelX < (P2LevelW - DispW)
      If P2LevelX + P2VitX > (P2LevelW - DispW) ; "Sort" du niveau?
         P2VitX = (P2LevelW - DispW) - P2LevelX
      EndIf
      P2PosX - P2VitX
      If P2PosX < 0
         P2ShiftX - PageW
         P2PosX + PageW
         Page4 ! 1
         Page5 ! 1
         Page6 ! 1
         Page7 ! 1
      EndIf
      P2LevelX = 0 - (P2ShiftX + P2PosX)
      P2OldLevelTileX = P2LevelTileX
      P2LevelTileX = P2LevelX / TileSize
      If P2LevelTileX <> P2OldLevelTileX
         P2UpdateTileRightBorder()
      EndIf
      DisplayFlag = 1
   EndIf
EndMacro

Macro MoveRight()
   If LevelX < (LevelW - DispW)
      If LevelX + VitX > (LevelW - DispW) ; "Sort" du niveau?
         VitX = (LevelW - DispW) - LevelX
      EndIf
      PosX - VitX
      If PosX < 0
         ShiftX - PageW
         PosX + PageW
         Page0 ! 1
         Page1 ! 1
         Page2 ! 1
         Page3 ! 1
      EndIf
      LevelX = 0 - (ShiftX + PosX)
      OldLevelTileX = LevelTileX
      LevelTileX = LevelX / TileSize
      If LevelTileX <> OldLevelTileX
         UpdateTileRightBorder()
      EndIf
      DisplayFlag = 1
      P2MoveRight()
   EndIf
EndMacro

Macro P2MoveUp()
   P2VitY = VitY / 2
   If P2LevelY > 0
      If P2LevelY - P2VitY < 0 ; "Sort" du niveau?
         P2VitY = P2LevelY
      EndIf
      P2PosY + P2VitY
      If P2PosY => PageH
         P2ShiftY + PageH
         P2PosY - PageH
         Page4 ! 2
         Page5 ! 2
         Page6 ! 2
         Page7 ! 2
      EndIf
      P2LevelY = 0 - (P2ShiftY + P2PosY)
      P2OldLevelTileY = P2LevelTileY
      P2LevelTileY = P2LevelY / TileSize
      If P2LevelTileY <> P2OldLevelTileY
         P2UpdateTileUpBorder()
      EndIf
      DisplayFlag = 1
   EndIf
EndMacro

Macro MoveUp()
   If LevelY > 0
      If LevelY - VitY < 0 ; "Sort" du niveau?
         VitY = LevelY
      EndIf
      PosY + VitY
      If PosY => PageH
         ShiftY + PageH
         PosY - PageH
         Page0 ! 2
         Page1 ! 2
         Page2 ! 2
         Page3 ! 2
      EndIf
      LevelY = 0 - (ShiftY + PosY)
      OldLevelTileY = LevelTileY
      LevelTileY = LevelY / TileSize
      If LevelTileY <> OldLevelTileY
         UpdateTileUpBorder()
      EndIf
      DisplayFlag = 1
   EndIf
   P2MoveUp()
EndMacro

Macro P2MoveDown()
   P2VitY = VitY / 2
   If P2LevelY < (P2LevelH - DispH)
      If P2LevelY + P2VitY > (P2LevelH - DispH) ; "Sort" du niveau?
         P2VitY = (P2LevelH - DispH) - P2LevelY
      EndIf
      P2PosY - P2VitY
      If P2PosY < 0
         P2ShiftY - PageH
         P2PosY + PageH
         Page4 ! 2
         Page5 ! 2
         Page6 ! 2
         Page7 ! 2
      EndIf
      P2LevelY = 0 - (P2ShiftY + P2PosY)
      P2OldLevelTileY = P2LevelTileY
      P2LevelTileY = P2LevelY / TileSize
      If P2LevelTileY <> P2OldLevelTileY
         P2UpdateTileDownBorder()
      EndIf
      DisplayFlag = 1
   EndIf
EndMacro

Macro MoveDown()
   If LevelY < (LevelH - DispH)
      If LevelY + VitY > (LevelH - DispH) ; "Sort" du niveau?
         VitY = (LevelH - DispH) - LevelY
      EndIf
      PosY - VitY
      If PosY < 0
         ShiftY - PageH
         PosY + PageH
         Page0 ! 2
         Page1 ! 2
         Page2 ! 2
         Page3 ! 2
      EndIf
      LevelY = 0 - (ShiftY + PosY)
      OldLevelTileY = LevelTileY
      LevelTileY = LevelY / TileSize
      If LevelTileY <> OldLevelTileY
         UpdateTileDownBorder()
      EndIf
      DisplayFlag = 1
      P2MoveDown()
   EndIf
EndMacro

#Syst = 4096
#DispMask = 16
#Deco = 256

;-______________
;- Globals...   
;-¯¯¯¯¯¯¯¯¯¯¯¯¯¯

Global TileSize.I ; Taille d'un Tile en pixels

Global ScrW.I ; Largeur de l'écran en pixels
Global ScrH.I ; Hauteur de l'écran en pixels
Global ScrD.I ; Profondeur de l'écran en bits par pixels

Global DispX1.I ; Coordonnée de la zone d'affichage
Global DispY1.I ; en pixels
Global DispX2.I ;
Global DispY2.I ;

Global DispW.I  ; Dimensions de l'écran d'affichage
Global DispH.I  ; en pixels

Global PageW.I ; Dimensions d'une page en pixels
Global PageH.I ;

Global PageTileW.I ; Dimensions d'une page en Tiles
Global PageTileH.I ;

Global I.I
Global P.I
Global X.I
Global Y.I
Global Tile.I
Global TempX.I
Global TempY.I

Global Message.S

Global Page0.I = 0
Global Page1.I = 1
Global Page2.I = 2
Global Page3.I = 3
Global Page4.I = 4
Global Page5.I = 5
Global Page6.I = 6
Global Page7.I = 7
;-Vitesse
Global Vit.I = 8

Global PosX.I ; Décalage dans une page
Global PosY.I ; en pixels

Global P2PosX.I ; Décalage dans une page
Global P2PosY.I ; en pixels

Global ShiftX.I ; Décalage page par page
Global ShiftY.I ; en pixels

Global P2ShiftX.I ; Décalage page par page
Global P2ShiftY.I ; en pixels

Global LevelX.I ; Décalage total (page + position)
Global LevelY.I ; en pixels

Global P2LevelX.I ; Décalage total (page + position)
Global P2LevelY.I ; en pixels

Global LevelTileX.I ; Décalage total (page + position)
Global LevelTileY.I ; en Tiles

Global P2LevelTileX.I ; Décalage total (page + position)
Global P2LevelTileY.I ; en Tiles

Global OldLevelTileX.I ; Dans la détection des mises à jour
Global OldLevelTileY.I ; Ancien décalage total en Tiles

Global P2OldLevelTileX.I ; Dans la détection des mises à jour
Global P2OldLevelTileY.I ; Ancien décalage total en Tiles

Global LevelTileW.I ; Dimensions du niveau en Tiles
Global LevelTileH.I ;

Global P2LevelTileW.I ; Dimensions du niveau en Tiles
Global P2LevelTileH.I ;

Global LevelTileMaxX.I ; Limites du niveau en Tiles
Global LevelTileMaxY.I ;

Global P2LevelTileMaxX.I ; Limites du niveau en Tiles
Global P2LevelTileMaxY.I ;

Global LevelW.I ; Dimensions du niveau en pixels
Global LevelH.I ;

Global P2LevelW.I ; Dimensions du niveau en pixels
Global P2LevelH.I ;

Global DisplayFlag.I

Global P2VitX.I
Global P2VitY.I

Global VitX.I
Global VitY.I

Global VitesseX.I
Global VitesseY.I

Global QuitGame.I

Global P2VitXCarry.I

TileSize = 24

LevelTileW = 256
LevelTileH = 256

P2LevelTileW = 192
P2LevelTileH = 192

LevelW = LevelTileW * TileSize
LevelH = LevelTileH * TileSize

P2LevelW = P2LevelTileW * TileSize
P2LevelH = P2LevelTileH * TileSize

LevelTileMaxX = LevelTileW - 1
LevelTileMaxY = LevelTileH - 1

P2LevelTileMaxX = P2LevelTileW - 1
P2LevelTileMaxY = P2LevelTileH - 1

Global Dim Tile.I(LevelTileMaxX, LevelTileMaxY)
Global Dim P2Tile.I(P2LevelTileMaxX, P2LevelTileMaxY)
Delay(99)

   InitSprite()
   InitKeyboard()

   ExamineDesktops()
   ScrW = DesktopWidth(0)
   ScrH = DesktopHeight(0)
   ScrD = DesktopDepth(0)
   
   DispX1 = 0
   DispY1 = 0
   DispX2 = ScrW - 1
   DispY2 = ScrH - 1
   DispW = (DispX2 - DispX1) + 1
   DispH = (DispY2 - DispY1) + 1
   
   PageW = DispW
   PageH = DispH
   PageW - (PageW % TileSize)
   If PageW < DispW: PageW + TileSize: EndIf
   PageH - (PageH % TileSize)
   If PageH < DispH: PageH + TileSize: EndIf

   PageTileW = PageW / TileSize
   PageTileH = PageH / TileSize
   
   OpenScreen(ScrW, ScrH, ScrD, "")
   
   SpriteDrawing()
   LevelLoading()

   DrawVisibleTiles()
   P2DrawVisibleTiles()
   Display()
;-______________
;- Repeat...   
;-¯¯¯¯¯¯¯¯¯¯¯¯¯¯
   Repeat
      ;Delay(99)
      Delay(1)
      DisplayFlag = 0
     
      VitX = Vit
      VitY = Vit
      If ExamineKeyboard()
         If KeyboardPushed(#PB_Key_Left)
            If (VitesseX - 2) > (0 - TileSize)
               VitesseX - 2
            EndIf
         EndIf
         If KeyboardPushed(#PB_Key_Right)
            If (VitesseX + 2) < (TileSize)
               VitesseX + 2
            EndIf
         EndIf
         If KeyboardPushed(#PB_Key_Up)
            If (VitesseY - 2) > (0 - TileSize)
               VitesseY - 2
            EndIf
         EndIf
         If KeyboardPushed(#PB_Key_Down)
            If (VitesseY + 2) < (TileSize)
               VitesseY + 2
            EndIf
         EndIf
         If KeyboardPushed(#PB_Key_Escape)
            QuitGame = 1
         EndIf
      EndIf
      If VitesseX < 0
         VitX = -VitesseX
         MoveLeft()
         VitesseX + 1
      EndIf
      If VitesseX > 0
         VitX = VitesseX
         MoveRight()
         VitesseX - 1
      EndIf
      If VitesseY < 0
         VitY = -VitesseY
         MoveUp()
         VitesseY + 1
      EndIf
      If VitesseY > 0
         VitY = VitesseY
         MoveDown()
         VitesseY - 1
      EndIf
      If DisplayFlag
         Display()
      EndIf
   Until QuitGame
   
   CloseScreen()
   End
   
   

Re: Scrolling and parallax

Posted: Tue Sep 22, 2009 11:48 pm
by Kaeru Gaman
what Language did you program with before you came to PureBasic?

Re: Scrolling and parallax

Posted: Wed Sep 23, 2009 3:05 am
by Rook Zimbabwe
@Kaeru: It looks like PB since 2007!

I like the example by kelebrindae as well!!! Good job both of you! 8)

Re: Scrolling and parallax

Posted: Wed Sep 23, 2009 8:47 am
by Kelebrindae
Thanks, Rook! :D

You may also like those two posts, based on the same code from Ollivier:
http://www.purebasic.fr/french/viewtopic.php?f=2&t=9696
http://www.purebasic.fr/french/viewtopic.php?f=6&t=9776
(Sorry, it's all in french; translation may come later if I've got time)

Wonderful piece of code he gave us here; very useful and flexible.

Re: Scrolling and parallax

Posted: Tue Sep 29, 2009 7:11 pm
by Rook Zimbabwe
Olli,
Did you write a TSP file for Tile Studio to output the code? I have tried top modify the include but don't yet know every location for TS!

Re: Scrolling and parallax

Posted: Tue Sep 29, 2009 8:50 pm
by Olliv
Kelebrindae did it here and here. These two files must be downloaded in the internal directory of TS, directory named TSP. Did you already do it?

Ollivier

Re: Scrolling and parallax

Posted: Tue Sep 29, 2009 10:31 pm
by Rook Zimbabwe
will try...

I was thinking about the TSD files though

Re: Scrolling and parallax

Posted: Wed Sep 30, 2009 12:29 pm
by Kelebrindae
@Rook:

Then it's here:
http://keleb.free.fr/codecorner/downloa ... eBasic.tsd 8)

The complete thread is here:
http://www.purebasic.fr/french/viewtopic.php?f=6&t=9776

There, you'll find some explanations about the choices I've made in the code generation.
Alas, my friend, it's written in the chaotic-evil aberration of nature the French call their "language".
Try Google Translate: the result is almost not completly ludicrous.

And if you've got some problems, I'll be glad to translate a thing or two... :wink:

Re: Scrolling and parallax

Posted: Wed Sep 30, 2009 8:14 pm
by Rook Zimbabwe
VERY COOL! 8) You have made the use of Tile Studio MUCH EASIER!!!

Re: Scrolling and parallax

Posted: Thu Oct 01, 2009 6:50 pm
by Olliv
(Thanks to Kelebrindae)

@Rook Zimbabwe

In this way, you can use a french expression to show your happiness : "to have the gourdin".

Ollivier

Re: Scrolling and parallax

Posted: Thu Oct 01, 2009 8:28 pm
by Rook Zimbabwe
:mrgreen: