PureBasic:Souris et Sprite3D
PureBasic:Souris et Sprite3D
<< Précédent | Sommaire | Suivant >>
Sommaire |
[modifier] Introduction
Dans ce tut vous apprendrez à utiliser :
- La souris dans le mode plein écran.
- Les sprites 3D
- La rotation et le déplacement d'un sprite 3D.
[modifier] Initialisation
Ce tutoriel reprend le programme minimal déjà évoqué au cours du tutoriel Premiers pas avec PureBasic.
Puisqu'il s'agit cette fois ci d'utiliser la souris et les sprites 3D, ajoutons les lignes suivantes :
;Initialise l'environnement propre à la gestion de la souris. InitMouse() ;Initialise l'environnement propre à la gestion des sprites 3D. InitSprite3D()
Ce qui donne
;Initialise l'environnement nécessaire au fonctionnement des sprites et pour ouvrir un écran.
InitSprite()
;Initialise l'environnement propre à la gestion du clavier.
InitKeyboard()
;Initialise l'environnement propre à la gestion de la souris.
InitMouse()
;Initialise l'environnement propre à la gestion des sprites 3D.
InitSprite3D()
;Ouvre un nouvel écran avec les caractéristiques Largeur, Hauteur et Profondeur.
OpenScreen(800,600,32,"Tut Sprite3D et Souris")
Repeat
;Inverse le buffer d'arrière plan avec le buffer visible à l'écran.
;La partie invisible du buffer remplace alors complètement La partie visible.
FlipBuffers()
;Efface l'écran courant avec la couleur specifiée.
ClearScreen(0,0,100)
;Met à jour l'état du clavier.Cette fonction doit être appelée avant d'utiliser les commandes
;KeyboardInkey(), KeyboardPushed() et KeyboardReleased().
ExamineKeyboard()
Until KeyboardPushed(#PB_Key_Escape)
[modifier] La souris
Dans le mode plein écran , il est nécessaire d'utiliser un sprite pour visualiser la souris.
On pourrait charger un sprite représentant la flèche traditionnelle , ou n'importe quelle autre forme , mais pour cet exemple nous n'utiliserons pas de média .
;Sprite pour la souris CreateSprite(1,5,5) StartDrawing(SpriteOutput(1)) Box(0,0,5,5,RGB(0,255,0)) StopDrawing()
ensuite il suffit de tester la position de la souris dans la boucle principale du programme avec les fonctions ExamineMouse(), MouseX() et MouseY().
If ExamineMouse() Destination\x = MouseX() Destination\y = MouseY() EndIf
[modifier] Sprite 3D
Un sprite 3D est un simple rectangle sur lequel on applique une texture. La texture est en fait un sprite classique chargé avec LoadSprite() ou CreateSprite() en utilisant le mode #PB_Sprite_Texture.
;Creation d'une texture CreateSprite(0,64,64,#PB_Sprite_Texture) ;On dessine un triangle plein dans la texture StartDrawing(SpriteOutput(0)) LineXY(1, 1, 1, SpriteHeight(0)-2,RGB(255,255,0)) LineXY(1, 1, SpriteWidth(0)-2, SpriteHeight(0)/2,RGB(255,255,0)) LineXY(1, SpriteHeight(0)-2, SpriteWidth(0)-2, SpriteHeight(0)/2,RGB(255,255,0)) FillArea(SpriteWidth(0)/2,SpriteHeight(0)/2,RGB(255,255,0),RGB(255,155,0)) StopDrawing() ;Creation d'un sprite3D utilisant la texture définie précédemment CreateSprite3D(0,0)
Il est bien sûr possible de charger un sprite pour servir de texture au sprite3D.
il suffit de remplacer
;Creation d'une texture CreateSprite(0,64,64,#PB_Sprite_Texture)
par
;Charge une texture LoadSprite(0,"NomDeLaTexture.Bmp")
Rappel : L'image peut être au format BMP , JPEG, TIFF, PNG ou TGA (voir ImagePlugin)
Maintenant que notre sprite 3D est créé, il reste à l'afficher à l'écran aux coordonnées de la souris. Il faut activer le moteur 3D par la commande Start3D() , Stop3D() indique que le traitement des sprites 3D est terminé.
If ExamineMouse()
If Start3D()
DisplaySprite3D(0, MouseX(), MouseY())
Stop3D()
EndIf
EndIf
[modifier] Programme de base
On obtient enfin un sprite 3D qui se déplace à l'écran .
;Initialise l'environnement nécessaire au fonctionnement des sprites et pour ouvrir un écran.
InitSprite()
;Initialise l'environnement propre à la gestion du clavier.
InitKeyboard()
;Initialise l'environnement propre à la gestion de la souris.
InitMouse()
;Initialise l'environnement propre à la gestion des sprites 3D.
InitSprite3D()
;Ouvre un nouvel écran avec les caractéristiques Largeur, Hauteur et Profondeur.
OpenScreen(800,600,32,"Tut Sprite3D et Souris")
;Creation d'une texture
CreateSprite(0,64,64,#PB_Sprite_Texture)
;On dessine un triangle plein dans la texture
StartDrawing(SpriteOutput(0))
LineXY(1, 1, 1, SpriteHeight(0)-2,RGB(255,255,0))
LineXY(1, 1, SpriteWidth(0)-2, SpriteHeight(0)/2,RGB(255,255,0))
LineXY(1, SpriteHeight(0)-2, SpriteWidth(0)-2, SpriteHeight(0)/2,RGB(255,255,0))
FillArea(SpriteWidth(0)/2,SpriteHeight(0)/2,RGB(255,255,0),RGB(255,155,0))
StopDrawing()
;Creation d'un sprite3D utilisant la texture définie précédemment
CreateSprite3D(0,0)
;Sprite pour la souris
CreateSprite(1,5,5)
StartDrawing(SpriteOutput(1))
Box(0,0,5,5,RGB(0,255,0))
StopDrawing()
Repeat
;Inverse le buffer d'arrière plan avec le buffer visible à l'écran.
;La partie invisible du buffer remplace alors complètement La partie visible.
FlipBuffers()
;Efface l'écran courant avec la couleur specifiée.
ClearScreen(0,0,100)
;Met à jour l'état du clavier.Cette fonction doit être appelée avant d'utiliser les commandes
;KeyboardInkey(), KeyboardPushed() et KeyboardReleased().
ExamineKeyboard()
If ExamineMouse()
If Start3D()
DisplaySprite3D(0, MouseX(), MouseY())
Stop3D()
EndIf
EndIf
;Affiche la souris
DisplaySprite(1, MouseX(), MouseY())
Until KeyboardPushed(#PB_Key_Escape)
[modifier] Un peu de math
On va s'efforcer ici d'améliorer le déplacement de notre sprite 3D. L'objectif est de déplacer le sprite 3D vers la souris , mais avec la vitesse propre du sprite.
Vitesse.f=3.0
- Sprite = Position du sprite 3D.
- Destination = Destination à atteindre pour le sprite 3D.
- Direction = Direction que le sprite 3D doit prendre pour rejoindre la destination (souris).
Structure Vecteur
x.f
y.f
EndStructure
Direction.Vecteur
Sprite.Vecteur
Destination.Vecteur
[modifier] Destination
On recopie la position de la souris dans destination.
;Destination
If ExamineMouse()
Destination\x = MouseX()
Destination\y = MouseY()
EndIf
[modifier] Direction
Nous connaissons deux points , la destination et la position du sprite , nous pouvons déterminer le vecteur direction entre ces deux points.
Le vecteur est ensuite normé ( norme du vecteur = 1 )
;Direction
Direction\x = Destination\x - Sprite\x
Direction\y = Destination\y - Sprite\y
Norme(@Direction)
Normalise un vecteur
Procedure Norme(*V.Vecteur)
Norme.f = Sqr(*V\x * *V\x + *V\y * *V\y)
If Norme <> 0
*V\x / Norme
*V\y / Norme
EndIf
EndProcedure
[modifier] Position sprite 3D
Si la distance entre le sprite 3D et la souris est inférieure à la vitesse du sprite 3D , c'est que la destination est atteinte , sinon on se déplace à la vitesse définie précédemment.
Procedure.f Distance(*p1.Vecteur, *p2.Vecteur)
ProcedureReturn Sqr((*p1\x - *p2\x) * (*p1\x - *p2\x) + (*p1\y - *p2\y) * (*p1\y - *p2\y))
EndProcedure
;Deplacement sprite
dist.f = Distance(@Destination, @Sprite)
If dist < Vitesse
Sprite\x + Direction\x * dist
Sprite\y + Direction\y * dist
Else
Sprite\x + Direction\x * Vitesse
Sprite\y + Direction\y * Vitesse
EndIf
[modifier] Rotation
Il nous reste à calculer l'angle de rotation du sprite 3D .
Procedure.f atan2f(y.f, x.f) !fld dword[p.v_y] !fld dword[p.v_x] !fpatan ProcedureReturn EndProcedure #RAD = 0.0175 Angle=atan2f(Direction\y, Direction\x) / #RAD
[modifier] Programme complet
; PB 3.94
Structure Vecteur
x.f
y.f
EndStructure
;Declare les procédures
Declare.f Distance(*p1.Vecteur, *p2.Vecteur)
Declare.f atan2f(y.f,x.f)
Declare Norme(*V.Vecteur)
;Initialise l'environnement nécessaire au fonctionnement des sprites et pour ouvrir un écran.
InitSprite()
;Initialise l'environnement propre à la gestion du clavier.
InitKeyboard()
;Initialise l'environnement propre à la gestion de la souris.
InitMouse()
;Initialise l'environnement propre à la gestion des sprites 3D.
InitSprite3D()
;Ouvre un nouvel écran avec les caractéristiques Largeur, Hauteur et Profondeur.
OpenScreen(800,600,32,"Tut Sprite3D et Souris")
;Déclaration des variables
Vitesse.f = 3
Direction.Vecteur
Sprite.Vecteur
Destination.Vecteur
#RAD = 0.0175
;Creation d'une texture
CreateSprite(0,64,64,#PB_Sprite_Texture)
;On dessine un triangle plein dans la texture
StartDrawing(SpriteOutput(0))
LineXY(1, 1, 1, SpriteHeight(0)-2,RGB(255,255,0))
LineXY(1, 1, SpriteWidth(0)-2, SpriteHeight(0)/2,RGB(255,255,0))
LineXY(1, SpriteHeight(0)-2, SpriteWidth(0)-2, SpriteHeight(0)/2,RGB(255,255,0))
FillArea(SpriteWidth(0)/2,SpriteHeight(0)/2,RGB(255,255,0),RGB(255,155,0))
StopDrawing()
;Creation d'un sprite3D utilisant la texture définie précédemment
CreateSprite3D(0,0)
;Sprite pour la souris
CreateSprite(1,5,5)
StartDrawing(SpriteOutput(1))
Box(0,0,5,5,RGB(0,255,0))
StopDrawing()
Repeat
;Inverse le buffer d'arrière plan avec le buffer visible à l'écran.
;La partie invisible du buffer remplace alors complètement La partie visible.
FlipBuffers()
;Efface l'écran courant avec la couleur specifiée.
ClearScreen(0,0,100)
;Met à jour l'état du clavier.Cette fonction doit être appelée avant d'utiliser les commandes
;KeyboardInkey(), KeyboardPushed() et KeyboardReleased().
ExamineKeyboard()
;Destination
If ExamineMouse()
Destination\x = MouseX()
Destination\y = MouseY()
EndIf
;Direction
Direction\x = Destination\x - Sprite\x
Direction\y = Destination\y - Sprite\y
Angle=atan2f(Direction\y, Direction\x) / #RAD
Norme(@Direction)
;Deplacement sprite
dist.f = Distance(@Destination, @Sprite)
If dist < Vitesse
Sprite\x + Direction\x * dist
Sprite\y + Direction\y * dist
Else
Sprite\x + Direction\x * Vitesse
Sprite\y + Direction\y * Vitesse
EndIf
;Affiche le sprite 3D
If Start3D()
DisplaySprite3D(0, Sprite\x, Sprite\y)
RotateSprite3D(0,Angle,0)
Stop3D()
EndIf
;Affiche la souris
DisplaySprite(1, Destination\x , Destination\y)
Until KeyboardPushed(#PB_Key_Escape)
End
Procedure.f Distance(*p1.Vecteur, *p2.Vecteur)
ProcedureReturn Sqr((*p1\x - *p2\x) * (*p1\x - *p2\x) + (*p1\y - *p2\y) * (*p1\y - *p2\y))
EndProcedure
Procedure Norme(*V.Vecteur)
Norme.f = Sqr(*V\x * *V\x + *V\y * *V\y)
If Norme <> 0
*V\x / Norme
*V\y / Norme
EndIf
EndProcedure
Procedure.f atan2f(y.f, x.f)
!fld dword[p.v_y]
!fld dword[p.v_x]
!fpatan
ProcedureReturn
EndProcedure
[modifier] Amélioration
Vous pouvez remplacer le triangle , par un sprite de voiture , et jouer sur la vitesse avec les touches gauche et droite de la souris.
;Destination
If ExamineMouse()
Destination\x = MouseX()
Destination\y = MouseY()
If MouseButton(1)
Vitesse + 0.2
ElseIf MouseButton(2) And Vitesse > 1
Vitesse - 0.2
EndIf
EndIf
[modifier] Mise à jour pour PureBasic 4.0
Comme vous devez sans doute déjà le savoir, PureBasic 4.0 apporte de nombreuses nouveautés mais aussi beaucoup de changements dans la façon d'écrire un code. Rassurez vous, pour adapter le code de ce tutoriel ça ne prend que quelques secondes, rien d'insurmontable.
Les changements dans ce code sont :
- ClearScreen(RGB(0,0,100)) : Désormais il n'y a plus qu'un paramètre couleur.
- La fonction assembleur Atan2() : Pour faciliter l'accès aux variables locales, une notation a été mise en place: 'p.v_NomVariable' pour une variable standard et 'p.p_NomPointeur' pour un pointeur.
J'ai profité de cette mise à jour pour ajouter quelques nouveautés :
- EnableExplicit : Force la déclaration des variables
- Define : Permet de définir des variables
- Remplacement de la procédure Distance() par la macro DISTANCE()
;PB 4.02 6 mai 2007
;Modification procédure ATAN2 !
EnableExplicit ; Force la déclaration de toutes les variables
Structure Vecteur
x.f
y.f
EndStructure
;Declare les procédures
Declare.f atan2f(y.f, x.f)
Declare Norme(*V.Vecteur)
;Initialise l'environnement nécessaire au fonctionnement des sprites et pour ouvrir un écran.
InitSprite()
;Initialise l'environnement propre à la gestion du clavier.
InitKeyboard()
;Initialise l'environnement propre à la gestion de la souris.
InitMouse()
;Initialise l'environnement propre à la gestion des sprites 3D.
InitSprite3D()
;Ouvre un nouvel écran avec les caractéristiques Largeur, Hauteur et Profondeur.
OpenScreen(800,600,32,"Tut Sprite3D et Souris")
;-Déclaration des variables
Define Angle, dist, Vitesse.f = 3
Define.Vecteur Direction, Sprite, Destination
Macro DISTANCE(p1, p2)
Sqr((p1\x - p2\x) * (p1\x - p2\x) + (p1\y - p2\y) * (p1\y - p2\y))
EndMacro
#RAD = 0.0175
;Creation d'une texture
CreateSprite(0,64,64,#PB_Sprite_Texture)
;On dessine un triangle plein dans la texture
StartDrawing(SpriteOutput(0))
LineXY(1, 1, 1, SpriteHeight(0)-2,RGB(255,255,0))
LineXY(1, 1, SpriteWidth(0)-2, SpriteHeight(0)/2,RGB(255,255,0))
LineXY(1, SpriteHeight(0)-2, SpriteWidth(0)-2, SpriteHeight(0)/2,RGB(255,255,0))
FillArea(SpriteWidth(0)/2,SpriteHeight(0)/2,RGB(255,255,0),RGB(255,155,0))
StopDrawing()
;Creation d'un sprite3D utilisant la texture définie précédemment
CreateSprite3D(0,0)
;Sprite pour la souris
CreateSprite(1,5,5)
StartDrawing(SpriteOutput(1))
Box(0,0,5,5,RGB(0,255,0))
StopDrawing()
Repeat
;Inverse le buffer d'arrière plan avec le buffer visible à l'écran.
;La partie invisible du buffer remplace alors complètement La partie visible.
FlipBuffers()
;Efface l'écran courant avec la couleur specifiée.
ClearScreen(RGB(0,0,100))
;Met à jour l'état du clavier.Cette fonction doit être appelée avant d'utiliser les commandes
;KeyboardInkey(), KeyboardPushed() et KeyboardReleased().
ExamineKeyboard()
;Destination
If ExamineMouse()
Destination\x = MouseX()
Destination\y = MouseY()
EndIf
;Direction
Direction\x = Destination\x - Sprite\x
Direction\y = Destination\y - Sprite\y
Angle=atan2f(Direction\y, Direction\x) / #RAD
Norme(@Direction)
;Deplacement sprite
dist = DISTANCE(Destination, Sprite)
If dist < Vitesse
Sprite\x + Direction\x * dist
Sprite\y + Direction\y * dist
Else
Sprite\x + Direction\x * Vitesse
Sprite\y + Direction\y * Vitesse
EndIf
;Affiche le sprite 3D
If Start3D()
DisplaySprite3D(0, Sprite\x, Sprite\y)
RotateSprite3D(0,Angle,0)
Stop3D()
EndIf
;Affiche la souris
DisplaySprite(1, Destination\x, Destination\y)
Until KeyboardPushed(#PB_Key_Escape)
End
Procedure Norme(*V.Vecteur)
Define.f Norme
Norme.f = Sqr(*V\x * *V\x + *V\y * *V\y)
If Norme
*V\x / Norme
*V\y / Norme
EndIf
EndProcedure
Procedure.f atan2f(y.f, x.f)
!fld dword[p.v_y]
!fld dword[p.v_x]
!fpatan
ProcedureReturn
EndProcedure

