[2D] Sprite Scrolling

Programmation avancée de jeux en PureBasic
Avatar de l’utilisateur
Cool Dji
Messages : 1126
Inscription : ven. 05/sept./2008 11:42
Localisation : Besançon
Contact :

Re: Sprite Scrolling

Message par Cool Dji »

Salut les amis,

Faire de la 2D avec les fonctions 3D offrent réellement des possibilités incroyables.
G-Rom avait pondu un exemple (petit jeu pour un punch, peut-être) qui m'avais inspiré pour coder un clone de Prezi (power-point en ligne) et ça rendait vraiment bien.

On peut, je pense, compenser la perte des spritepixelcollision en gérant virtuellement (sans les afficher les sprites).
Tu construits un Entity avec l'image du sprite (en png) et tu geres les collisions car tu construits aussi un sprite avec la meme image qui te permets de gérer facilement les collisions...
On peut meme imaginer que les entitys soient décalées dans les z afin d'éviter les bugs d'affichage sans que cela affecte les sprites...

Désolé, je n'ai pas de codes pour montrer l'exemple et je pars en vacances à la fin de la semaine et n'aurai pas le temps d'ici là...

A++
Only PureBasic makes it possible
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Sprite Scrolling

Message par falsam »

Cool Dji a écrit :On peut, je pense, compenser la perte des spritepixelcollision en gérant virtuellement (sans les afficher les sprites).
Pourquoi simple quand on peut faire compliqué hein ? :wink:
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Sprite Scrolling

Message par djes »

Le code d'Ar-S ne me semble pas mal ! Le principe pour un scroll en continu "hyper fluide" est d'avoir deux (ou plus) écrans en largeur (si scroll horizontal) et deux (ou plus) écrans en hauteur (si scroll vertical). On va travailler dans les parties non affichées pour mettre à jour le décor qui arrive. En théorie ça aurait pu se faire avec un clipsprite() (d'ailleurs ça se faisait dans le temps), voire avec plusieurs sprites (mais ça c'est plus possible).
Pour quelque chose d'un peu moins fluide et moins coûteux en mémoire, on peut travailler avec les tuiles (c'est à dire des portions d'images carrées, par exemple dans Sonic on construisait le décor avec des tuiles de 32 pixels x 32 pixels), mais cela implique de grosses opérations de copie à chaque VBL -euh! pardon- à chaque rafraîchissement/changement de buffer.
Cela peut se faire avec un écran de large + la largeur d'une tuile [+ hauteur d'une tuile si scroll vertical), et alors on fait une copie de l'écran entier "décalé" à partir d'une copie mémoire ; ou alors en reconstruisant le décor entièrement de façon décalée (méthode la moins coûteuse en mémoire) puisqu'elle ne nécessite aucun buffer supplémentaire.
comtois
Messages : 5172
Inscription : mer. 21/janv./2004 17:48
Contact :

Re: Sprite Scrolling

Message par comtois »

Cool Dji a écrit :Salut les amis,

Faire de la 2D avec les fonctions 3D offrent réellement des possibilités incroyables.
G-Rom avait pondu un exemple (petit jeu pour un punch, peut-être) qui m'avais inspiré pour coder un clone de Prezi (power-point en ligne) et ça rendait vraiment bien.
Tu fais sans doute référence à cette excellente démo ?
http://www.purebasic.fr/french/viewtopi ... 6&p=177412

C'était pour compléter cet exemple que j'ai ajouté la commande MaterialAnimation() (voir l'exemple MaterialAnimation.pb). Je n'ai pas trouvé de bons sprites pour l'instant.

Note : Apparemment il y a un bug dans la version 5.50 pour la commande CreateTexture() , il faut forcer le dernier paramètre avec une chaine vide, exemple :

Code : Tout sélectionner

CreateTexture(#PB_Any,64,64,"")
Avec la lib 3D, il est possible d'utiliser le moteur physique pour faire pas mal de trucs, et aussi les particules, etc, voir les compositors.
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Avatar de l’utilisateur
venom
Messages : 3072
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: Sprite Scrolling

Message par venom »

djes a écrit :Le code d'Ar-S ne me semble pas mal ! Le principe pour un scroll en continu "hyper fluide" est d'avoir deux (ou plus) écrans en largeur (si scroll horizontal) et deux (ou plus) écrans en hauteur (si scroll vertical).
Personnellement, j'aurais réagis de la sorte si j'aurais eu besoin de faire ce type de scroll. :wink:






@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Avatar de l’utilisateur
TazNormand
Messages : 1294
Inscription : ven. 27/oct./2006 12:19
Localisation : Calvados (14)

Re: Sprite Scrolling

Message par TazNormand »

Salut,

Je vais peut-être dire une connerie, n'y connaissant rien à la 3D, mais est-ce possible d'appliquer une texture sur un cylindre beaucoup plus large que la largeur de l'écran et de faire "tourner" ce cylindre sur l'axe Y (donc rotation de droite à gauche ou inversement) ?
Image
Image
Avatar de l’utilisateur
Ar-S
Messages : 9476
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: [2D] Sprite Scrolling

Message par Ar-S »

Logiquement oui. Il me semble aussi qu'on doit pouvoir faire défiler une texture sur un simple plan (carré plat). Du moins dans les softs de 3D on le peut. En PB je ne suis pas assez calé en 3D pour répondre.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
comtois
Messages : 5172
Inscription : mer. 21/janv./2004 17:48
Contact :

Re: [2D] Sprite Scrolling

Message par comtois »

Je n'ai pas tout lu, donc désolé si c'est hors sujet ou déjà dit, voici un exemple de scrolling utilisant le ClipSprite()

Touches Joueur 1
Camera\Touche\Bas = #PB_Key_Down
Camera\Touche\Haut = #PB_Key_Up
Camera\Touche\Droite = #PB_Key_Right
Camera\Touche\Gauche = #PB_Key_Left

Touches Joueur 2
Camera2\Touche\Bas = #PB_Key_S
Camera2\Touche\Haut = #PB_Key_Z
Camera2\Touche\Droite = #PB_Key_D
Camera2\Touche\Gauche = #PB_Key_Q

La même map utilisée par 2 joueurs

Code : Tout sélectionner

; Comtois
; PB 4.51
 
InitSprite()
InitKeyboard()
OpenScreen(1024,768,32,"Map")
 
KeyboardMode(#PB_Keyboard_International)
Enumeration
  #Herbe
  #Eau
  #Fleur
  #Arbre
  #Bord
EndEnumeration
 
Structure s_Point
  x.i
  y.i
EndStructure
 
Structure s_Screen
  Width.i
  Height.i
EndStructure
Structure S_Box
  x.i
  y.i
  Width.i
  Height.i
EndStructure
 
Structure s_Commande
  Haut.i
  Bas.i
  Gauche.i
  Droite.i
EndStructure
 
Structure s_Camera
  Position.s_Point
  Destination.s_Point
  Speed.i
  Screen.s_Screen ; Dimension de l'écran
  ViewPort.s_Box
  Touche.s_Commande
EndStructure
 
#TailleTitleCarteX=440
#TailleTitleCarteY=440
#TailleTitle=32
 
Declare DessineSprite(Sprite, Couleur)
Declare RandomMap()
Declare CameraEvent(*Camera.s_Camera)
Declare AfficheMap(*Camera.s_Camera)
Declare AfficheBox(*Camera.s_Camera)
 
 
Camera.s_Camera
Camera\Speed = 3
Camera\Position\x = 0
Camera\Position\y = 0
Camera\ViewPort\x = 40
Camera\ViewPort\y = 40
Camera\ViewPort\Width = 300
Camera\ViewPort\Height = 150
Camera\Touche\Bas    = #PB_Key_Down
Camera\Touche\Haut   = #PB_Key_Up
Camera\Touche\Droite = #PB_Key_Right
Camera\Touche\Gauche = #PB_Key_Left
 
Camera2.s_Camera
Camera2\Speed = 3
Camera2\Position\x = 0
Camera2\Position\y = 0
Camera2\ViewPort\x = 40
Camera2\ViewPort\y = 240
Camera2\ViewPort\Width = 300
Camera2\ViewPort\Height = 150
Camera2\Touche\Bas    = #PB_Key_S
Camera2\Touche\Haut   = #PB_Key_Z
Camera2\Touche\Droite = #PB_Key_D
Camera2\Touche\Gauche = #PB_Key_Q
 
DessineSprite(#Bord, $0000FF)
DessineSprite(#Herbe, $00FF00)
DessineSprite(#Eau, $FF0000)
DessineSprite(#Fleur, $00FFFF)
DessineSprite(#Arbre, $000088)
 
Global Dim Map(#TailleTitleCarteX,#TailleTitleCarteY)
RandomMap()
 
Repeat
  ClearScreen(0)
  CameraEvent(@Camera)
  AfficheMap(@Camera)
  AfficheBox(@Camera)
  CameraEvent(@Camera2)
  AfficheMap(@Camera2)
  AfficheBox(@Camera2)
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
 
Procedure DessineSprite(Sprite, Couleur)
  CreateSprite(Sprite,#TailleTitle,#TailleTitle)
  If StartDrawing(SpriteOutput(Sprite))
    Box(0,0,SpriteWidth(Sprite),SpriteHeight(Sprite),Couleur)
    StopDrawing()
    ProcedureReturn #True
  EndIf
EndProcedure
 
Procedure RandomMap()
  For y=0 To #TailleTitleCarteY
    For x=0 To #TailleTitleCarteX
      If x=0 Or x=#TailleTitleCarteX Or y=0 Or y=#TailleTitleCarteY Or x=#TailleTitleCarteX/2 Or y=#TailleTitleCarteY/2
        Map(x,y)=#Bord
      Else
        Map(x,y)=Random(#Arbre)
      EndIf   
    Next x
  Next y   
EndProcedure
 
Procedure AfficheBox(*Camera.s_Camera)
  StartDrawing(ScreenOutput())
    DrawingMode(#PB_2DDrawing_Outlined)
    Box(*Camera\ViewPort\x, *Camera\ViewPort\y, *Camera\ViewPort\Width, *Camera\ViewPort\Height,$FFFFFF)
  StopDrawing()
EndProcedure
 
Procedure CameraEvent(*Camera.s_Camera)
 
  If ExamineKeyboard()
 
    If KeyboardPushed(*Camera\Touche\Droite)
      Key_Right = #True
    EndIf
    If KeyboardReleased(*Camera\Touche\Droite)
      Key_Right = #False
    EndIf     
    If KeyboardPushed(*Camera\Touche\Gauche)
      Key_Left = #True
    EndIf
    If KeyboardReleased(*Camera\Touche\Gauche)
      Key_Left = #False
    EndIf     
    If KeyboardPushed(*Camera\Touche\Haut)
      Key_Up = #True
    EndIf
    If KeyboardReleased(*Camera\Touche\Haut)
      Key_Up = #False
    EndIf
    If KeyboardPushed(*Camera\Touche\Bas)
      Key_Down = #True
    EndIf
    If KeyboardReleased(*Camera\Touche\Bas)
      Key_down = #False
    EndIf         
  EndIf
    If Key_Right And *Camera\Position\x < (#TailleTitleCarteX + 1) * #TailleTitle - *Camera\ViewPort\Width
      *Camera\Position\x + *Camera\Speed
    ElseIf Key_Left And *Camera\Position\x > 0
      *Camera\Position\x - *Camera\Speed
    EndIf
    If Key_Down And *Camera\Position\y < (#TailleTitleCarteY + 1) * #TailleTitle - *Camera\ViewPort\Height
      *Camera\Position\y + *Camera\Speed
    ElseIf Key_Up And *Camera\Position\y > 0
      *Camera\Position\y - *Camera\Speed
    EndIf
 
EndProcedure
 
Procedure AfficheMap(*Camera.s_Camera)
  Define.i Tx, Ty  ; Index sur le tableau DataMap pour récupérer le numéro du Tile à afficher
  Define.i Rx, Ry  ; Position sur le Tile à afficher (entre 0 et la largeur ou hauteur du Tile à afficher)
  Define.i Px, Py  ; Position à l'écran du Tile à afficher
  Define.S_Box Src ; Portion de l'image à récupérer sur le Chipset (Tile à afficher)
 
  Tx         = *Camera\Position\x / #TailleTitle
  Ty         = *Camera\Position\y / #TailleTitle
  Ry         = *Camera\Position\y % #TailleTitle
  Src\y      = Ry
  Src\Height = #TailleTitle - Ry
  Py         = *Camera\ViewPort\y
 
 
  While Py < *Camera\ViewPort\y + *Camera\ViewPort\Height
    Px        = *Camera\ViewPort\x   
    Rx        = *Camera\Position\x % #TailleTitle
    Tx        = *Camera\Position\x / #TailleTitle   
    Src\x     = Rx
    Src\Width = #TailleTitle - Rx
 
    While Px < *Camera\ViewPort\x + *Camera\ViewPort\Width
      ClipSprite(Map(Tx,Ty), Src\x, Src\y, Src\Width, Src\Height)
      DisplaySprite(Map(Tx,Ty), Px, Py)
 
      ;On se place après le Tile qui vient d'être affiché     
      Px + Src\Width
      ;On calcule le prochain Tile à afficher
      Tx + 1
      ;
      Src\x = 0
      ;Tant que l'on n'atteint pas l'extrémité de la carte, le Tile sera complet
      Src\Width = #TailleTitle
      ;sinon il faut calculer sa largeur
      If (Px + Src\Width) > (*Camera\ViewPort\x + *Camera\ViewPort\Width)
        Src\Width = *Camera\ViewPort\x + *Camera\ViewPort\Width - Px
      EndIf
 
    Wend
    ;On se place après le Tile qui vient d'être affiché
    Py + Src\Height
    ;On calcule le prochain Tile à afficher (index sur le tableau
    Ty + 1
    ;
    Src\y      = 0
    ;Tant que l'on n'atteint pas l'extrémité de la carte, le Tile sera complet
    Src\Height = #TailleTitle
    ;sinon il faut calculer sa hauteur
    If Py + Src\Height > *Camera\ViewPort\y + *Camera\ViewPort\Height
      Src\Height = *Camera\ViewPort\y + *Camera\ViewPort\Height - Py
    EndIf
  Wend 
 
EndProcedure
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Avatar de l’utilisateur
Cool Dji
Messages : 1126
Inscription : ven. 05/sept./2008 11:42
Localisation : Besançon
Contact :

Re: [2D] Sprite Scrolling

Message par Cool Dji »

Hello,

Oui, Comtois, je parlais bien de l'exemple que tu as mis...

ci-dessous le premier jet que j'avais réalisé, un espèce de power-point avec des fonctions 3D : on change de vue avec barre espace et on quitte avec esc...

http://www.jeuxvideobesancon.fr/Telecha ... reativ.zip

J'ai à la maison une version beaucoup plus sexy avec des vidéos dans les texture3D (sisi) et un scrolling à la générique StarWars.
Je posterai sur un nouveau post. là c'est pour montrer un ex de scrolling 2D en 3D...
Only PureBasic makes it possible
Avatar de l’utilisateur
Ar-S
Messages : 9476
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: [2D] Sprite Scrolling

Message par Ar-S »

Alléchant Cool Dji 8)
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Bernie
Messages : 282
Inscription : mar. 22/mars/2016 10:12
Localisation : En France

Re: [2D] Sprite Scrolling

Message par Bernie »

Cool Dji trop cool ton exemple
Répondre