Défilement 2D (Smooth Scrolling) avec ou sans parallaxe

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Défilement 2D (Smooth Scrolling) avec ou sans parallaxe

Message par Ollivier »

Bon, j'avais refilé ce code à Huitbit avec quelques restrictions qui n'ont plus lieu d'être.

Voici donc le code initial de défilement 2D suffisamment fluide pour s'amuser.

Mode emploi: appuyez sur les 4 touches de direction.

Tout est modifiable à volonté. S'il y a des difficultés à trouver où est-ce qu'on doit faire une modif pour voir autre chose que des briques dans le noir, n'hésitez pas à poser vos questions...

Donc, vous créez ou importez vos propres sprites (en français, on appelle ça un lutin). Pour le premier code, il n'y a qu'un seul tableau qui stocke tout le décor. Je crois qu'il s'appelle Tile(x,y) où vous mettez le n° du sprite et zoup la boucle principale ici présente digère le défilement sans broncher un yota. J'adore les codes souples donc beaucoup de paramètres sont modifiables mais je n'ai pas mis beaucoup de commentaires donc il faut y aller piano pour savoir à quoi correspond chaque variable. Je tiens à préciser que la quasi-totalité des variables sont des entiers donc attention aux réglages. J'ai, depuis fait un code avec flottants, c'est plus souple mais là le code est trop compliqué pour poster la machine à gaz.

Les paramètres principaux que je vous suggère de modifier sont la vitesse de défilement, la taille d'un tile (lutin, morceau carré ou sprite élémentaire dans le décor), la taille du décor lui-même. En ce qui concerne la taille du décor, vous pouvez y aller, ça supporte un bon décor bien immense: ça dépend de votre mémoire vive.

Il y a quatre macros à invoquer pour les quatre directions de défilement (MoveUp, MoveLeft, MoveDown et MoveRight). Elles peuvent être invoquées simultanément pour fusionner des mouvements circulaires ou diagonaux. Regardez juste la boucle principale pour comprendre leur fonctionnement. Pour "téléporter" (=passer d'un endroit du décor à un autre endroit), il doit y avoir une macro qui se charge de mettre à jour les quatre page d'affichage.

Bon, je vous fais l'explication à l'envers (comme d'hab) mais en gros, on ne voit jamais que quatre pages à l'écran qui sont modifiées en permanence en fonctions des mouvements demandés. Ce process permet un défilement toujours régulier qu'il y ait ou non un décor chargé. Pour le parallaxe double plan, il y a huit pages. ça commence alors à prendre pas de mémoire vidéo. Si on veut plus de plans en parallaxe
(3 plans, 4 plans ou plus...), on ne peut plus user de cette méthode: il faut alors afficher directement les tiles du décor à l'écran mais le rendu est moins fluide et régulier.

Pour le parallaxe (le deuxième code plus bas), il y a un second tableau pour stocker le décor: P2Tile(x,y). Exactement le même principe que le premier tableau sans distinction de sprite d'avant-plan et d'arrière plan.

A noter que pour le premier plan en parallaxe, la couleur rgb(0,0,0) (#Black) est transparente.

Bonne bourre!

Code : Tout sélectionner

EnableExplicit

Macro Display()
;   Message = ""
;   Message + ""
;   Message + Str(PageTileW) + " ; "
   

;   ClearScreen(0)
   ;UseBuffer(#DispMask)
      DisplaySprite(Page0, DispX1 + PosX, DispY1 + PosY)
      DisplaySprite(Page1, DispX1 + PosX - PageW, DispY1 + PosY)
      DisplaySprite(Page2, DispX1 + PosX, DispY1 + PosY - PageH)
      DisplaySprite(Page3, DispX1 + PosX - PageW, DispY1 + PosY - PageH)
   ;UseBuffer(-1)
;   DisplayTransparentSprite(#DispMask, DispX1, DispY1)
;   StartDrawing(ScreenOutput() )
;      DrawText(0, 0, Message)
;   StopDrawing()
   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(#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 3
      CreateSprite(I, PageW, PageH)
      UseBuffer(I)
         For Y = 0 To PageH - 1
            For X = 0 To PageW - 1
               DisplaySprite(#Deco + 1, X, Y)
               X + TileSize ; Remplace le step
               X - 1        ; Idem
            Next X
            Y + TileSize ; Remplace le Step
            Y - 1        ; Idem
         Next Y
         X = PageW - SpriteWidth(#Syst + I)
         Y = PageH - SpriteHeight(#Syst + I)
         DisplaySprite(#Syst + I, 0, 0)
         DisplaySprite(#Syst + I, X, 0)
         DisplaySprite(#Syst + I, 0, Y)
         DisplaySprite(#Syst + I, X, Y)
      UseBuffer(#PB_Default)
   Next I
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
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 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 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 UpdateTileLeftBorder()
   For Y = (LevelY - TileSize) To (LevelY + PageH + TileSize) ; Rajouté +TileSize
      UpdateTile((LevelX - TileSize), 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 UpdateTileUpBorder()
   For X = (LevelX - TileSize) To (LevelX + PageW + TileSize) ; Rajouté +TileSize
      UpdateTile(X, (LevelY - TileSize) )
      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 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 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
   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
            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
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
   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
;-Vitesse
Global Vit.I = 8

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

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

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

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

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

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

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

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

Global DisplayFlag.I

Global VitX.I
Global VitY.I

Global VitesseX.I
Global VitesseY.I

Global QuitGame.I

TileSize = 24

LevelTileW = 256
LevelTileH = 256

LevelW = LevelTileW * TileSize
LevelH = LevelTileH * TileSize

LevelTileMaxX = LevelTileW - 1
LevelTileMaxY = LevelTileH - 1

Global Dim Tile.I(LevelTileMaxX, LevelTileMaxY)
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()
   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
   
   
Dernière modification par Ollivier le sam. 11/juil./2009 1:42, modifié 4 fois.
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

J'en profite pour balancer un autre. ça fera ça en moins sur mon disque dur. C'est le vide-grenier en ce moment...

Même méthode en double plan (parallaxe).

Code : Tout sélectionner

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
   
   
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

tres sympa :) merci d'avoir partagé
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

Tu es prolixe en ce moment! Très beau code, très fluide! :)
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

@Djes

Prolixe? Est-ce le terme exact? :?

Ollivier
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Message par djes »

Non, excuse! Je voulais dire prolifique!
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

par contre si j'ai bien compris ton code exit les sprites 3D (a cause de l'utilisation de usebuffer), et c'est difficile d'avoir des animations du decors du a l'utilisation des pages non ?
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

Pour les animations, je ne pense pas que ça ralentit quoi que ce soit, au lieu de dessiner la même image à chaque flipbuffer, tu dessines une série d'images qui change à chaque flipbuffer.
Résultat : Même vitesse d'affichage.

Ensuite, pour la 3D, l'affichage d'un sprite3D va plus vite que l'affichage d'un sprite classique (du moins, c'est ce que j'ai observé)

Et pour le UseBuffer(), je pense que c'est la méthode d'affichage choisie et que l'on peut la changer.
Ce qui est intéressant et ce qui donne la fluidité du mouvement, c'est la prise en compte d'une accélération dans les déplacement.
Ca donne des mouvements très naturel. C'est vraiment bien trouvé :)
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
beauregard
Messages : 1307
Inscription : dim. 08/juil./2007 18:32
Localisation : Toulouse

Message par beauregard »

Thyphoon a écrit :par contre si j'ai bien compris ton code exit les sprites 3D (a cause de l'utilisation de usebuffer), et c'est difficile d'avoir des animations du decors du a l'utilisation des pages non ?
non, en fonction des valeurs x et y tu peux afficher des sprites3D sans problème. Mais pour un jeu en 2D, le plus dur à coder c'est le scrolling et l'editeur de niveau( dans forum jeu, j'ai mis un editeur de niveau, page 2).
config de mon ordi: seven, directx11, Pentium(R) DualCore E5700, RadeonHD 4550 512MB, PureBasic 4.61 x86
kelebrindae
Messages : 579
Inscription : ven. 11/mai/2007 15:21

Message par kelebrindae »

Magnifique!
Un beau scrolling comme ça, c'est une "brique" importante dans un jeu en 2D; ça va aider beaucoup de monde (à commencer par moi!).

Merci beaucoup ! :D
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

Vraiment terrible ton scrolling ollivier, chapeau 8)

Ce code est d'ailleurs tellement excellent que je n'ai pu m'empêcher de jouer un peu avec.

Et au risque de passer pour un bourrin voici une version
totalement vomitive qui se contrôle avec la souris, attention ca bouge... :lol:

Code : Tout sélectionner

EnableExplicit

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

Macro Display()
	
	ClearScreen(0)
	
	DisplayP2()
	DisplayTransparentSprite(Page0, PosX, PosY)
	DisplayTransparentSprite(Page1, PosX - PageW, PosY)
	DisplayTransparentSprite(Page2, PosX, PosY - PageH)
	DisplayTransparentSprite(Page3, PosX - PageW, PosY - PageH)
	
	StartDrawing(ScreenOutput())
	DrawingMode(#PB_2DDrawing_Transparent)
	DrawingFont(FontID(0))
	DrawText((ScrW-270)+Random(4), (ScrH-115)+Random(10), "Ollivier", $000000)
	DrawText((ScrW-270)+Random(4), (ScrH-105)+Random(10), "Ollivier", $FFFFFF)
	DrawText(50+Random(4), 60+Random(10), "2D Smooth Parallax Scrolling", $000000)
	DrawText(50+Random(4), 50+Random(10), "2D Smooth Parallax Scrolling", $FFFFFF)
	DrawingFont(FontID(1))
	DrawText(320+Random(4), 110+Random(10), "PureBasic 4.31", $000000)
	DrawText(320+Random(4), 100+Random(10), "PureBasic 4.31", $FFFFFF)
	StopDrawing()
	
	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) )
      For i = 0 To TileSize / 2 
      	Box(i, i, TileSize - i*2, TileSize - i*2, RGB((i*255)/(TileSize/2), 0, 0) )
      Next
   StopDrawing()

   CreateSprite(#Deco + 2, TileSize, TileSize)
   StartDrawing(SpriteOutput(#Deco + 2) )
      For i = 0 To TileSize / 2
      	Box(i, i, TileSize - i*2, TileSize - i*2, RGB(0, 0, (i*250)/(TileSize/2)) )
      Next
   StopDrawing()

   CreateSprite(#Deco + 3, TileSize, TileSize)
   StartDrawing(SpriteOutput(#Deco + 3) )
      For i = 0 To TileSize / 2
      	Box(i, i, TileSize - i*2, TileSize - i*2, RGB(0, 0, (i*100)/(TileSize/2)) )
      Next
   StopDrawing()

   CreateSprite(#Deco + 4, TileSize, TileSize)
   StartDrawing(SpriteOutput(#Deco + 4) )
      For i = 0 To TileSize / 2
      	Box(i, i, TileSize - i*2, TileSize - i*2, RGB(0, 0, (i*50)/(TileSize/2)) )
      Next
   StopDrawing()

   CreateSprite(#Deco + 5, TileSize, TileSize)
   StartDrawing(SpriteOutput(#Deco + 5) )
      For i = 0 To TileSize / 2
      	Box(i, i, TileSize - i*2, TileSize - i*2, RGB(0, (i*250)/(TileSize/2), 0) )
      Next
   StopDrawing()

   CreateSprite(#Deco + 6, TileSize, TileSize)
   StartDrawing(SpriteOutput(#Deco + 6) )
      For i = 0 To TileSize / 2
      	Box(i, i, TileSize - i*2, TileSize - i*2, RGB((i*255)/(TileSize/2), (i*255)/(TileSize/2), 0) )
      Next
   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
      For X = 0 To P2LevelTileMaxX 
         P2Tile(X, Y) = #Deco + 2 + Random(2)
      Next X
   Next Y
EndMacro

Macro LevelLoading()
   For Y = 0 To LevelTileMaxY
      For X = 0 To LevelTileMaxX 
         Select Random(5) 
         	Case 0:  Tile(X, Y) = #Deco + 5
         	Case 1:  Tile(X, Y) = #Deco + 6
         	Case 2:  Tile(X, Y) = #Deco + 1
            Default: Tile(X, Y) = #Deco
         EndSelect
      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 = 400

LevelTileW = 2560
LevelTileH = 2560

P2LevelTileW = 1920
P2LevelTileH = 1920

LevelW = LevelTileW * TileSize
LevelH = LevelTileH * TileSize

P2LevelW = P2LevelTileW * TileSize/2
P2LevelH = P2LevelTileH * TileSize/2

LevelTileMaxX = LevelTileW - 1
LevelTileMaxY = LevelTileH - 1

P2LevelTileMaxX = P2LevelTileW - 1
P2LevelTileMaxY = P2LevelTileH - 1

Define mxDelta, myDelta

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

   InitMouse()
   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, "")
   
   LoadFont(0, "Arial", 40, #PB_Font_Bold | #PB_Font_HighQuality)
   LoadFont(1, "Tahoma", 60, #PB_Font_Bold | #PB_Font_HighQuality)
   
   SpriteDrawing()
   LevelLoading()

   DrawVisibleTiles()
   P2DrawVisibleTiles()
   Display()
;-______________
;- Repeat...   
;-¯¯¯¯¯¯¯¯¯¯¯¯¯¯
	
   Repeat
      
      Delay(1)
      DisplayFlag = 0
     
      VitX = Vit
      VitY = Vit
      
      If ExamineMouse()
      	mxDelta = MouseDeltaX()
        If mxDelta < 0
	        If (VitesseX + mxDelta) > (0 - TileSize)
	      		VitesseX + mxDelta ; Mouse Left
	        EndIf
	    ElseIf mxDelta > 0
            If (VitesseX + mxDelta) < (TileSize)
               VitesseX + mxDelta ; Mouse Right
            EndIf
        EndIf
      	myDelta = MouseDeltaY()
        If myDelta < 0
	        If (VitesseY + myDelta) > (0 - TileSize)
	      		VitesseY + myDelta ; Mouse Up
	        EndIf
        ElseIf myDelta > 0
	        If (VitesseY + myDelta) < (TileSize)
	      		VitesseY + myDelta ; Mouse Down
	        EndIf
        EndIf
        If MouseButton(#PB_MouseButton_Left)
        	QuitGame = 1
        EndIf
      EndIf
      
      If ExamineKeyboard()
         If KeyboardPushed(#PB_Key_Left)
            If (VitesseX - 3) > (0 - TileSize)
               VitesseX - 3
            EndIf
         EndIf
         If KeyboardPushed(#PB_Key_Right)
            If (VitesseX + 3) < (TileSize)
               VitesseX + 3
            EndIf
         EndIf
         If KeyboardPushed(#PB_Key_Up)
            If (VitesseY - 3) > (0 - TileSize)
               VitesseY - 3
            EndIf
         EndIf
         If KeyboardPushed(#PB_Key_Down)
            If (VitesseY + 3) < (TileSize)
               VitesseY + 3
            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
      
      Display()
      
   Until QuitGame
   
   CloseScreen()
   
   End
   
   
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

@Flype

Ah oui c'est du bourrin... :D

Code : Tout sélectionner

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 Rect(X1, Y1, X2, Y2, C)
   Line(X1, Y1, X2, Y1, C)
   Line(X1, Y1, X1, Y2, C)
   Line(X2, Y1, X2, Y2, C)
   Line(X1, Y2, X2, Y2, C)
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) )
      For i = 0 To TileSize / 2
         Box(i, i, TileSize - i*2, TileSize - i*2, RGB((i*255)/(TileSize/2), 0, 0) )
      Next
      Rect(0, 0, TileSize, TileSize, RGB(1, 1, 1) )
   StopDrawing()

   CreateSprite(#Deco + 2, TileSize, TileSize)
   StartDrawing(SpriteOutput(#Deco + 2) )
      For i = 0 To TileSize / 2
         Box(i, i, TileSize - i*2, TileSize - i*2, RGB(0, 0, (i*250)/(TileSize/2)) )
      Next
      Rect(0, 0, TileSize, TileSize, RGB(1, 1, 1) )
   StopDrawing()

   CreateSprite(#Deco + 3, TileSize, TileSize)
   StartDrawing(SpriteOutput(#Deco + 3) )
      For i = 0 To TileSize / 2
         Box(i, i, TileSize - i*2, TileSize - i*2, RGB(0, 0, (i*100)/(TileSize/2)) )
      Next
      Rect(0, 0, TileSize, TileSize, RGB(1, 1, 1) )
   StopDrawing()

   CreateSprite(#Deco + 4, TileSize, TileSize)
   StartDrawing(SpriteOutput(#Deco + 4) )
      For i = 0 To TileSize / 2
         Box(i, i, TileSize - i*2, TileSize - i*2, RGB(0, 0, (i*50)/(TileSize/2)) )
      Next
      Rect(0, 0, TileSize, TileSize, RGB(1, 1, 1) )
   StopDrawing()

   CreateSprite(#Deco + 5, TileSize, TileSize)
   StartDrawing(SpriteOutput(#Deco + 5) )
      For i = 0 To TileSize / 2
         Box(i, i, TileSize - i*2, TileSize - i*2, RGB(0, (i*250)/(TileSize/2), 0) )
      Next
      Rect(0, 0, TileSize, TileSize, RGB(1, 1, 1) )
   StopDrawing()

   CreateSprite(#Deco + 6, TileSize, TileSize)
   StartDrawing(SpriteOutput(#Deco + 6) )
      For i = 0 To TileSize / 2
         Box(i, i, TileSize - i*2, TileSize - i*2, RGB((i*255)/(TileSize/2), (i*255)/(TileSize/2), 0) )
      Next
      Rect(0, 0, TileSize, TileSize, RGB(1, 1, 1) )
   StopDrawing()
   
   CreateSprite(#Deco + 10, TileSize, TileSize)
   StartDrawing(SpriteOutput(#Deco + 10) )
      For i = 0 To TileSize / 2
         Box(i, i, TileSize - i*2, TileSize - i*2, RGB((i*255)/(TileSize/2), (i*255)/(TileSize/2), (i*255)/(TileSize/2) ) )
      Next
      Rect(0, 0, TileSize, TileSize, RGB(1, 1, 1) )
   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
      For X = 0 To P2LevelTileMaxX
         P2Tile(X, Y) = #Deco + 2 + Random(2)
      Next X
   Next Y
   Define J.I
   CreateImage(100, 256, 16)
   StartDrawing(imageoutput(100) )
      DrawText(0, 0, "Flype System", #White, #Black)
      For Y = 0 To 15
         For X = 0 To 255
            I = Point(X, Y)
            If I
               For J = 0 To 192 Step 16
                  P2Tile(X, Y) = #Deco + 10
                  P2Tile(X + J, Y + J) = #Deco + 10
               Next J
            EndIf
         Next X
      Next Y
   StopDrawing()
EndMacro

Macro LevelLoading()
   For Y = 0 To LevelTileMaxY
      For X = 0 To LevelTileMaxX
         Tile(X, Y) = #Deco
         If ((((X % 40) + (Y % 20) ) - 10) & $7FFFFFFF) < 3
            Tile(X, Y) = #Deco + 6
         EndIf
         If (Y % 20) < 4
            Tile(X, Y) = #Deco + 1
         EndIf         
         If (X % 40) < 2
            Tile(X, Y) = #Deco + 5
         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 = 16

LevelTileW = 256
LevelTileH = 256

P2LevelTileW = 292
P2LevelTileH = 292

LevelW = LevelTileW * TileSize
LevelH = LevelTileH * TileSize

P2LevelW = P2LevelTileW * TileSize/2
P2LevelH = P2LevelTileH * TileSize/2

LevelTileMaxX = LevelTileW - 1
LevelTileMaxY = LevelTileH - 1

P2LevelTileMaxX = P2LevelTileW - 1
P2LevelTileMaxY = P2LevelTileH - 1

Define mxDelta, myDelta

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

   InitMouse()
   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, "")
   
   LoadFont(0, "Arial", 40, #PB_Font_Bold | #PB_Font_HighQuality)
   LoadFont(1, "Tahoma", 60, #PB_Font_Bold | #PB_Font_HighQuality)
   
   SpriteDrawing()
   LevelLoading()

   DrawVisibleTiles()
   P2DrawVisibleTiles()
   Display()
;-______________
;- Repeat...   
;-¯¯¯¯¯¯¯¯¯¯¯¯¯¯
   
   Repeat
     
      Delay(1)
      DisplayFlag = 0
     
      VitX = Vit
      VitY = Vit
     
      If ExamineMouse()
         mxDelta = MouseDeltaX()
        If mxDelta < 0
           If (VitesseX + mxDelta) > (0 - TileSize)
               VitesseX + mxDelta ; Mouse Left
           EndIf
       ElseIf mxDelta > 0
            If (VitesseX + mxDelta) < (TileSize)
               VitesseX + mxDelta ; Mouse Right
            EndIf
        EndIf
         myDelta = MouseDeltaY()
        If myDelta < 0
           If (VitesseY + myDelta) > (0 - TileSize)
               VitesseY + myDelta ; Mouse Up
           EndIf
        ElseIf myDelta > 0
           If (VitesseY + myDelta) < (TileSize)
               VitesseY + myDelta ; Mouse Down
           EndIf
        EndIf
        If MouseButton(#PB_MouseButton_Left)
           QuitGame = 1
        EndIf
      EndIf
     
      If ExamineKeyboard()
         If KeyboardPushed(#PB_Key_Left)
            If (VitesseX - 3) > (0 - TileSize)
               VitesseX - 3
            EndIf
         EndIf
         If KeyboardPushed(#PB_Key_Right)
            If (VitesseX + 3) < (TileSize)
               VitesseX + 3
            EndIf
         EndIf
         If KeyboardPushed(#PB_Key_Up)
            If (VitesseY - 3) > (0 - TileSize)
               VitesseY - 3
            EndIf
         EndIf
         If KeyboardPushed(#PB_Key_Down)
            If (VitesseY + 3) < (TileSize)
               VitesseY + 3
            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
     
      Display()
     
   Until QuitGame
   
   CloseScreen()
   
   End
   
   
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

Là où j'ai été "blessé" par ton code, c'est dans le fait d'avoir rajouté inutilement ClearScreen(0)! J'ai réenlevé la transparence des sprites d'arrière-plan. Je pense que tu ne vois pas le problème car tu dois posséder un bon matériel mais moi, qui possède un poste à galène, le ClearScreen() est gourmand en ressources, plus gourmand que l'affichage naturel des sprites qui tâchent de remplacer correctement la fonction de ClearScreen().

Pour les animations, cette méthode est "short". Elle permet de scroller correctement deux plans statiques, mais dès que l'on a des animations envahissantes, il vaut mieux se résoudre à un seul plan (1er code de sujet) et à rajouter une mosaïque d'icônes en avant-plan. Je testerai sur mon "poste à galène". Je pense franchement que toute personne qui veut faire un jeu en 2D type Mario ou Sonic en a la possibilité. Et que c'est un segment qui allie nostalgie et côté ludique.

Ollivier
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

Effectivement ma bécane suit parfaitement et cela reste super fluide mais je comprends, en plus je l'avais mis juste pour essayer...

NB:
Sympa le décors de fond...
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

Ta modif sème le doute chez moi. Je me demande si le problème de gourmandise en ressources de ClearScreen() n'est pas devenu une histoire ancienne sur la version 4.31...
Répondre