Position sprite

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Ekim
Messages : 215
Inscription : dim. 24/juin/2018 1:20

Position sprite

Message par Ekim »

Bonsoirs à tous,
j'ai commencé très récemment à programmer en Pb, et je réclame votre aide sur un point précis,
j'aimerais savoir comment peut on retrouver les coordonnées XY d'un sprite sur une surface "OpenWindowedScreen" s'il vous plait?
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: Position sprite

Message par Fig »

Bienvenue, :D

Ton sprite n'est pas un objet, tu ne peux donc pas l'interroger sur sa position.
Il est affiché là où tu l'as mis par conséquent, tu connais déjà forcément sa position. C'est ta responsabilité de garder la trace de ses coordonées dans des variables.


Un exemple de code de l'aide [F1] simplifié pour que tu comprenne... Tu peux le modifier pour comprendre comment ça marche.

Code : Tout sélectionner

;
; ------------------------------------------------------------
;
;   PureBasic - Sprite example file
;
;    (c) Fantaisie Software
;
; ------------------------------------------------------------
;

If InitSprite() = 0 Or InitKeyboard() = 0
  MessageRequester("Error", "Sprite system can't be initialized", 0)
  End
EndIf
If OpenScreen(800, 600, 32, "Sprite") 
  LoadSprite(0, #PB_Compiler_Home + "examples/sources/Data/PureBasic.bmp")
  x=0:y=0
  Repeat
    FlipBuffers()   
    ClearScreen(RGB(0,0,0))
    DisplaySprite(0, x, y)
    x=x+1
    y=y+1
    ExamineKeyboard()
  Until KeyboardPushed(#PB_Key_Escape)
  
Else
  MessageRequester("Error", "Can't open a 800*600 - 32 bit screen !", 0)
EndIf

Ici, tes coordonnées sont dans les variables x et y par exemple...
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Ekim
Messages : 215
Inscription : dim. 24/juin/2018 1:20

Re: Position sprite

Message par Ekim »

Ok, donc si j'ai bien compris, il est préférable de transformer le sprite en objet en créant son profil pour facilité sa manipulation, n'est ce pas ?
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Position sprite

Message par Micoute »

Code : Tout sélectionner

;:=============================================================================
;:- MoteurSprite.pbi
;:- Author          : Eddy
;:- Date            : September 25, 2013
;:- Compiler        : PureBasic 5.20 LTS
;:- Target OS       : Mac, Linux, Windows
;:- Source --------------------------------------------------------------------
;:- http://www.purebasic.fr/english/Vuetopic.php?f=40&t=56507
;;- Traduit en français par Micoute
;:=============================================================================
EnableExplicit
Structure SP_DEFORMATION
  x.f[4]
  y.f[4]
EndStructure
Structure SP_FRAME
  u.f[4]
  v.f[4]
  Largeur.f
  Hauteur.f
  PointChaudX.f
  PointChaudY.f
EndStructure
Structure SP_ATLAS
  Atlas.i
  
  Texture.i
  Array Frames.SP_FRAME(0)
EndStructure
Structure SP_SPRITE
  Sprite.i
  
  *CoucheParent.SP_Couche
  x.f
  y.f
  EchelleX.f
  EchelleY.f
  Angle.f
  Etat.i
  Frame.i
  Couleurs.i[4]
  *Deformer.SP_DEFORMATION
EndStructure
Structure SP_Couche
  Couche.i
  StructureUnion
    CouchePivot.i
    CoucheRoll.i
    CoucheEchelle.i
  EndStructureUnion
  CoucheDecalage.i
  CouchePosition.i
  CoucheOmbre.i
  
  Mesh.i
  OmbreMesh.i
  Material.i
  OmbreMateriel.i
  MelangeMateriel.i
  FiltreMateriel.i
  *Atlas.SP_ATLAS
  
  Map *SpritesAttaches.SP_SPRITE()
  *VueParent.SP_Vue
  x.f
  y.f
  EchelleX.f
  EchelleY.f
  Etat.i
  CouleurOmbre.i
  DecalageOmbreX.f
  DecalageOmbreY.f
EndStructure
Structure SP_Vue
  Vue.i
  VuePivot.i
  DecalageVue.i
  StructureUnion
    VuePosition.i
    VueRoll.i
  EndStructureUnion
  Camera.i
  
  Map *AttachedCouches.SP_Couche()
  x.f
  y.f
  CameraX.i
  CameraY.i
  LargeurCamera.i
  CameraHauteur.i
  DecalageX.f
  DecalageY.f
  EchelleX.f
  EchelleY.f
EndStructure
Structure SP_MOTEUR
  Map Atlases.SP_ATLAS()
  Map Vues.SP_Vue()
  Map Couches.SP_Couche()
  Map Sprites.SP_SPRITE()
  *SpriteDefaut.SP_SPRITE
  *CoucheDefaut.SP_Couche
  Array OrdreUV.i(3, 3)
EndStructure
Global MoteurSprite.SP_MOTEUR

Macro SP_Colon
  :
EndMacro
Macro SP_Override(Function)
  SP_Colon#Macro Function#SP_Colon#SP_#Function#SP_Colon#EndMacro
EndMacro
SP_Override(SpriteID)
SP_Override(PivoterSprite)
SP_Override(LibererSprite)

Enumeration
  #Sprite_Cache=%1
  #Sprite_RetournerX=%10
  #Sprite_RetournerY=%100
  #Sprite_RetournerXY=#Sprite_RetournerX|#Sprite_RetournerY
  #Sprite_Desactive=%1000
  
  #Couche_Cache=%1
  #Ombre_Couche=%10
EndEnumeration

Procedure.i VueID(Vue)
  ProcedureReturn FindMapElement(MoteurSprite\Vues(), ""+Vue)
EndProcedure
Procedure.i CoucheID(Couche)
  ProcedureReturn FindMapElement(MoteurSprite\Couches(), ""+Couche)
EndProcedure
Procedure.i SpriteID(Sprite)
  ProcedureReturn FindMapElement(MoteurSprite\Sprites(), ""+Sprite)
EndProcedure
Procedure.i AtlasID(Atlas)
  ProcedureReturn FindMapElement(MoteurSprite\Atlases(), ""+Atlas)
EndProcedure

;---------- Couleur
Macro CouleurRGB(CouleurRGBA)
  RGB(Red(CouleurRGBA), Green(CouleurRGBA), Blue(CouleurRGBA))
EndMacro
Macro CouleurRGBA(CouleurRGB, Alpha)
  RGBA(Red(CouleurRGB), Green(CouleurRGB), Blue(CouleurRGB), Alpha)
EndMacro

;---------- ATLAS
Procedure LibererAtlas(Atlas)
  Protected *Atlas.SP_ATLAS=AtlasID(Atlas)
  ;free resources
  FreeTexture(*Atlas\Texture)
  DeleteMapElement(MoteurSprite\Atlases(), ""+Atlas)
EndProcedure
Procedure.i CreerAtlas(Atlas, Largeur, Hauteur)
  Protected Resultat
  If Atlas=#PB_Any
    Static NumeroAtlas=$FFFF : NumeroAtlas+103 : Atlas=NumeroAtlas
    AddMapElement(MoteurSprite\Atlases(), ""+Atlas)
    Resultat=Atlas
  Else
    If AtlasID(Atlas) : LibererAtlas(Atlas) : EndIf
    Resultat=AddMapElement(MoteurSprite\Atlases(), ""+Atlas)
  EndIf
  
  With MoteurSprite\Atlases()
    \Atlas=Atlas
    \Texture=CreateTexture(#PB_Any, Largeur, Hauteur)
    \Frames(0)\u[0]=0 : \Frames(0)\v[0]=0
    \Frames(0)\u[1]=1 : \Frames(0)\v[1]=0
    \Frames(0)\u[2]=1 : \Frames(0)\v[2]=1
    \Frames(0)\u[3]=0 : \Frames(0)\v[3]=1
    \Frames(0)\Largeur=Largeur
    \Frames(0)\Hauteur=Hauteur
    ProcedureReturn Resultat
  EndWith
EndProcedure
Procedure.i ChargerAtlas(Atlas, FichierImage.s, Qualite=2)
  Protected ImageTextire=LoadImage(#PB_Any, FichierImage)
  Protected LargTexture=ImageWidth(ImageTextire)
  Protected HautTexture=ImageHeight(ImageTextire)
  
  If Qualite>0
    ;power of 2 texture size improves rendering Qualite
    LargTexture=Pow(2, Round(Log(LargTexture)/Log(2), #PB_Round_Up))
    HautTexture=Pow(2, Round(Log(HautTexture)/Log(2), #PB_Round_Up))
    
    ;texture square size improves compatibility with some GPU
    If Qualite>1
      If LargTexture<HautTexture : LargTexture=HautTexture : Else : HautTexture=LargTexture : EndIf
    EndIf
  EndIf
  
  Protected Resultat=CreerAtlas(Atlas, LargTexture, HautTexture)
  With MoteurSprite\Atlases()
    StartDrawing(TextureOutput(\Texture))
    DrawingMode(#PB_2DDrawing_AlphaBlend)
    DrawImage(ImageID(ImageTextire), 0, 0)
    StopDrawing()
  EndWith
  FreeImage(ImageTextire)
  
  ProcedureReturn Resultat
EndProcedure
Procedure.i SortieAtlas(Atlas)
  Protected *Atlas.SP_ATLAS=AtlasID(Atlas)
  ProcedureReturn TextureOutput(*Atlas\Texture)
EndProcedure
Procedure.i DefinirFrameAtlas(Atlas, Frame, x, y, Largeur, Hauteur, PointChaudX=0, PointChaudY=0, EstPivote=#False)
  Protected *Atlas.SP_ATLAS=AtlasID(Atlas)
  With *Atlas
    If Frame=#PB_Any
      Frame=ArraySize(\Frames())+1
    EndIf
    If Frame> ArraySize(\Frames())
      ReDim \Frames(Frame)
    EndIf
    
    If EstPivote : x-1 : EndIf
    Protected tw.f=TextureWidth(\Texture)
    Protected th.f=TextureHeight(\Texture)
    Protected u0.f=x/tw, v0.f=y/th
    Protected u1.f=(x+Largeur)/tw, v1.f=(y+Hauteur)/th
  EndWith
  With *Atlas\Frames(Frame)
    If EstPivote
      \u[0]=u1 : \v[0]=v0
      \u[1]=u1 : \v[1]=v1
      \u[2]=u0 : \v[2]=v1
      \u[3]=u0 : \v[3]=v0
      \Largeur=Hauteur
      \Hauteur=Largeur
      \PointChaudX=PointChaudY
      \PointChaudY=\Hauteur-PointChaudX
    Else
      \u[0]=u0 : \v[0]=v0
      \u[1]=u1 : \v[1]=v0
      \u[2]=u1 : \v[2]=v1
      \u[3]=u0 : \v[3]=v1
      \Largeur=Largeur
      \Hauteur=Hauteur
      \PointChaudX=PointChaudX
      \PointChaudY=PointChaudY
    EndIf
  EndWith
  ProcedureReturn Frame
EndProcedure
Procedure LancerAtlas(Atlas, Marge=1)
EndProcedure
Procedure ArreterAtlas()
EndProcedure

;---------- SPRITE
Procedure LibererSprite(Sprite)
  Protected *Sprite.SP_Sprite=SpriteID(Sprite)
  ;detach parent
  FindMapElement(*Sprite\CoucheParent\SpritesAttaches(), ""+Sprite)
  DeleteMapElement(*Sprite\CoucheParent\SpritesAttaches())
  ;free resources
  If *Sprite\Deformer : FreeMemory(*Sprite\Deformer) : EndIf
  DeleteMapElement(MoteurSprite\Sprites(), ""+Sprite)
EndProcedure
Procedure.i CreerSpriteAnime(Sprite, Couche, x.f, y.f, Frame=#PB_Default, Couleur=#PB_Default, Transparence=#PB_Default, Angle.f=#PB_Default, EchelleX.f=#PB_Default, EchelleY.f=#PB_Default)
  Protected Resultat
  If Sprite=#PB_Any
    Static NumeroSprite=$FFFF : NumeroSprite+103 : Sprite=NumeroSprite
    AddMapElement(MoteurSprite\Sprites(), ""+Sprite)
    Resultat=Sprite
  Else
    If SpriteID(Sprite) : LibererSprite(Sprite) : EndIf
    Resultat=AddMapElement(MoteurSprite\Sprites(), ""+Sprite)
  EndIf
  
  With MoteurSprite\Sprites()
    \Sprite=Sprite
    \CoucheParent=CoucheID(Couche)
    \CoucheParent\SpritesAttaches(""+Sprite)=MoteurSprite\Sprites()
    
    Protected indexCoin, nouvelleCouleur=Couleur, nouvelleTransparence=Transparence, couleurDefaut
    For indexCoin=0 To 3
      couleurDefaut=MoteurSprite\SpriteDefaut\Couleurs[indexCoin]
      If Couleur=#PB_Default : nouvelleCouleur=CouleurRGB(couleurDefaut) : EndIf
      If Transparence=#PB_Default : nouvelleTransparence=Alpha(couleurDefaut) : EndIf
      \Couleurs[indexCoin]=CouleurRGBA(nouvelleCouleur, nouvelleTransparence)
    Next
    If Frame=#PB_Default : \Frame=MoteurSprite\SpriteDefaut\Frame : Else : \Frame=Frame : EndIf
    If x=#PB_Default : \x=MoteurSprite\SpriteDefaut\x : Else : \x=x : EndIf
    If y=#PB_Default : \y=MoteurSprite\SpriteDefaut\y : Else : \y=y : EndIf
    If Angle=#PB_Default : \Angle=MoteurSprite\SpriteDefaut\Angle : Else : \Angle=Angle : EndIf
    If EchelleX=#PB_Default : \EchelleX=MoteurSprite\SpriteDefaut\EchelleX : Else : \EchelleX=EchelleX : EndIf
    If EchelleY=#PB_Default : \EchelleY=MoteurSprite\SpriteDefaut\EchelleY : Else : \EchelleY=EchelleY : EndIf
    ProcedureReturn Resultat
  EndWith
EndProcedure
Procedure CacherSprite(Sprite, EstCache)
  Protected *Sprite.SP_SPRITE=SpriteID(Sprite)
  *Sprite\Etat & ~#Sprite_Cache | Bool(EstCache)*#Sprite_Cache
EndProcedure
Procedure DesactiverSprite(Sprite, EstDesactive)
  Protected *Sprite.SP_SPRITE=SpriteID(Sprite)
  *Sprite\Etat & ~#Sprite_Desactive | Bool(EstDesactive)*#Sprite_Desactive
EndProcedure
Procedure DeplacerSprite(Sprite, x.f, y.f, Mode=#PB_Relative)
  Protected *Sprite.SP_SPRITE=SpriteID(Sprite)
  If Mode = #PB_Relative
    *Sprite\x+x
    *Sprite\y+y
  Else
    *Sprite\x=x
    *Sprite\y=y
  EndIf
EndProcedure
Procedure PivoterSprite(Sprite, Angle.f, Mode=#PB_Relative)
  Protected *Sprite.SP_SPRITE=SpriteID(Sprite)
  If Mode=#PB_Relative
    *Sprite\Angle+Angle
  Else
    *Sprite\Angle=Angle
  EndIf
EndProcedure
Procedure EchelleSprite(Sprite, EchelleX.f, EchelleY.f, Mode=#PB_Absolute)
  Protected *Sprite.SP_SPRITE=SpriteID(Sprite)
  If Mode=#PB_Absolute
    *Sprite\EchelleX=EchelleX
    *Sprite\EchelleY=EchelleY
  Else
    *Sprite\EchelleX+EchelleX
    *Sprite\EchelleY+EchelleY
  EndIf
EndProcedure
Procedure RetournerSprite(Sprite, RetournerX=#False, RetournerY=#False)
  Protected *Sprite.SP_SPRITE=SpriteID(Sprite)
  With *Sprite
    RetournerX & ~(#Sprite_RetournerX|#Sprite_RetournerY)
    If RetournerX : \Etat | #Sprite_RetournerX : EndIf
    If RetournerY : \Etat | #Sprite_RetournerY : EndIf
  EndWith
EndProcedure
Procedure DeformerSprite(Sprite, x0.f, y0.f, x1.f, y1.f, x2.f, y2.f, x3.f, y3.f)
  Protected *Sprite.SP_SPRITE=SpriteID(Sprite)
  With *Sprite\Deformer
    *Sprite\Deformer=AllocateMemory(SizeOf(SP_DEFORMATION))
    \x[0]=x0 : \y[0]=y0
    \x[1]=x1 : \y[1]=y1
    \x[2]=x2 : \y[2]=y2
    \x[3]=x3 : \y[3]=y3
  EndWith
EndProcedure
Procedure FausserSprite(Sprite, Premier.f, Second.f, Vertical=#False)
  If Vertical
    DeformerSprite(Sprite, 0, Premier, 0, Second, 0, Second, 0, Premier)
  Else
    DeformerSprite(Sprite, Premier, 0, Premier, 0, Second, 0, Second, 0)
  EndIf
EndProcedure
Procedure AgencerSprite(Sprite, Gauche.f=#PB_Ignore, Haut.f=#PB_Ignore, Droite.f=#PB_Ignore, Bas.f=#PB_Ignore, EnPixels=#True)
  Protected *Sprite.SP_SPRITE=SpriteID(Sprite)
  With *Sprite
    Protected l=\CoucheParent\VueParent\LargeurCamera
    Protected h=\CoucheParent\VueParent\CameraHauteur
    Protected AgencementX, AgencementY
    If Not EnPixels
      If Haut<>#PB_Ignore : Haut*h : EndIf
      If Bas<>#PB_Ignore : Bas*h : EndIf
      If Droite<>#PB_Ignore : Droite*l : EndIf
      If Gauche<>#PB_Ignore : Gauche*l : EndIf
    EndIf
    AgencementX+1*Bool(Gauche<>#PB_Ignore)+2*Bool(Droite<>#PB_Ignore)
    AgencementY+1*Bool(Haut<>#PB_Ignore)+2*Bool(Bas<>#PB_Ignore)
    Select AgencementX
      Case 0 :
      Case 1 :
      Case 2 :
      Case 3 :
    EndSelect
  EndWith
EndProcedure
Procedure DefinirTransparenceSprite(Sprite, Transparence, indexCoin=#PB_Any)
  Protected *Sprite.SP_SPRITE=SpriteID(Sprite)
  If indexCoin=#PB_Any
    For indexCoin=0 To 3
      *Sprite\Couleurs[indexCoin]=CouleurRGBA(CouleurRGB(*Sprite\Couleurs[indexCoin]), Transparence)
    Next
  Else
    *Sprite\Couleurs[indexCoin]=CouleurRGBA(CouleurRGB(*Sprite\Couleurs[indexCoin]), Transparence)
  EndIf
EndProcedure
Procedure DefinirCouleurSprite(Sprite, Couleur, indexCoin=#PB_Any)
  Protected *Sprite.SP_SPRITE=SpriteID(Sprite)
  If indexCoin=#PB_Any
    For indexCoin=0 To 3
      *Sprite\Couleurs[indexCoin]=CouleurRGBA(Couleur, Alpha(*Sprite\Couleurs[indexCoin]))
    Next
  Else
    *Sprite\Couleurs[indexCoin]=CouleurRGBA(Couleur, Alpha(*Sprite\Couleurs[indexCoin]))
  EndIf
EndProcedure
Procedure DefinirFrameSprite(Sprite, Frame)
  Protected *Sprite.SP_SPRITE=SpriteID(Sprite)
  *Sprite\Frame=Frame
EndProcedure
Procedure.f AngleSprite(Sprite)
  Protected *Sprite.SP_SPRITE=SpriteID(Sprite)
  ProcedureReturn *Sprite\Angle
EndProcedure
Procedure.f SpriteX(Sprite)
  Protected *Sprite.SP_SPRITE=SpriteID(Sprite)
  ProcedureReturn *Sprite\x
EndProcedure
Procedure.f SpriteY(Sprite)
  Protected *Sprite.SP_SPRITE=SpriteID(Sprite)
  ProcedureReturn *Sprite\y
EndProcedure
Procedure.f SpriteEchelleX(Sprite)
  Protected *Sprite.SP_SPRITE=SpriteID(Sprite)
  ProcedureReturn *Sprite\EchelleX
EndProcedure
Procedure.f SpriteEchelleY(Sprite)
  Protected *Sprite.SP_SPRITE=SpriteID(Sprite)
  ProcedureReturn *Sprite\EchelleY
EndProcedure
Procedure.i couleurSprite(Sprite, indexCoin=0)
  Protected *Sprite.SP_SPRITE=SpriteID(Sprite)
  ProcedureReturn CouleurRGB(*Sprite\Couleurs[indexCoin])
EndProcedure
Procedure.i TransparenceSprite(Sprite, indexCoin=0)
  Protected *Sprite.SP_SPRITE=SpriteID(Sprite)
  ProcedureReturn Alpha(*Sprite\Couleurs[indexCoin])
EndProcedure
Procedure.i FrameSprite(Sprite)
  Protected *Sprite.SP_SPRITE=SpriteID(Sprite)
  ProcedureReturn *Sprite\Frame
EndProcedure
Procedure.i CacheSprite(Sprite)
  Protected *Sprite.SP_SPRITE=SpriteID(Sprite)
  ProcedureReturn Bool(*Sprite\Etat & #Sprite_Cache)
EndProcedure
Procedure.i EtatSprite(Sprite)
  Protected *Sprite.SP_SPRITE=SpriteID(Sprite)
  ProcedureReturn *Sprite\Etat
EndProcedure

;---------- Couche
Procedure LibererCouche(Couche)
  Protected *Couche.SP_Couche=CoucheID(Couche)
  ;delete dependencies
  ForEach *Couche\SpritesAttaches()
    FreeSprite(*Couche\SpritesAttaches()\Sprite)
  Next
  ;detach parent
  FindMapElement(*Couche\VueParent\AttachedCouches(), ""+Couche)
  DeleteMapElement(*Couche\VueParent\AttachedCouches())
  ;free resources
  FreeNode(*Couche\CouchePivot)
  FreeNode(*Couche\CoucheDecalage)
  FreeNode(*Couche\CouchePosition)
  FreeNode(*Couche\CoucheOmbre)
  FreeMesh(*Couche\Mesh)
  FreeMesh(*Couche\OmbreMesh)
  FreeMaterial(*Couche\Material)
  FreeMaterial(*Couche\OmbreMateriel)
  DeleteMapElement(MoteurSprite\Couches(), ""+Couche)
EndProcedure
Procedure.i CreerCouche(Couche, Vue, *AtlasID, MelangeMateriel=#PB_Default, FiltreMateriel=#PB_Default)
  Protected Resultat
  If Couche=#PB_Any
    Static NumeroCouche=$FFFF : NumeroCouche+103 : Couche=NumeroCouche
    AddMapElement(MoteurSprite\Couches(), ""+Couche)
    Resultat=Couche
  Else
    If CoucheID(Couche) : LibererCouche(Couche) : EndIf
    Resultat=AddMapElement(MoteurSprite\Couches(), ""+Couche)
  EndIf
  
  With MoteurSprite\Couches()
    \Couche=Couche
    \Atlas=*AtlasID
    \Material=CreateMaterial(#PB_Any, TextureID(\Atlas\Texture))
    MaterialCullingMode(\Material, #PB_Material_NoCulling)
    If MelangeMateriel=#PB_Default : MelangeMateriel=MoteurSprite\CoucheDefaut\MelangeMateriel : EndIf
    If FiltreMateriel=#PB_Default : FiltreMateriel=MoteurSprite\CoucheDefaut\FiltreMateriel : EndIf
    MaterialFilteringMode(\Material, FiltreMateriel)
    MaterialBlendingMode(\Material, MelangeMateriel)
    DisableMaterialLighting(\Material, #True)
    \OmbreMateriel=CopyMaterial(\Material, #PB_Any)
    
    \Mesh=CreateMesh(#PB_Any, #PB_Mesh_TriangleList, #PB_Mesh_Dynamic)
    SetMeshMaterial(\Mesh, MaterialID(\Material))
    MeshVertexPosition(0, 0, 0)
    MeshVertexNormal(0, 0, 0)
    MeshVertexTangent(0, 0, 0)
    MeshVertexTextureCoordinate(0, 0)
    MeshVertexColor(RGBA(255, 255, 255, 255))
    MeshVertexPosition(1, 0, 0)
    MeshVertexPosition(1, 1, 0)
    MeshFace(0, 1, 2)
    FinishMesh(0)
    NormalizeMesh(\Mesh)
    
    \OmbreMesh=CreateMesh(#PB_Any, #PB_Mesh_TriangleList, #PB_Mesh_Dynamic)
    SetMeshMaterial(\OmbreMesh, MaterialID(\OmbreMateriel))
    MeshVertexPosition(0, 0, 0)
    MeshVertexNormal(0, 0, 0)
    MeshVertexTangent(0, 0, 0)
    MeshVertexTextureCoordinate(0, 0)
    MeshVertexColor(RGBA(255, 255, 255, 255))
    MeshVertexPosition(1, 0, 0)
    MeshVertexPosition(1, 1, 0)
    MeshFace(0, 1, 2)
    FinishMesh(0)
    NormalizeMesh(\OmbreMesh)
    
    \CoucheOmbre=CreateNode(#PB_Any)
    \CouchePosition=CreateNode(#PB_Any)
    \CoucheDecalage=CreateNode(#PB_Any)
    \CouchePivot=CreateNode(#PB_Any)
    SetRenderQueue(MeshID(\OmbreMesh), 1, 10)
    SetRenderQueue(MeshID(\Mesh), 1, 100)
    AttachNodeObject(\CouchePosition, NodeID(\CoucheOmbre))
    AttachNodeObject(\CouchePosition, MeshID(\Mesh))
    AttachNodeObject(\CoucheDecalage, NodeID(\CouchePosition))
    AttachNodeObject(\CouchePivot, NodeID(\CoucheDecalage))
    \VueParent=VueID(Vue)
    \VueParent\AttachedCouches(""+Couche)=MoteurSprite\Couches()
    AttachNodeObject(\VueParent\VuePivot, NodeID(\CouchePivot))
    ScaleNode(\CoucheDecalage, \VueParent\EchelleX, \VueParent\EchelleY, 1)
    MoveNode(\CoucheDecalage, \VueParent\DecalageX, \VueParent\DecalageY, 500)
    ProcedureReturn Resultat
  EndWith
EndProcedure
Procedure CacherCouche(Couche, EstCache)
  Protected *Couche.SP_Couche=CoucheID(Couche)
  With *Couche
    If EstCache
      If Not (\Etat & #Couche_Cache)
        \Etat | #Couche_Cache
        DetachNodeObject(\CouchePosition, MeshID(\Mesh))
        If (\Etat & #Ombre_Couche) : DetachNodeObject(\CoucheOmbre, MeshID(\OmbreMesh)) : EndIf
      EndIf
    Else
      If \Etat & #Couche_Cache
        \Etat & ~#Couche_Cache
        AttachNodeObject(\CouchePosition, MeshID(\Mesh))
        If (\Etat & #Ombre_Couche) : AttachNodeObject(\CoucheOmbre, MeshID(\OmbreMesh)) : EndIf
      EndIf
    EndIf
  EndWith
EndProcedure
Procedure DeplacerCouche(Couche, x.f, y.f, Mode=#PB_Relative)
  Protected *Couche.SP_Couche=CoucheID(Couche)
  If Mode = #PB_Relative
    *Couche\x+x
    *Couche\y+y
  Else
    *Couche\x=x
    *Couche\y=y
  EndIf
  MoveNode(*Couche\CouchePosition, x, y, 0, Mode)
EndProcedure
Procedure PivoterCouche(Couche, Angle.f, Mode=#PB_Relative)
  Protected *Couche.SP_Couche=CoucheID(Couche)
  RotateNode(*Couche\CoucheRoll, 0, 0, Angle, Mode)
EndProcedure
Procedure EchelleCouche(Couche, EchelleX.f, EchelleY.f, Mode=#PB_Absolute)
  Protected *Couche.SP_Couche=CoucheID(Couche)
  If Mode=#PB_Absolute
    *Couche\EchelleX=EchelleX
    *Couche\EchelleY=EchelleY
  Else
    *Couche\EchelleX+EchelleX
    *Couche\EchelleY+EchelleY
  EndIf
  ScaleNode(*Couche\CoucheEchelle, EchelleX, EchelleY, 1, Mode)
EndProcedure
Procedure DefinirOmbreCouche(Couche, CastOmbre, Couleur.f=#PB_Ignore, Transparence.f=#PB_Ignore, DecalageX.f=#PB_Ignore, DecalageY.f=#PB_Ignore)
  Protected *Couche.SP_Couche=CoucheID(Couche)
  With *Couche
    If CastOmbre
      If Not (\Etat & #Ombre_Couche)
        \Etat | #Ombre_Couche
        If Not (\Etat & #Couche_Cache)
          AttachNodeObject(\CoucheOmbre, MeshID(\OmbreMesh))
        EndIf
      EndIf
      If Couleur.f<>#PB_Ignore : \CouleurOmbre=CouleurRGBA(Couleur, Alpha(\CouleurOmbre)) : EndIf
      If Transparence.f<>#PB_Ignore : \CouleurOmbre=CouleurRGBA(CouleurRGB(\CouleurOmbre), Transparence) : EndIf
      If DecalageX.f<>#PB_Ignore : \DecalageOmbreX=DecalageX : EndIf
      If DecalageY.f<>#PB_Ignore : \DecalageOmbreY=DecalageY : EndIf
      MoveNode(\CoucheOmbre, \DecalageOmbreX, \DecalageOmbreY, 0, #PB_Absolute)
      MaterialBlendingMode(\OmbreMateriel, #PB_Material_AlphaBlend)
    Else
      If \Etat & #Ombre_Couche
        \Etat & ~#Ombre_Couche
        DetachNodeObject(\CoucheOmbre, MeshID(\OmbreMesh))
      EndIf
    EndIf
  EndWith
EndProcedure
Procedure DefinirOrdreCouche(Couche, Order, OrdreOmbre=#PB_Ignore)
  Protected *Couche.SP_Couche=CoucheID(Couche)
  With *Couche
    If Order<>#PB_Ignore
      If Order<0 : Order=0 : EndIf
      If Order>10000 : Order=10000 : EndIf
      SetRenderQueue(MeshID(\Mesh), 1, Order)
    EndIf
    If OrdreOmbre<>#PB_Ignore
      If OrdreOmbre<0 : OrdreOmbre=0 : EndIf
      If OrdreOmbre>10000 : OrdreOmbre=10000 : EndIf
      SetRenderQueue(MeshID(\OmbreMesh), 1, OrdreOmbre)
    EndIf
  EndWith
EndProcedure
Procedure.f AngleCouche(Couche)
  Protected *Couche.SP_Couche=CoucheID(Couche)
  ProcedureReturn NodeRoll(*Couche\CoucheRoll)
EndProcedure
Procedure.f CoucheX(Couche)
  Protected *Couche.SP_Couche=CoucheID(Couche)
  ProcedureReturn *Couche\x
EndProcedure
Procedure.f CoucheY(Couche)
  Protected *Couche.SP_Couche=CoucheID(Couche)
  ProcedureReturn *Couche\y
EndProcedure
Procedure.f CoucheEchelleX(Couche)
  Protected *Couche.SP_Couche=CoucheID(Couche)
  ProcedureReturn *Couche\EchelleX
EndProcedure
Procedure.f CoucheEchelleY(Couche)
  Protected *Couche.SP_Couche=CoucheID(Couche)
  ProcedureReturn *Couche\EchelleY
EndProcedure
Procedure.i CacheCouche(Couche)
  Protected *Couche.SP_Couche=CoucheID(Couche)
  ProcedureReturn Bool(*Couche\Etat & #Couche_Cache)
EndProcedure
Procedure.i EtatCouche(Couche)
  Protected *Couche.SP_Couche=CoucheID(Couche)
  ProcedureReturn *Couche\Etat
EndProcedure

;---------- Vue
Procedure LibererVue(Vue)
  Protected *Vue.SP_Vue=VueID(Vue)
  ;delete dependencies
  ForEach *Vue\AttachedCouches()
    LibererCouche(*Vue\AttachedCouches()\Couche)
  Next
  ;free resources
  FreeCamera(*Vue\Camera)
  FreeNode(*Vue\VuePivot)
  DeleteMapElement(MoteurSprite\Vues(), ""+Vue)
EndProcedure
Procedure.i CreerVue(Vue, BackCouleur=0, EstEtire=#False, x.f=0, y.f=0, l.f=100, h.f=100)
  Protected Resultat
  If Vue=#PB_Any
    Static NumeroVue=$FFFF : NumeroVue+103 : Vue=NumeroVue
    AddMapElement(MoteurSprite\Vues(), ""+Vue)
    Resultat=Vue
  Else
    If VueID(Vue) : LibererVue(Vue) : EndIf
    Resultat=AddMapElement(MoteurSprite\Vues(), ""+Vue)
  EndIf
  
  With MoteurSprite\Vues()
    \Vue=Vue
    \Camera=CreateCamera(#PB_Any, x, y, l, h)
    \CameraX=CameraViewX(\Camera)
    \CameraY=CameraViewY(\Camera)
    \LargeurCamera=CameraViewWidth(\Camera)
    \CameraHauteur=CameraViewHeight(\Camera)
    CameraBackColor(\Camera, BackCouleur)
    CameraRange(\Camera, 0.1, 1000)
    CameraProjectionMode(\Camera, #PB_Camera_Orthographic)
    SetOrientation(CameraID(\Camera), 1, 0, 0, 0)
    
    Protected Cache=CreateEntity(#PB_Any, MeshID(CreateCube(#PB_Any, 100)), #PB_Material_None)
    ScaleEntity(Cache, 100, 100, 0.01)
    HideEntity(Cache, 1)
    MoveEntity(Cache, 0, 0, 500)
    
    \VuePivot=CreateNode(#PB_Any)
    \DecalageVue=CreateNode(#PB_Any)
    \VuePosition=CreateNode(#PB_Any)
    AttachNodeObject(\VuePosition, CameraID(\Camera))
    AttachNodeObject(\DecalageVue, NodeID(\VuePosition))
    AttachNodeObject(\VuePivot, NodeID(\DecalageVue))
    AttachNodeObject(\VuePivot, EntityID(Cache))
    
    RenderWorld()
    If MousePick(\Camera, CameraViewX(\Camera), CameraViewY(\Camera))
      \DecalageX=PickX()
      \DecalageY=PickY()
      If EstEtire
        \EchelleX=Abs(PickX()/(ScreenWidth()/2))
        \EchelleY=Abs(PickY()/(ScreenHeight()/2))
      Else
        \EchelleX=Abs(PickX()/(CameraViewWidth(\Camera)/2))
        \EchelleY=Abs(PickY()/(CameraViewHeight(\Camera)/2))
      EndIf
      FreeEntity(Cache)
    EndIf
    
    ScaleNode(\DecalageVue, \EchelleX, \EchelleY, 1)
    
    Static nouvelleVuePos : nouvelleVuePos+$FFFF
    MoveNode(\VuePivot, nouvelleVuePos, nouvelleVuePos, nouvelleVuePos)
    
    ProcedureReturn Resultat
  EndWith
EndProcedure
Procedure ModeVueCamera(Vue, RenderMode=#PB_Camera_Textured)
  Protected *Vue.SP_Vue=VueID(Vue)
  CameraRenderMode(*Vue\Camera, RenderMode)
EndProcedure
Procedure DeplacerVue(Vue, x.f, y.f, Mode=#PB_Relative)
  Protected *Vue.SP_Vue=VueID(Vue)
  If Mode = #PB_Relative
    *Vue\x+x
    *Vue\y+y
  Else
    *Vue\x=x
    *Vue\y=y
  EndIf
  ProcedureReturn MoveNode(*Vue\VuePosition, x, y, 0, Mode)
EndProcedure
Procedure PivoterVue(Vue, Angle.f, Mode=#PB_Relative)
  Protected *Vue.SP_Vue=VueID(Vue)
  RotateNode(*Vue\VueRoll, 0, 0, Angle, Mode)
EndProcedure
Procedure.f AngleVue(Vue)
  Protected *Vue.SP_Vue=VueID(Vue)
  ProcedureReturn NodeRoll(*Vue\VueRoll)
EndProcedure
Procedure.f VueX(Vue)
  Protected *Vue.SP_Vue=VueID(Vue)
  ProcedureReturn *Vue\x
EndProcedure
Procedure.f VueY(Vue)
  Protected *Vue.SP_Vue=VueID(Vue)
  ProcedureReturn *Vue\y
EndProcedure
Procedure.i VueCameraX(Vue)
  Protected *Vue.SP_Vue=VueID(Vue)
  ProcedureReturn *Vue\CameraX
EndProcedure
Procedure.i VueCameraY(Vue)
  Protected *Vue.SP_Vue=VueID(Vue)
  ProcedureReturn *Vue\CameraY
EndProcedure
Procedure.i LargeurCameraVue(Vue)
  Protected *Vue.SP_Vue=VueID(Vue)
  ProcedureReturn *Vue\LargeurCamera
EndProcedure
Procedure.i HauteurCameraVue(Vue)
  Protected *Vue.SP_Vue=VueID(Vue)
  ProcedureReturn *Vue\CameraHauteur
EndProcedure

Procedure InitMoteurSprite()
  If InitSprite()
    With MoteurSprite
      \SpriteDefaut=AddMapElement(\Sprites(), ""+#PB_Default)
      \CoucheDefaut=AddMapElement(\Couches(), ""+#PB_Default)
      
      \OrdreUV(0, 0)=0 : \OrdreUV(0, 1)=1 : \OrdreUV(0, 2)=2 : \OrdreUV(0, 3)=3 ;Normal
      \OrdreUV(1, 0)=1 : \OrdreUV(1, 1)=0 : \OrdreUV(1, 2)=3 : \OrdreUV(1, 3)=2 ;Retourner X
      \OrdreUV(2, 0)=3 : \OrdreUV(2, 1)=2 : \OrdreUV(2, 2)=1 : \OrdreUV(2, 3)=0 ;Retourner Y
      \OrdreUV(3, 0)=2 : \OrdreUV(3, 1)=3 : \OrdreUV(3, 2)=0 : \OrdreUV(3, 3)=1 ;Retourner X & Y
    EndWith
    Protected CouleurOpaque=RGBA(255, 255, 255, 255)
    Protected indexCoin
    With MoteurSprite\SpriteDefaut
      \EchelleX=1
      \EchelleY=1
      For indexCoin=0 To 3 : \Couleurs[indexCoin]=CouleurOpaque : Next
    EndWith
    With MoteurSprite\CoucheDefaut
      \MelangeMateriel=#PB_Material_AlphaBlend
      \FiltreMateriel=#PB_Material_Bilinear
    EndWith
    
    ProcedureReturn #True
  EndIf
EndProcedure
Procedure RenduSprites()
  Protected *Vue.SP_Vue, *Couche.SP_Couche, *Sprite.SP_SPRITE
  Protected indexSommet
  
  ForEach MoteurSprite\Vues()
    ForEach MoteurSprite\Vues()\AttachedCouches()
      *Couche=MoteurSprite\Vues()\AttachedCouches()
      If *Couche\Etat & #Couche_Cache : Continue : EndIf
      
      indexSommet=0
      UpdateMesh(*Couche\Mesh, 0)
      ForEach *Couche\SpritesAttaches()
        *Sprite=*Couche\SpritesAttaches()
        If *Sprite\Etat & #Sprite_Cache : Continue : EndIf
        
        With *Sprite
          Protected *Frame.SP_FRAME=\CoucheParent\Atlas\Frames(\Frame)
          Protected x0.f, y0.f, x1.f, y1.f, hx.f, hy.f, i, RetournerMode=0
          Dim x.f(3) : Dim y.f(3)
          Dim u.f(3) : Dim v.f(3)
          
          hx=*Frame\PointChaudX
          hy=*Frame\PointChaudY
          If Not (\Etat & #Sprite_RetournerXY)
            CopyMemory(@*Frame\u[0], u(), 4*SizeOf(Float))
            CopyMemory(@*Frame\v[0], v(), 4*SizeOf(Float))
          Else
            RetournerMode=1*Bool(\Etat & #Sprite_RetournerX)+2*Bool(\Etat & #Sprite_RetournerY)
            If \Etat & #Sprite_RetournerX : hx=*Frame\Largeur-hx : EndIf
            If \Etat & #Sprite_RetournerY : hy=*Frame\Hauteur-hy : EndIf
            For i=0 To 3
              u(i)=*Frame\u[MoteurSprite\OrdreUV(RetournerMode, i)]
              v(i)=*Frame\v[MoteurSprite\OrdreUV(RetournerMode, i)]
            Next
          EndIf
          
          If \Angle=0 And \Deformer=0
            x0=\x-hx*\EchelleX : x1=x0+*Frame\Largeur*\EchelleX
            y0=\y-hy*\EchelleY : y1=y0+*Frame\Hauteur*\EchelleY
            x(0)=x0 : y(0)=y0 : x(1)=x1 : y(1)=y0
            x(2)=x1 : y(2)=y1 : x(3)=x0 : y(3)=y1
          Else
            x0=-hx*\EchelleX : x1=x0+*Frame\Largeur*\EchelleX
            y0=-hy*\EchelleY : y1=y0+*Frame\Hauteur*\EchelleY
            x(0)=x0 : y(0)=y0 : x(1)=x1 : y(1)=y0
            x(2)=x1 : y(2)=y1 : x(3)=x0 : y(3)=y1
            
            If \Deformer
              For i=0 To 3
                x(i)+\Deformer\x[i]
                y(i)+\Deformer\y[i]
              Next
            EndIf
            Protected radian.f=Radian(\Angle)
            Protected cos.f=Cos(radian), sin.f=Sin(radian)
            For i=0 To 3
              Protected px.f=x(i), py.f=y(i)
              x(i)=\x+cos*px-sin*py
              y(i)=\y+sin*px+cos*py
            Next
          EndIf
          
          For i=0 To 3
            MeshVertexPosition(x(i), y(i), 0)
            MeshVertexTextureCoordinate(u(i), v(i))
            MeshVertexColor(\Couleurs[i])
          Next
          
          MeshFace(indexSommet, indexSommet+1, indexSommet+2)
          MeshFace(indexSommet+2, indexSommet+3, indexSommet)
          indexSommet+4
        EndWith
      Next
      FinishMesh(0)
      
      With *Couche
        If \Etat & #Ombre_Couche
          Dim vertices.PB_meshvertex(0)
          Dim faces.PB_MeshFace(0)
          GetMeshData(\Mesh, 0, vertices(), #PB_Mesh_Vertex|#PB_Mesh_Vertex|#PB_Mesh_UVCoordinate, 0, MeshVertexCount(\Mesh, 0)-1)
          GetMeshData(\Mesh, 0, faces(), #PB_Mesh_Face, 0, MeshIndexCount(\Mesh, 0)-1)
          
          UpdateMesh(\OmbreMesh, 0)
          For i=0 To ArraySize(vertices())
            MeshVertexPosition(vertices(i)\x, vertices(i)\y, 0)
            MeshVertexTextureCoordinate(vertices(i)\u, vertices(i)\v)
            MeshVertexColor(\CouleurOmbre)
          Next
          For i=0 To ArraySize(faces())
            MeshIndex(faces(i)\Index)
          Next
          FinishMesh(0)
        EndIf
      EndWith
    Next
  Next
EndProcedure



CompilerIf #PB_Compiler_IsMainFile
  DisableExplicit
  If InitEngine3D()=0 Or InitMoteurSprite()=0
    MessageRequester("Init", "Echoué!")
    End
  EndIf
  
  AntialiasingMode(#PB_AntialiasingMode_None)
  
  win=OpenWindow(#PB_Any, 0, 0, 800, 600, "Moteur Sprite FX", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  OpenWindowedScreen(WindowID(win), 0, 0, WindowWidth(win), WindowHeight(win))
  
  ;dessiner image atlas
  fontID=LoadFont(0, "Arial", 22, #PB_Font_Bold|#PB_Font_HighQuality|#PB_Font_Italic)
  spriteAtlas=CreerAtlas(#PB_Any, 160, 128)
  If StartDrawing(SortieAtlas(spriteAtlas))
    
    DrawingMode(#PB_2DDrawing_Transparent|#PB_2DDrawing_AlphaBlend)
    DrawingFont(fontID)
    Texte.s = "MICOUTE"
    DrawText(25, 10, Texte, RGBA(255, 255, 255, 255))
    txtW=TextWidth(Texte)
    txtH=TextHeight(Texte)
    
    DrawingMode(#PB_2DDrawing_Gradient|#PB_2DDrawing_AlphaBlend)
    BackColor(RGBA(255, 255, 0, 255))
    GradientColor(0.8, RGBA(255, 0, 0, 50))
    FrontColor(RGBA(200, 70, 10, 255))
    LinearGradient(0, 0, 0, 64)
    Box(5, 5, 16, 64)
    
    ResetGradientColors()
    BackColor(RGBA(0, 255, 0, 255))
    GradientColor(0.8, RGBA(0, 0, 255, 50))
    FrontColor(RGBA(60, 100, 255, 255))
    LinearGradient(0, 0, 64, 0)
    Box(21, 69, 64, 16)
    
    ResetGradientColors()
    BackColor(RGBA(255, 255, 255, 255))
    GradientColor(0.6, RGBA(150, 150, 150, 255))
    FrontColor(RGBA(255, 255, 255, 255))
    LinearGradient(25, 53, 30, 70)
    For i=0 To 6
      RoundBox(25+i*20, 45, 16, 16, 7, 4)
    Next
    
    DrawingMode(#PB_2DDrawing_Outlined|#PB_2DDrawing_AlphaBlend)
    FrontColor(RGBA(255, 255, 255, 255))
    Box(5, 5, 16, 64)
    Box(21, 69, 64, 16)
    Box(0, 0, 159, 128)
    StopDrawing()
  EndIf
  ;extraire frames image
  frameRouge=DefinirFrameAtlas(spriteAtlas, #PB_Any, 5, 5, 16, 64)
  frameBleue=DefinirFrameAtlas(spriteAtlas, #PB_Any, 21, 69, 64, 16, 32, 8, #True)
  frameTexte=DefinirFrameAtlas(spriteAtlas, #PB_Any, 25, 10, txtW, txtH)
  
  ;créer une vue d'arrière plan
  vueFond=CreerVue(#PB_Any, RGB(10, 10, 10))
  If vueFond
    ;créer couches FX
    ajouterCoucheFX=CreerCouche(#PB_Any, vueFond, AtlasID(spriteAtlas), #PB_Material_Add, #PB_Material_None)
    CouleurCoucheFX=CreerCouche(#PB_Any, vueFond, AtlasID(spriteAtlas), #PB_Material_Color, #PB_Material_None)
    
    ;créer sprites FX (changement de couleur du sprite par défaut)
    DefinirCouleurSprite(#PB_Default, RGB(93, 137, 175), 2)
    For i=1 To 10
      ajouterFX=CreerSpriteAnime(#PB_Any, ajouterCoucheFX, 650, 200, frameRouge)
      EchelleSprite(ajouterFX, 1, 1+i*0.1)
      PivoterSprite(ajouterFX, -90+i*20)
    Next
    DefinirCouleurSprite(#PB_Default, RGB(93, 137, 175), 2)
    For i=1 To 10
      CouleurFX=CreerSpriteAnime(#PB_Any, CouleurCoucheFX, 650, 50, frameRouge)
      EchelleSprite(CouleurFX, 1, 1+i*0.1)
      PivoterSprite(CouleurFX, -90+i*20)
    Next
    DefinirCouleurSprite(#PB_Default, RGB(255, 255, 255))
  EndIf
  
  ;créer vue premier plan
  VuePP=CreerVue(#PB_Any, RGB(62, 62, 62), #False, 0, 0, 64.0, 85.34)
  ;Debug "Vue Caméra = "+VueCameraY(VuePP)+", "+VueCameraX(VuePP)+", "+LargeurCameraVue(VuePP)+", "+HauteurCameraVue(VuePP)
  If VuePP
    ;créer des couches lissées et pixellisées
    coucheLisse=CreerCouche(#PB_Any, VuePP, AtlasID(spriteAtlas))
    pixelCouche=CreerCouche(#PB_Any, VuePP, AtlasID(spriteAtlas), #PB_Material_AlphaBlend, #PB_Material_None)
    
    ;réorganiser les couches et activer l'ombre
    DefinirOmbreCouche(coucheLisse, #True, RGB(0, 0, 0), 100, 5, 5)
    DefinirOrdreCouche(coucheLisse, 100, 90)
    DefinirOrdreCouche(pixelCouche, 80)
    
    ;créer sprites
    imageEntiere=CreerSpriteAnime(#PB_Any, pixelCouche, 5, 5, 0)
    barreRouge=CreerSpriteAnime(#PB_Any, pixelCouche, 10, 150, frameRouge)
    barreBleue=CreerSpriteAnime(#PB_Any, pixelCouche, 10+(16+8+1), 150+32, frameBleue)
    
    ;créer des sprites pivotés et mis à l'échelle
    barreLisse=CreerSpriteAnime(#PB_Any, coucheLisse, 90, 190, frameBleue)
    PivoterSprite(barreLisse, -10)
    pixelBar=CreerSpriteAnime(#PB_Any, pixelCouche, 130, 190, frameBleue)
    PivoterSprite(pixelBar, -10)
    EchelleSprite(pixelBar, 2, 1)
    ;Debug "Angle Sprite = "+AngleSprite(pixelBar)+" Echelle X = "+SpriteEchelleX(pixelBar)+" Echelle Y = "+SpriteEchelleY(pixelBar)
    
    ;créer des sprites déformés
    formeLisse=CreerSpriteAnime(#PB_Any, coucheLisse, 200, 150, frameRouge)
    DeformerSprite(formeLisse, -16, 0, 16, 0, 8, 0, -8, 0)
    pixelShape=CreerSpriteAnime(#PB_Any, pixelCouche, 224, 153, frameRouge)
    FausserSprite(pixelShape, 32, 0)
    
    ;créer des sprites colorisés et retournés
    txt=CreerSpriteAnime(#PB_Any, coucheLisse, 100+30, 300, frameTexte)
    DefinirCouleurSprite(txt, RGB(255, 214, 126))
    txtX=CreerSpriteAnime(#PB_Any, coucheLisse, 100+30, 300, frameTexte)
    RetournerSprite(txtX, #True, #False)
    DefinirTransparenceSprite(txtX, 150)
    ;Debug "Tranparence Sprite = "+TransparenceSprite(txtX)
    txtY=CreerSpriteAnime(#PB_Any, coucheLisse, 100+30, 300, frameTexte)
    RetournerSprite(txtY, #False, #True)
    DefinirCouleurSprite(txtY, RGB(255, 14, 126), 0)
    DefinirCouleurSprite(txtY, RGB(255, 14, 126), 2)
    ;Debug "Pos Sprite  = "+SpriteX(txtY)+","+SpriteX(txtY)+" Couleur = "+Hex(couleurSprite(txtY, 2))
    txtBoth=CreerSpriteAnime(#PB_Any, coucheLisse, 100+30, 300, frameTexte)
    RetournerSprite(txtBoth, #True, #True)
    DefinirTransparenceSprite(txtBoth, 50, 0)
    DefinirTransparenceSprite(txtBoth, 50, 2)
    ;Debug "Sprite  retouné X = "+Bool(EtatSprite(txtBoth)& #Sprite_RetournerX)+" retourné Y = "+Bool(EtatSprite(txtBoth)& #Sprite_RetournerY)
  EndIf
  
  
  Repeat
    RenduSprites()
    RenderWorld()
    FlipBuffers()
  Until WaitWindowEvent(1)=#PB_Event_CloseWindow
  End
CompilerEndIf
Dernière modification par Micoute le dim. 24/juin/2018 13:48, modifié 1 fois.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Ekim
Messages : 215
Inscription : dim. 24/juin/2018 1:20

Re: Position sprite

Message par Ekim »

Wouah, merci Micoute@ pour ce morceau de code si je puis dire))
avec mon faible niveau je pense que j'aurais besoin d'une douzaine de jours pour pouvoir tout comprendre)))

donc en gros il ne faut pas hésiter à créer la structure du sprite

mon projet est plutôt simple j'aimerais en fait faire déplacer un sprite du point x1 y1 jusqu'au point x2 y2

en tout cas je vous remercie pour votre aide, c'est très sympa Fig@ ;)
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Position sprite

Message par Micoute »

Ce forum étant fait pour l'entraide entre programmeurs en PureBasic, il est donc tout naturel que je participe aussi et j'ai été bien content et reconnaissant, moi aussi d'avoir une aide charitable quand j'en ai eut besoin et je pense encore en avoir besoin dans le futur.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
Ar-S
Messages : 9472
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Position sprite

Message par Ar-S »

@Micoute.. les balises codes STP.

Salut Ekim et bienvenue.

A mon humble avis tu devrais commencer tranquillement avec le code de Fig.
Tu ne transformes rien en "objet" en 2D.
Ton sprite est une entité qui a une taille L et H sur une position X et Y dans un écran qui a une taille X et Y (ça tombe bien ;))
En gros tu as un sprite avec une largeur que tu peux connaitre via SpriteWidth(); la hateur via SpriteHeight()
l'affichage de ton sprite se fait via displaysprite(x, y, etc etc))
il te suffit de modifier x et y pour deplacer ton sprite.

La position x0 et y0 est en haut à gauche (pour l'ecran ou pour ton sprite).

Ton avant dans ta boucle événementielle (repeat/until) tu positionnes ton sprite.
Et ensuite, dans cette même boucle, tu imposes un changement de coordonnées via (par exemple) les flèches de ton clavier puis tu affiches ton sprites.
Regardes les exemples de la doc. Ils sont parlant.

Tu peux aussi regarde une petite intro que j'ai fait qui te permet de déplacer une chouette animée.
https://www.purebasic.fr/french/viewtop ... ny#p198796
~~~~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
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Position sprite

Message par Micoute »

Balises posées en bonnes et dues formes.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Ekim
Messages : 215
Inscription : dim. 24/juin/2018 1:20

Re: Position sprite

Message par Ekim »

Merci pour le conseil @Ar-S que je vais suivre à la lettre en tout cas)
j’étudirais le tronçon de code de @Micoute au fur et à mesure de mon apprentissage


mais c'est très encouragent une telle aide encore merci à tous ;)
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Position sprite

Message par Micoute »

Un petit programme d'exemple pour avancer plus vite dans l'apprentissage.

Code : Tout sélectionner

XIncludeFile "Moteur Sprite.pbi" ;Indiquer ici le chemin du fichier à inclure

DisableExplicit
If InitEngine3D()=0 Or InitMoteurSprite()=0
  MessageRequester("Init", "Echoué!")
  End
EndIf

AntialiasingMode(#PB_AntialiasingMode_None)

Fenetre_principale=OpenWindow(#PB_Any, 0, 0, 800, 600, "Moteur Sprite FX", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(Fenetre_principale), 0, 0, WindowWidth(Fenetre_principale), WindowHeight(Fenetre_principale))

;dessiner image atlas
fontID=LoadFont(0, "Arial", 22, #PB_Font_Bold|#PB_Font_HighQuality|#PB_Font_Italic)
spriteAtlas=CreerAtlas(#PB_Any, 160, 128)
If StartDrawing(SortieAtlas(spriteAtlas))
  
  DrawingMode(#PB_2DDrawing_Transparent|#PB_2DDrawing_AlphaBlend)
  DrawingFont(fontID)
  Texte.s = "MICOUTE"
  DrawText(25, 10, Texte, RGBA(255, 255, 255, 255))
  largeurTxt=TextWidth(Texte)
  hauteurTxt=TextHeight(Texte)
  
  DrawingMode(#PB_2DDrawing_Gradient|#PB_2DDrawing_AlphaBlend)
  BackColor(RGBA(255, 255, 0, 255))
  GradientColor(0.8, RGBA(255, 0, 0, 50))
  FrontColor(RGBA(200, 70, 10, 255))
  LinearGradient(0, 0, 0, 64)
  Box(5, 5, 16, 64)
  
  ResetGradientColors()
  BackColor(RGBA(0, 255, 0, 255))
  GradientColor(0.8, RGBA(0, 0, 255, 50))
  FrontColor(RGBA(60, 100, 255, 255))
  LinearGradient(0, 0, 64, 0)
  Box(21, 69, 64, 16)
  
  ResetGradientColors()
  BackColor(RGBA(255, 255, 255, 255))
  GradientColor(0.6, RGBA(150, 150, 150, 255))
  FrontColor(RGBA(255, 255, 255, 255))
  LinearGradient(25, 53, 30, 70)
  For i=0 To 7
    RoundBox(25 + (i*20), 45, 16, 16, 7, 4)
  Next
  
  DrawingMode(#PB_2DDrawing_Outlined|#PB_2DDrawing_AlphaBlend)
  FrontColor(RGBA(255, 255, 255, 255))
  Box(5, 5, 16, 64)
  Box(21, 69, 64, 16)
  ;Box(0, 0, 159, 128)
  StopDrawing()
EndIf
;extraire frames image
frameRouge=DefinirFrameAtlas(spriteAtlas, #PB_Any, 5, 5, 16, 64)
frameBleue=DefinirFrameAtlas(spriteAtlas, #PB_Any, 21, 69, 64, 16, 32, 8, #True)
frameTexte=DefinirFrameAtlas(spriteAtlas, #PB_Any, 25, 10, largeurTxt, hauteurTxt)

;créer une vue d'arrière plan
vueFond=CreerVue(#PB_Any, RGB(10, 10, 10))
If vueFond
  ;créer couches FX
  ajouterCoucheFX=CreerCouche(#PB_Any, vueFond, AtlasID(spriteAtlas), #PB_Material_Add, #PB_Material_None)
  CouleurCoucheFX=CreerCouche(#PB_Any, vueFond, AtlasID(spriteAtlas), #PB_Material_Color, #PB_Material_None)
  
  ;créer sprites FX (changement de couleur du sprite par défaut)
  DefinirCouleurSprite(#PB_Default, RGB(93, 137, 175), 2)
  For i=1 To 10
    CouleurFX=CreerSpriteAnime(#PB_Any, CouleurCoucheFX, 650, 50, frameRouge)
    EchelleSprite(CouleurFX, 1, 1 + (i*0.1))
    PivoterSprite(CouleurFX, -90 + (i*20))
  Next
  DefinirCouleurSprite(#PB_Default, RGB(93, 137, 175), 2)
  For i=1 To 10
    ajouterFX=CreerSpriteAnime(#PB_Any, ajouterCoucheFX, 650, 200, frameRouge)
    EchelleSprite(ajouterFX, 1, 1 + (i*0.1))
    PivoterSprite(ajouterFX, -90 + (i*20))
  Next
  DefinirCouleurSprite(#PB_Default, RGB(255, 255, 255))
EndIf

;créer vue premier plan
VuePP=CreerVue(#PB_Any, RGB(62, 62, 62), #False, 0, 0, 64.0, 85.34)
;Debug "Vue Caméra = "+VueCameraY(VuePP)+", "+VueCameraX(VuePP)+", "+LargeurCameraVue(VuePP)+", "+HauteurCameraVue(VuePP)
If VuePP
  ;créer des couches lissées et pixellisées
  coucheLisse=CreerCouche(#PB_Any, VuePP, AtlasID(spriteAtlas))
  pixelCouche=CreerCouche(#PB_Any, VuePP, AtlasID(spriteAtlas), #PB_Material_AlphaBlend, #PB_Material_None)
  
  ;réorganiser les couches et activer l'ombre
  DefinirOmbreCouche(coucheLisse, #True, RGB(0, 0, 0), 100, 5, 5)
  DefinirOrdreCouche(coucheLisse, 100, 90)
  DefinirOrdreCouche(pixelCouche, 80)
  
  ;créer sprites
  imageEntiere=CreerSpriteAnime(#PB_Any, pixelCouche, 5, 5, 0)
  barreRouge=CreerSpriteAnime(#PB_Any, pixelCouche, 10, 150, frameRouge)
  barreBleue=CreerSpriteAnime(#PB_Any, pixelCouche, 35, 182, frameBleue)
  
  ;créer des sprites pivotés et mis à l'échelle
  barreLisse=CreerSpriteAnime(#PB_Any, coucheLisse, 90, 190, frameBleue)
  PivoterSprite(barreLisse, -10)
  pixelBar=CreerSpriteAnime(#PB_Any, pixelCouche, 130, 190, frameBleue)
  PivoterSprite(pixelBar, -10)
  EchelleSprite(pixelBar, 2, 1)
  ;Debug "Angle Sprite = "+AngleSprite(pixelBar)+" Echelle X = "+SpriteEchelleX(pixelBar)+" Echelle Y = "+SpriteEchelleY(pixelBar)
  
  ;créer des sprites déformés
  formeLisse=CreerSpriteAnime(#PB_Any, coucheLisse, 200, 150, frameRouge)
  DeformerSprite(formeLisse, -16, 0, 16, 0, 8, 0, -8, 0)
  pixelShape=CreerSpriteAnime(#PB_Any, pixelCouche, 224, 153, frameRouge)
  FausserSprite(pixelShape, 32, 0)
  
  ;créer des sprites colorisés et retournés
  txt=CreerSpriteAnime(#PB_Any, coucheLisse, 130, 300, frameTexte)
  DefinirCouleurSprite(txt, RGB(255, 214, 126))
  txtX=CreerSpriteAnime(#PB_Any, coucheLisse, 130, 300, frameTexte)
  RetournerSprite(txtX, #True, #False)
  DefinirTransparenceSprite(txtX, 150)
  ;Debug "Tranparence Sprite = "+TransparenceSprite(txtX)
  txtY=CreerSpriteAnime(#PB_Any, coucheLisse, 130, 300, frameTexte)
  RetournerSprite(txtY, #False, #True)
  DefinirCouleurSprite(txtY, RGB(255, 14, 126), 0)
  DefinirCouleurSprite(txtY, RGB(255, 14, 126), 2)
  ;Debug "Pos Sprite  = "+SpriteX(txtY)+","+SpriteX(txtY)+" Couleur = "+Hex(couleurSprite(txtY, 2))
  les2Txt=CreerSpriteAnime(#PB_Any, coucheLisse, 130, 300, frameTexte)
  RetournerSprite(les2Txt, #True, #True)
  DefinirTransparenceSprite(les2Txt, 50, 0)
  DefinirTransparenceSprite(les2Txt, 50, 2)
  ;Debug "Sprite  retouné X = "+Bool(EtatSprite(les2Txt)& #Sprite_RetournerX)+" retourné Y = "+Bool(EtatSprite(les2Txt)& #Sprite_RetournerY)
EndIf


Repeat
  RenduSprites()
  RenderWorld()
  FlipBuffers()
Until WaitWindowEvent(1)=#PB_Event_CloseWindow
End
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
Ar-S
Messages : 9472
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Position sprite

Message par Ar-S »

Voilà un exemple tiré de la doc que j'ai complété et commenté.

Code : Tout sélectionner

; Les énumérations sont pratiques lorsque tu n'as pas un grand nombre de sprites/gadget etc...
Enumeration
  #MonSprite
  #MonSprite2
EndEnumeration



If InitKeyboard() = 0 Or InitSprite() = 0
  MessageRequester("Error", "Can't initialize the sprite system.", 0)
  End
EndIf

MessageRequester("Information", "Press 'ESC' To quit!", 0)


; Une procédure permet d'être appelé plusieurs fois dans ton code, ça te simplifiera grandement la tache
Procedure CreationSprite(ID_DuSprite)
  ;On crée un sprite vide de 100 x100
  CreateSprite(ID_DuSprite,100,100)
  ; On va dessiner dedans
  StartDrawing(SpriteOutput(ID_DuSprite))
  ; dessinons un dégradé
  DrawingMode(#PB_2DDrawing_Gradient)      
  BackColor(RGB(255,255,255))
  FrontColor(RGB(0,0,255))     
  CircularGradient(50, 50, 50)     
  Circle(50, 50, 50)
  CircularGradient(350, 100, 75)
  Circle(300, 100, 100)
  StopDrawing()
EndProcedure



If OpenScreen(800, 600, 32, "Keyboard + 2D")
  
  ; Initialisation des positions
  x = 100
  y = 100
  
  ; Creation du sprite grace à notre procédure
  CreationSprite(#MonSprite)
  ; L'intérêt de la procédure est que tu peux créer un autre sprite simplement
  CreationSprite(#MonSprite2)
  
  ; Boucle
  Repeat
  
    FlipBuffers()
    
    ClearScreen(RGB(0,0,0))
  
    ExamineKeyboard()
    
    ; Avec les touches du clavier, on ne touche pas au sprite, on change juste sa position
    If KeyboardPushed(#PB_Key_Left)
      x-3
    EndIf
  
    If KeyboardPushed(#PB_Key_Right)
      x+3
    EndIf
  
    If KeyboardPushed(#PB_Key_Up)
      y-3
    EndIf
  
    If KeyboardPushed(#PB_Key_Down)
      y+3
    EndIf
    
    ; On définit les limites en x pour ne pas qu'ils sortent de l'écran
    If x < 0 
      x = 0
    ElseIf x > 800-SpriteWidth(#Monsprite)
      x = 800-SpriteWidth(#Monsprite)
    EndIf
    ; Tu peux refaire de même avec y en remplaçant x par y, 800 par 600 et SpriteWidth() par Sprite Height
    
    
    
    ; Ensuite tu affiches
      DisplaySprite(#MonSprite, x, y)
      DisplaySprite(#MonSprite2, x, y+150)
     
  Until KeyboardPushed(#PB_Key_Escape)

Else
  MessageRequester("Error", "Impossible to open a 800*600 32 bit screen",0)
EndIf

End   
~~~~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
Ekim
Messages : 215
Inscription : dim. 24/juin/2018 1:20

Re: Position sprite

Message par Ekim »

Excellent l'exemple merci @Ar-s

et si j'ai envi d'envoyer un projectile d'un point A à un point B pendant que je déplace mon sprite via "ExamineKeyboard()", devrais-je créer un Thread obligatoirement?
Avatar de l’utilisateur
Ar-S
Messages : 9472
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Position sprite

Message par Ar-S »

Non, heureusement.
Tu fais bouger ton sprite projectile simplement plus vite (x+6 par exemple).
Et tu le fais commencer a la positipn du sprite qui tire + largeur projectile.
Pour ne pas te perdre tu peux creer 2 variables globales en debut de code.

Code : Tout sélectionner

VitesseVaisseau = 3
VitesseProj = 6

Ensuite dans ton code tu modifies x+3 en x+vitessevaiseau etc
On verra par la suite les structures qui clarifient aussi un peu le code.
~~~~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
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Position sprite

Message par falsam »

Bienvenu à bord Ekim.
Ekim a écrit :j'ai commencé très récemment à programmer en Pb
Ekim l'a précisé dans sa demande : Il débute avec PureBasic. Il est donc inutile de poster des codes à rallonges quand un utilisateur signale qu'il débute avec PureBasic.
Ekim a écrit :j'aimerais savoir comment peut on retrouver les coordonnées XY d'un sprite sur une surface "OpenWindowedScreen" s'il vous plait?
La demande est précise et demandait une réponse précise que Fig a apporté précisément.
Ekim a écrit :avec mon faible niveau je pense que j'aurais besoin d'une douzaine de jours pour pouvoir tout comprendre)))
Contrairement à moi, Ekim est diplomate :wink:

Je reviens sur ton dernier commentaire avec cette contribution commenté.
Ekim a écrit :mon projet est plutôt simple j'aimerais en fait faire déplacer un sprite du point x1 y1 jusqu'au point x2 y2

Code : Tout sélectionner

EnableExplicit

; Structure d'un vecteur 2D
Structure newVector
  x.f
  y.f
EndStructure

; Structure minimum d'un sprite
Structure newSprite
  id.i
  x.f
  y.f
EndStructure

;Definition du sprite
Global MySprite.newSprite

; Définition du point de départ et d'arrivée
Global A.newVector, B.newVector

; Définition de la distance et vitesse de déplacement
Global Distance.f, Speed.f = 60

; Déclaration du nombre d'iterations à effectuer pour aller du point A à B
Global n.f

; Déclaration des déplacements en x et y 
Global Dx.f, Dy.f

; Sommaire de l'application
Declare   Start()
Declare.d Distance(*p.Point, *q.Point)

Start()

Procedure Start()
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  OpenWindow(0, 0, 0, 0, 0, "FullScreen", #PB_Window_BorderLess | #PB_Window_Maximize)
  OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0), WindowHeight(0))
  
  ; Positionner le point de départ et d'arrivée
  A\x = 10
  A\y = 10
  
  B\x = 600
  B\y = 600
  
  ; Calculer la distance entre les vecteurs A et B
  Distance = Distance(A, B)
  
  ; En divisant la distance par la variable Speed on obtient une durée 
  ; Cette durée est matérialisé par le nombre "n" d'itérations à effectuer
  n = Sqr(Distance) / Speed
  
  ; Diviser la distance horizontale par le nombre d'itérations pour connaitre le déplacement à effectuer en x et y.
  Dx.f = (B\x - A\x) / N
  Dy.f = (B\y - A\y) / N
  
  ;Chargement du sprite (ici on prendra une image figurant dans les exemples de PureBasic)
  UsePNGImageDecoder()
  MySprite\id = LoadSprite(#PB_Any, #PB_Compiler_Home + "Examples\Sources\Data\world.png", #PB_Sprite_AlphaBlending) 
  MySprite\x = A\x
  MySprite\y = A\y
  
  Repeat
    Repeat : Until WindowEvent() = 0
    
    ClearScreen(RGB(255, 255, 255))
    
    ;Déplacer le sprite entre A et B
    DisplaySprite(MySprite\id, MySprite\x, MySprite\y)
    
    ;Calculer la nouvelle position du sprite
    If MySprite\y < B\x Or MySprite\y < B\y
      MySprite\x + Dx
      MySprite\y + Dy
    EndIf
    
    ExamineKeyboard()
    FlipBuffers()
  Until KeyboardReleased(#PB_Key_Escape)
EndProcedure

Procedure.d Distance(*p.Point, *q.Point)
  Protected Distance.d, dx.d, dy.d
  
  ;Distance horizontale
  dx = *p\x - *q\x   
  
  ;Distance verticale
  dy = *p\y - *q\y
  
  ;Théoréme de Pythagore
  Distance = Sqr(dx*dx + dy*dy )
  
  ProcedureReturn Distance
EndProcedure
Touche Escape pour quitter l'application.

:!: Précision importante : Le point d'ancrage (ou point de déplacement) d'un sprite est situé en haut à gauche du sprite.
Dernière modification par falsam le jeu. 28/juin/2018 17:30, modifié 1 fois.
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%
Ekim
Messages : 215
Inscription : dim. 24/juin/2018 1:20

Re: Position sprite

Message par Ekim »

Merci @falsam pour la pertinence de ta réponse, et désolé de n'avoir pu répondre avant car tourbillon de la vie oblige malheureusement(((
je vais de ce pat examiner ton bout de code, encore merci
Répondre