Position sprite
Position sprite
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?
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?
Re: Position sprite
Bienvenue,
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.
Ici, tes coordonnées sont dans les variables x et y par exemple...
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
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
Version de PB : 6.00LTS - 64 bits
Re: Position sprite
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 ?
Re: Position sprite
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 !
Un homme doit être poli, mais il doit aussi être libre !
Re: Position sprite
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@
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@
Re: Position sprite
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 !
Un homme doit être poli, mais il doit aussi être libre !
Re: Position sprite
@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
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
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳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
Re: Position sprite
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 !
Un homme doit être poli, mais il doit aussi être libre !
Re: Position sprite
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
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
Re: Position sprite
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 !
Un homme doit être poli, mais il doit aussi être libre !
Re: Position sprite
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
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳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
Re: Position sprite
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?
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?
Re: Position sprite
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.
On verra par la suite les structures qui clarifient aussi un peu le code.
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
~~~~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
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳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
- falsam
- Messages : 7244
- Inscription : dim. 22/août/2010 15:24
- Localisation : IDF (Yvelines)
- Contact :
Re: Position sprite
Bienvenu à bord Ekim.
Je reviens sur ton dernier commentaire avec cette contribution commenté.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.
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'ai commencé très récemment à programmer en Pb
La demande est précise et demandait une réponse précise que Fig a apporté précisément.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?
Contrairement à moi, Ekim est diplomateEkim a écrit :avec mon faible niveau je pense que j'aurais besoin d'une douzaine de jours pour pouvoir tout comprendre)))
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
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%
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Re: Position sprite
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
je vais de ce pat examiner ton bout de code, encore merci