Page 3 sur 3

Re: Sprite Scrolling

Publié : mer. 27/juil./2016 11:29
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++

Re: Sprite Scrolling

Publié : mer. 27/juil./2016 12:28
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:

Re: Sprite Scrolling

Publié : mer. 27/juil./2016 19:05
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.

Re: Sprite Scrolling

Publié : mer. 27/juil./2016 20:56
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.

Re: Sprite Scrolling

Publié : mer. 27/juil./2016 21:25
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:






@++

Re: Sprite Scrolling

Publié : jeu. 28/juil./2016 8:37
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) ?

Re: [2D] Sprite Scrolling

Publié : jeu. 28/juil./2016 10:05
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.

Re: [2D] Sprite Scrolling

Publié : jeu. 28/juil./2016 12:03
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

Re: [2D] Sprite Scrolling

Publié : jeu. 28/juil./2016 12:35
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...

Re: [2D] Sprite Scrolling

Publié : jeu. 28/juil./2016 14:16
par Ar-S
Alléchant Cool Dji 8)

Re: [2D] Sprite Scrolling

Publié : ven. 29/juil./2016 6:44
par Bernie
Cool Dji trop cool ton exemple