Bon, c'est mon tour de faire subir les derniers outrages au code d'Ollivier.
Sur le principe de base, je n'ai rien changé. J'ai juste modifié un petit truc qui me gênait, à savoir: pour chaque plan de scrolling, il fallait copier/coller toutes les macros; ça marchait bien, c'était super-rapide, mais à lire et à maintenir, je trouvais ça un peu lourd.
=> dans ma version, il y a une seule "instance" des macros, quel que soit le nombre de layers.
Ces derniers sont stockés dans une liste structurée, ce qui permet d'en ajouter facilement avec un addElement. Le premier de la liste (n°0) est opaque et constitue le fond, les suivants sont transparents et sont affichés par ordre de création.
Cela fait probablement perdre un peu de temps à l'exécution, mais pas trop, je pense (PB est rapide sur les listes).
Ah, pis j'ai aussi ajouté la possibilité d'avoir des tiles rectangulaires et de tailles différentes d'un layer sur l'autre.
Dernière chose: il y a une constante #USESPRITE3D au début, pour utiliser ou non les sprites 3D (ça ne concerne que les 4 grands sprites "pages" de chaque layers). Sur mon PC de test, c'est plutôt plus lent, mais c'est un GPU bureautique alors c'est sans doute normal.
Code : Tout sélectionner
EnableExplicit
#USESPRITE3D = #False
#MAXLAYERS = 3 ; modifiez cette valeur si vous voulez avoir plus de layers
#MAXLEVELSIZEX = 255 ; modifiez cette valeur et celle du dessous
#MAXLEVELSIZEY = 255 ; si vous voulez avoir des niveaux plus grands
;- **** Code générique Scrolling ****
; (tout ce code pourrait être sorti dans un include)
; Structure utilisée par les layers (= "plans de scrolling")
Structure layer_struct
numlayer.i ; ordre: le layer 0 est le fond (non transparent), les suivants viennent par dessus
; Taille des tiles
tileSizeX.i ; largeur en pixels
tileSizeY.i ; hauteur en pixels
; N° des 4 sprites de la taille de l'écran (= pages) nécessaires au scrolling
page0.i
page1.i
page2.i
page3.i
firstPage.i ; n° de la première de ces pages (utilisé dans updateTile)
; Dimensions d'une page
PageW.i ; largeur en pixels
PageH.i ; hauteur en pixels
PageTileW.i ; largeur en Tiles
PageTileH.i ; hauteur en Tiles
; Dimensions du niveau
LevelW.i ; largeur en pixels
LevelH.i ; hauteur en pixels
LevelTileW.i ; largeur en Tiles
LevelTileH.i ; hauteur en Tiles
LevelTileMaxX.i ; Limites du niveau en Tiles
LevelTileMaxY.i ;
PosX.i ; Décalage dans une page
PosY.i ; en pixels
ShiftX.i ; Décalage page par page
ShiftY.i ; en pixels
LevelX.i ; Décalage total (page + position)
LevelY.i ; en pixels
LevelTileX.i ; Décalage total (page + position)
LevelTileY.i ; en Tiles
OldLevelTileX.i ; Dans la détection des mises à jour
OldLevelTileY.i ; Ancien décalage total en Tiles
; Vitesse de déplacement du layer
vitRatio.f ; ratio par rapport au layer du premier-plan (ex: 2 => le layer se déplace 2x moins vite)
VitX.i ; vitesse horizontale
VitY.i ; vitesse horizontale
EndStructure
; Variables globales utilisées par les macro de scrolling
Global P.i
Global X.i
Global Y.i
Global Tile.i
Global TempX.i
Global TempY.i
Global DisplayFlag.b
; Liste des layers
Global NewList tileLayer.layer_struct()
; Voici LE truc qui m'embête: ce tableau aurait logiquement dû être dans la structure ci-dessus,
; et changer de taille pour chaque layer (en fonction des dimensions du layer et des tiles de ce layer).
; Ce serait possible en utilisant juste une zone mémoire plutôt qu'un tableau, mais ça demande un ou deux
; calculs de plus et c'est moins facile à lire...
Global Dim tile.i(#MAXLAYERS-1,#MAXLEVELSIZEX,#MAXLEVELSIZEY)
; Cette procédure ajoute un layer de scrolling à la liste et en initialise les variables
; Note: c'est une procédure plutôt qu'une macro, car ça n'a pas besoin d'être hyper-rapide
Procedure.i createLayer(dispW.i,dispH.i,TileW.i,TileH.i,speedRatio.f,LevelTileW.i,LevelTileH.i)
Protected numLayer.i
; Déterminer le n° du nouveau layer
If ListSize(tileLayer()) > 0
LastElement(tileLayer())
numLayer = tileLayer()\numlayer + 1
EndIf
; Ajout d'un layer dans la liste
AddElement(tileLayer())
tileLayer()\numlayer = numLayer
tileLayer()\TileSizeX = TileW
tileLayer()\TileSizeY = TileH
tileLayer()\vitRatio = speedRatio
tileLayer()\LevelTileW = LevelTileW
tileLayer()\LevelTileH = LevelTileH
; Calculs faits préalablement pour ne pas perdre de temps à les refaire en cours d'exécution
tileLayer()\LevelW = tileLayer()\LevelTileW * tileLayer()\TileSizeX
tileLayer()\LevelH = tileLayer()\LevelTileH * tileLayer()\TileSizeY
tileLayer()\LevelTileMaxX = tileLayer()\LevelTileW - 1
tileLayer()\LevelTileMaxY = tileLayer()\LevelTileH - 1
tileLayer()\PageW = DispW
tileLayer()\PageW - (tileLayer()\PageW % tileLayer()\TileSizeX)
If tileLayer()\PageW < DispW
tileLayer()\PageW + tileLayer()\TileSizeX
EndIf
tileLayer()\PageH = DispH
tileLayer()\PageH - (tileLayer()\PageH % tileLayer()\TileSizeY)
If tileLayer()\PageH < DispH
tileLayer()\PageH + tileLayer()\TileSizeY
EndIf
tileLayer()\PageTileW = tileLayer()\PageW / tileLayer()\TileSizeX
tileLayer()\PageTileH = tileLayer()\PageH / tileLayer()\TileSizeY
ProcedureReturn tileLayer()\numlayer
EndProcedure
; Cette procédure initialise les 4 pages nécessaires à chaque layer de scroll
; Note: c'est une procédure plutôt qu'une macro, car ça n'a pas besoin d'être hyper-rapide
Procedure initScrollPages()
Protected i.i,numpage.i = 0
; Pour chaque layer, créer 4 pages pour le scrolling
ForEach tilelayer()
tilelayer()\firstpage = numpage
tilelayer()\page0 = numpage
tilelayer()\page1 = numpage+1
tilelayer()\page2 = numpage+2
tilelayer()\page3 = numpage+3
For i = 0 To 3
CompilerIf #USESPRITE3D = #True
CreateSprite(numpage, tilelayer()\PageW, tilelayer()\PageH, #PB_Sprite_Texture)
CreateSprite3D(numpage, numpage)
CompilerElse
CreateSprite(numpage, tilelayer()\PageW, tilelayer()\PageH)
CompilerEndIf
numpage+1
Next i
Next tilelayer()
EndProcedure
Macro GetPageNo(X, Y) ; Calcul de la page concernée
((X / tileLayer()\PageW) & 1) + (((Y / tileLayer()\PageH) & 1) << 1)
EndMacro
Macro GetXValue(X) ; Calcul de X dans la page
((X % tileLayer()\PageW) - (X % tileLayer()\TileSizeX) )
EndMacro
Macro GetYValue(Y) ; Calcul de Y dans la page
((Y % tileLayer()\PageH) - (Y % tileLayer()\TileSizeY) )
EndMacro
Macro GetTile(XX, YY)
Tile = -1
TempX = XX / tileLayer()\TileSizeX
If (TempX => 0)
If (TempX <= tileLayer()\LevelTileMaxX)
TempY = YY / tileLayer()\TileSizeY
If (TempY => 0)
If (TempY <= tileLayer()\LevelTileMaxY)
Tile = Tile(tileLayer()\numLayer, TempX, TempY)
EndIf
EndIf
EndIf
EndIf
EndMacro
Macro UpdateTile(XX, YY)
GetTile(XX, YY) ; Retourne le global Tile.i
If Tile <> -1
P = GetPageNo(XX, YY)
UseBuffer(P + tileLayer()\firstPage)
DisplaySprite(Tile, GetXValue(XX), GetYValue(YY) )
UseBuffer(-1)
EndIf
EndMacro
Macro UpdateTileLeftBorder()
For Y = (tileLayer()\LevelY - tileLayer()\TileSizeY) To (tileLayer()\LevelY + tileLayer()\PageH + tileLayer()\TileSizeY) ; Rajouté +TileSize
UpdateTile((tileLayer()\LevelX - tileLayer()\TileSizeY), Y)
Y + tileLayer()\TileSizeY
Y - 1
Next Y
EndMacro
Macro UpdateTileRightBorder()
For Y = (tileLayer()\LevelY - tileLayer()\TileSizeY) To (tileLayer()\LevelY + tileLayer()\PageH) ; Rajouté -TileSize
UpdateTile((tileLayer()\LevelX + tileLayer()\PageW), Y)
Y + tileLayer()\TileSizeY
Y - 1
Next Y
EndMacro
Macro UpdateTileUpBorder()
For X = (tileLayer()\LevelX - tileLayer()\TileSizeX) To (tileLayer()\LevelX + tileLayer()\PageW + tileLayer()\TileSizeX) ; Rajouté +TileSize
UpdateTile(X, (tileLayer()\LevelY - tileLayer()\TileSizeX) )
X + tileLayer()\TileSizeX
X - 1
Next X
EndMacro
Macro UpdateTileDownBorder()
For X = (tileLayer()\LevelX - tileLayer()\TileSizeX) To (tileLayer()\LevelX + tileLayer()\PageW) ;Rajouté -TileSize
UpdateTile(X, (tileLayer()\LevelY + tileLayer()\PageH) )
X + tileLayer()\TileSizeX
X - 1
Next X
EndMacro
Macro DrawVisibleTiles()
For Y = tileLayer()\LevelY To tileLayer()\LevelY + tileLayer()\PageH
For X = tileLayer()\LevelX To tileLayer()\LevelX + tileLayer()\PageW
UpdateTile(X, Y)
X + tileLayer()\TileSizeX
X - 1
Next X
Y + tileLayer()\TileSizeY
Y - 1
Next Y
EndMacro
Macro MoveLeft()
If tileLayer()\LevelX > 0
If tileLayer()\LevelX - tileLayer()\VitX < 0 ; "Sort" du niveau?
tileLayer()\VitX = tileLayer()\LevelX
EndIf
tileLayer()\PosX + tileLayer()\VitX
If tileLayer()\PosX => tileLayer()\PageW
tileLayer()\ShiftX + tileLayer()\PageW
tileLayer()\PosX - tileLayer()\PageW
tileLayer()\Page0 ! 1
tileLayer()\Page1 ! 1
tileLayer()\Page2 ! 1
tileLayer()\Page3 ! 1
EndIf
tileLayer()\LevelX = 0 - (tileLayer()\ShiftX + tileLayer()\PosX)
tileLayer()\OldLevelTileX = tileLayer()\LevelTileX
tileLayer()\LevelTileX = tileLayer()\LevelX / tileLayer()\TileSizeX
If tileLayer()\LevelTileX <> tileLayer()\OldLevelTileX
UpdateTileLeftBorder()
EndIf
DisplayFlag = #True
EndIf
EndMacro
Macro MoveRight()
If tileLayer()\LevelX < (tileLayer()\LevelW - tileLayer()\PageW)
If tileLayer()\LevelX + tileLayer()\VitX > (tileLayer()\LevelW - tileLayer()\PageW) ; "Sort" du niveau?
tileLayer()\VitX = (tileLayer()\LevelW - tileLayer()\PageW) - tileLayer()\LevelX
EndIf
tileLayer()\PosX - tileLayer()\VitX
If tileLayer()\PosX < 0
tileLayer()\ShiftX - tileLayer()\PageW
tileLayer()\PosX + tileLayer()\PageW
tileLayer()\Page0 ! 1
tileLayer()\Page1 ! 1
tileLayer()\Page2 ! 1
tileLayer()\Page3 ! 1
EndIf
tileLayer()\LevelX = 0 - (tileLayer()\ShiftX + tileLayer()\PosX)
tileLayer()\OldLevelTileX = tileLayer()\LevelTileX
tileLayer()\LevelTileX = tileLayer()\LevelX / tileLayer()\TileSizeX
If tileLayer()\LevelTileX <> tileLayer()\OldLevelTileX
UpdateTileRightBorder()
EndIf
DisplayFlag = #True
EndIf
EndMacro
Macro MoveUp()
If tileLayer()\LevelY > 0
If tileLayer()\LevelY - tileLayer()\VitY < 0 ; "Sort" du niveau?
tileLayer()\VitY = tileLayer()\LevelY
EndIf
tileLayer()\PosY + tileLayer()\VitY
If tileLayer()\PosY => tileLayer()\PageH
tileLayer()\ShiftY + tileLayer()\PageH
tileLayer()\PosY - tileLayer()\PageH
tileLayer()\Page0 ! 2
tileLayer()\Page1 ! 2
tileLayer()\Page2 ! 2
tileLayer()\Page3 ! 2
EndIf
tileLayer()\LevelY = 0 - (tileLayer()\ShiftY + tileLayer()\PosY)
tileLayer()\OldLevelTileY = tileLayer()\LevelTileY
tileLayer()\LevelTileY = tileLayer()\LevelY / tileLayer()\TileSizeY
If tileLayer()\LevelTileY <> tileLayer()\OldLevelTileY
UpdateTileUpBorder()
EndIf
DisplayFlag = #True
EndIf
EndMacro
Macro MoveDown()
If tileLayer()\LevelY < (tileLayer()\LevelH - tileLayer()\PageH)
If tileLayer()\LevelY + tileLayer()\VitY > (tileLayer()\LevelH - tileLayer()\PageH) ; "Sort" du niveau?
tileLayer()\VitY = (tileLayer()\LevelH - tileLayer()\PageH) - tileLayer()\LevelY
EndIf
tileLayer()\PosY - tileLayer()\VitY
If tileLayer()\PosY < 0
tileLayer()\ShiftY - tileLayer()\PageH
tileLayer()\PosY + tileLayer()\PageH
tileLayer()\Page0 ! 2
tileLayer()\Page1 ! 2
tileLayer()\Page2 ! 2
tileLayer()\Page3 ! 2
EndIf
tileLayer()\LevelY = 0 - (tileLayer()\ShiftY + tileLayer()\PosY)
tileLayer()\OldLevelTileY = tileLayer()\LevelTileY
tileLayer()\LevelTileY = tileLayer()\LevelY / tileLayer()\TileSizeY
If tileLayer()\LevelTileY <> tileLayer()\OldLevelTileY
UpdateTileDownBorder()
EndIf
DisplayFlag = #True
EndIf
EndMacro
Macro Move(moveX,moveY)
ForEach tileLayer()
If moveX < 0
tileLayer()\VitX = -(moveX) / tileLayer()\vitRatio
MoveLeft()
Else
If moveX > 0
tileLayer()\VitX = (moveX) / tileLayer()\vitRatio
MoveRight()
EndIf
EndIf
If moveY < 0
tileLayer()\VitY = -(moveY) / tileLayer()\vitRatio
MoveUp()
Else
If moveY > 0
tileLayer()\VitY = (moveY) / tileLayer()\vitRatio
MoveDown()
EndIf
EndIf
Next tileLayer()
EndMacro
Macro Display()
CompilerIf #USESPRITE3D = #True
Start3D()
DisplaySprite3D(tileLayer()\Page0, tileLayer()\PosX, tileLayer()\PosY)
DisplaySprite3D(tileLayer()\Page1, tileLayer()\PosX - tileLayer()\PageW, tileLayer()\PosY)
DisplaySprite3D(tileLayer()\Page2, tileLayer()\PosX, tileLayer()\PosY - tileLayer()\PageH)
DisplaySprite3D(tileLayer()\Page3, tileLayer()\PosX - tileLayer()\PageW, tileLayer()\PosY - tileLayer()\PageH)
Stop3D()
CompilerElse
If tileLayer()\numlayer = 0
DisplaySprite(tileLayer()\Page0, tileLayer()\PosX, tileLayer()\PosY)
DisplaySprite(tileLayer()\Page1, tileLayer()\PosX - tileLayer()\PageW, tileLayer()\PosY)
DisplaySprite(tileLayer()\Page2, tileLayer()\PosX, tileLayer()\PosY - tileLayer()\PageH)
DisplaySprite(tileLayer()\Page3, tileLayer()\PosX - tileLayer()\PageW, tileLayer()\PosY - tileLayer()\PageH)
Else
DisplayTransparentSprite(tileLayer()\Page0, tileLayer()\PosX, tileLayer()\PosY)
DisplayTransparentSprite(tileLayer()\Page1, tileLayer()\PosX - tileLayer()\PageW, tileLayer()\PosY)
DisplayTransparentSprite(tileLayer()\Page2, tileLayer()\PosX, tileLayer()\PosY - tileLayer()\PageH)
DisplayTransparentSprite(tileLayer()\Page3, tileLayer()\PosX - tileLayer()\PageW, tileLayer()\PosY - tileLayer()\PageH)
EndIf
CompilerEndIf
EndMacro
;- **** Fin du code générique ****
;-
#DECO=1000
; Création de sprites pour l'exemple
Procedure spriteDrawing()
; sprites de l'arrière-plan
FirstElement(tileLayer())
CreateSprite(#DECO, tileLayer()\TileSizeX, tileLayer()\TileSizeY)
StartDrawing( SpriteOutput(#DECO) )
Box(0, 0, tileLayer()\TileSizeX, tileLayer()\TileSizeY, RGB(1,1,1))
StopDrawing()
CreateSprite(#DECO+1, tileLayer()\TileSizeX, tileLayer()\TileSizeY)
StartDrawing( SpriteOutput(#DECO+1) )
Box(0, 0, tileLayer()\TileSizeX, tileLayer()\TileSizeY, RGB(127,0,0))
StopDrawing()
CreateSprite(#DECO+2, tileLayer()\TileSizeX, tileLayer()\TileSizeY)
StartDrawing( SpriteOutput(#DECO+2) )
Box(0, 0, tileLayer()\TileSizeX, tileLayer()\TileSizeY, RGB(0,127,0))
StopDrawing()
CreateSprite(#DECO+3, tileLayer()\TileSizeX, tileLayer()\TileSizeY)
StartDrawing( SpriteOutput(#DECO+3) )
Box(0, 0, tileLayer()\TileSizeX, tileLayer()\TileSizeY, RGB(0,0,127))
StopDrawing()
; sprites du layer 1
NextElement(tileLayer())
CreateSprite(#DECO+10, tileLayer()\TileSizeX, tileLayer()\TileSizeY)
StartDrawing( SpriteOutput(#DECO+10) )
Box(0, 0, tileLayer()\TileSizeX, tileLayer()\TileSizeY, RGB(0,0,0))
StopDrawing()
CreateSprite(#DECO+11, tileLayer()\TileSizeX, tileLayer()\TileSizeY)
StartDrawing( SpriteOutput(#DECO+11) )
Circle(tileLayer()\TileSizeX/2,tileLayer()\TileSizeY/2,tileLayer()\TileSizeX/2,$777777)
Circle(tileLayer()\TileSizeX/2-1,tileLayer()\TileSizeY/2-1,tileLayer()\TileSizeX/2-2,$AAAAAA)
Circle(tileLayer()\TileSizeX/2-3,tileLayer()\TileSizeY/2-3,tileLayer()\TileSizeX/2-6,$BBBBBB)
Circle(tileLayer()\TileSizeX/2-6,tileLayer()\TileSizeY/2-6,tileLayer()\TileSizeX/2-12,$CCCCCC)
StopDrawing()
; sprites du premier plan
NextElement(tileLayer())
CreateSprite(#DECO+4, tileLayer()\TileSizeX, tileLayer()\TileSizeY)
StartDrawing( SpriteOutput(#DECO+4) )
Box(0, 0, tileLayer()\TileSizeX, tileLayer()\TileSizeY, RGB(0,0,0))
StopDrawing()
CreateSprite(#DECO+5, tileLayer()\TileSizeX, tileLayer()\TileSizeY)
StartDrawing( SpriteOutput(#DECO+5) )
Box(0, 0, tileLayer()\TileSizeX, tileLayer()\TileSizeY, RGB(255,0,0))
StopDrawing()
CreateSprite(#DECO+6, tileLayer()\TileSizeX, TileLayer()\TileSizeY)
StartDrawing( SpriteOutput(#DECO+6) )
Box(0, 0, tileLayer()\TileSizeX, tileLayer()\TileSizeY, RGB(0,255,0))
StopDrawing()
CreateSprite(#DECO+7, tileLayer()\TileSizeX, tileLayer()\TileSizeY)
StartDrawing( SpriteOutput(#DECO+7) )
Box(0, 0, tileLayer()\TileSizeX, tileLayer()\TileSizeY, RGB(255,255,0))
StopDrawing()
CreateSprite(#DECO+8, tileLayer()\TileSizeX, TileLayer()\TileSizeY)
StartDrawing( SpriteOutput(#DECO+8) )
Box(0, 0, tileLayer()\TileSizeX, tileLayer()\TileSizeY, RGB(0,0,255))
StopDrawing()
EndProcedure
; Création d'un niveau "en dur" (sans Data) pour l'exemple
Procedure levelLoading()
Protected x.i,y.i
Protected EmptySprite.i, nbSprites.i
; Layer d'arrière-plan
FirstElement(tileLayer())
EmptySprite = #DECO ; <= sprite "couleur de fond" pour ce layer
nbSprites = 3 ; <= Nb de sprites (autre que le "vide") pour ce layer
; Vider le layer
For Y = 0 To tileLayer()\LevelTileMaxY
For X = 0 To tileLayer()\LevelTileMaxX
Tile(tileLayer()\numLayer, X,Y) = EmptySprite
Next X
Next Y
; Pour le test, mettre des briques au hasard à l'intérieur
For Y = 0 To tileLayer()\LevelTileMaxY
For X = 0 To tileLayer()\LevelTileMaxX
If Random(9) = 0
Tile(tileLayer()\numLayer, X,Y) = EmptySprite+1 + Random(nbSprites-1)
EndIf
Next X
Next Y
; Layer suivant
NextElement(tileLayer())
For Y = 0 To tileLayer()\LevelTileMaxY
For X = 0 To tileLayer()\LevelTileMaxX
Tile(tileLayer()\numLayer, X,Y) = #DECO+10
Next X
Next Y
For Y = 0 To tileLayer()\LevelTileMaxY
For X = 0 To tileLayer()\LevelTileMaxX
If Random(19) = 0
Tile(tileLayer()\numLayer, X,Y) = #DECO+11
EndIf
Next X
Next Y
; Layer du premier-plan
NextElement(tileLayer())
EmptySprite = #DECO+4 ; <= sprite "couleur de fond" pour ce layer
nbSprites = 4 ; <= Nb de sprites (autre que le "vide") pour ce layer
; Vider le layer
For Y = 0 To tileLayer()\LevelTileMaxY
For X = 0 To tileLayer()\LevelTileMaxX
Tile(tileLayer()\numLayer, X,Y) = EmptySprite
Next X
Next Y
; Pour le test, dessiner les bords du niveau et mettre des briques au hasard à l'intérieur
For Y = 0 To tileLayer()\LevelTileMaxY
Tile(tileLayer()\numLayer, 0, Y) = EmptySprite+1
Tile(tileLayer()\numLayer, tileLayer()\LevelTileMaxX, Y) = EmptySprite+1
For X = 0 To tileLayer()\LevelTileMaxX
Tile(tileLayer()\numLayer, X, 0) = EmptySprite+1
Tile(tileLayer()\numLayer, X, tileLayer()\LevelTileMaxY) = EmptySprite+1
If Random(19) = 0
Tile(tileLayer()\numLayer, X,Y) = EmptySprite+1 + Random(nbSprites-1)
EndIf
Next X
Next Y
EndProcedure
;-______________
;- Globals...
;-¯¯¯¯¯¯¯¯¯¯¯¯¯¯
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 maxSpeed.i = 24
Global VitesseX.i
Global VitesseY.i
Global QuitGame.i
Global num_frames.i,fps.i,lst_second.i
Delay(99)
;- Initialisation système
InitSprite()
InitKeyboard()
CompilerIf #USESPRITE3D = #True
InitSprite3D()
Sprite3DQuality(#PB_Sprite3D_NoFiltering)
CompilerEndIf
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
OpenScreen(ScrW, ScrH, ScrD, "")
;- Initialisation du scrolling, chargement des sprites et des niveaux
; Arrière-plan: gros blocs sombres
createLayer(dispW,dispH,48,32,2,80,128)
; Layer 1: boules
createLayer(dispW,dispH,64,64,1.5,72,72)
; Layer 2: petits carrés
createLayer(dispW,dispH,24,24,1,256,256)
; Création des pages de scroll (4 par layers)
initScrollPages()
; Pour le test, on dessine quelques sprites et niveaux
spriteDrawing()
levelLoading()
; Affichage initial du décor
ForEach tileLayer()
DrawVisibleTiles()
Display()
Next tileLayer()
FlipBuffers()
;-______________
;- Repeat...
;-¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Repeat
Delay(1)
DisplayFlag = 0
; Récupérer l'action de l'utilisateur
If ExamineKeyboard()
If KeyboardPushed(#PB_Key_Left)
If (VitesseX - 2) > -maxSpeed
VitesseX - 2
EndIf
EndIf
If KeyboardPushed(#PB_Key_Right)
If (VitesseX + 2) < maxSpeed
VitesseX + 2
EndIf
EndIf
If KeyboardPushed(#PB_Key_Up)
If (VitesseY - 2) > -maxSpeed
VitesseY - 2
EndIf
EndIf
If KeyboardPushed(#PB_Key_Down)
If (VitesseY + 2) < maxSpeed
VitesseY + 2
EndIf
EndIf
If KeyboardPushed(#PB_Key_Escape)
QuitGame = 1
EndIf
EndIf
; La vitesse décroît progressivement (comme si on avait de l'élan), sauf si on rencontre le bord du niveau
LastElement(tileLayer()) ; on teste le layer de premier plan: c'est lui qui conditionne le mouvement des autres
If VitesseX < 0
If tileLayer()\LevelX + VitesseX < 0
VitesseX = -tileLayer()\LevelX
Else
VitesseX+1
EndIf
EndIf
If VitesseX > 0
If tileLayer()\LevelX + VitesseX > (tileLayer()\LevelW - tileLayer()\PageW)
VitesseX = (tileLayer()\LevelW - tileLayer()\PageW) - tileLayer()\LevelX
Else
VitesseX-1
EndIf
EndIf
If VitesseY < 0
If tileLayer()\LevelY + VitesseY < 0
VitesseY = -tileLayer()\LevelY
Else
VitesseY+1
EndIf
EndIf
If VitesseY > 0
If tileLayer()\LevelY + VitesseY > (tileLayer()\LevelH - tileLayer()\PageH)
VitesseY = (tileLayer()\LevelH - tileLayer()\PageH) - tileLayer()\LevelY
Else
VitesseY-1
EndIf
EndIf
; Faire bouger le scrolling
Move(VitesseX,VitesseY)
; Si un déplacement a eu lieu, on réaffiche les pages
If DisplayFlag
ForEach tileLayer()
Display()
Next tileLayer()
; Ce petit bout de code mesure et affiche les FPS
num_frames+1
If ElapsedMilliseconds()-lst_second>=1000
fps=num_frames
num_frames=0
lst_second=ElapsedMilliseconds()
EndIf
StartDrawing(ScreenOutput())
DrawText(5,5,Str(fps))
StopDrawing()
; Inverse les buffers
FlipBuffers(#PB_Screen_NoSynchronization) ; pas de synchro, sinon les FPS sont au maximum égaux à la fréquence de rafraîchissement du moniteur
Else
lst_second=ElapsedMilliseconds()
num_frames=0
EndIf
Until QuitGame
CloseScreen()
End