[RESOLU] (& meme + :))un sprite qui se déplace vers un autre
[RESOLU] (& meme + :))un sprite qui se déplace vers un autre
salut
Je cherche la technique pour faire qu'un sprite se déplace en ligne vers un autre.
Un exemple :
- un magicien lance une boule de feu vers un ennemi.
Je ne sais pas trop comment faire ça. J'ai réussi si ce n'est pas une ligne droite.
Merci
Je cherche la technique pour faire qu'un sprite se déplace en ligne vers un autre.
Un exemple :
- un magicien lance une boule de feu vers un ennemi.
Je ne sais pas trop comment faire ça. J'ai réussi si ce n'est pas une ligne droite.
Merci
Dernière modification par blendman le mer. 23/mars/2011 9:27, modifié 1 fois.
http://blendman.blogspot.com/
Forum PB fr : http://www.purebasic.fr/french - Forum PB Eng : http://www.purebasic.fr/english
Forum PB fr : http://www.purebasic.fr/french - Forum PB Eng : http://www.purebasic.fr/english
Re: un sprite qui se déplace vers un autre
Code : Tout sélectionner
; Cpl.Bator
; PureBasic 4.10
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
Structure point
x.f
y.f
EndStructure
CompilerEndIf
#SW=800
#SH=600
InitSprite() : InitKeyboard() : InitMouse()
OpenScreen(#SW,#SH,32,"")
;-Structures
Structure VECTOR2
x.f
y.f
EndStructure
Structure ENTITY
Position.VECTOR2
Angle.f
EndStructure
;-Declarations des fonctions
Declare DrawArrow(Lenght.l , x.f , y.f , Angle.f)
Declare.f curveangle(newangle.f,oldangle.f,increments.f)
Declare.f ReturnDegAngle(x1.f,y1.f,x2.f,y2.f)
Declare track_SmoothPoint(*A.ENTITY,*B.ENTITY, turnspeed.f=1.0)
; ************************************************************************************
#NB_ARROW = 3
Dim Arrow.ENTITY(#NB_ARROW)
For i = 1 To #NB_ARROW
Arrow(i)\Position\x = Random(#SW)
Arrow(i)\Position\y = Random(#SH)
Arrow(i)\Angle = 0
Next
; ************************************************************************************
; Cible des "arrow" , coordonées de la souris pour la position
Target.ENTITY
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
KeyboardMode(#PB_Keyboard_International)
CompilerEndIf
Repeat
ExamineMouse()
ExamineKeyboard()
ClearScreen(0)
Target\Position\x = MouseX()
Target\Position\y = MouseY()
StartDrawing(ScreenOutput())
Circle(Target\Position\x,Target\Position\y,2,255)
StopDrawing()
For i = 1 To #NB_ARROW
DrawArrow(50 , Arrow(i)\Position\x , Arrow(i)\Position\y , Arrow(i)\Angle)
track_SmoothPoint(Arrow(i),Target,20)
Arrow(i)\Position\x + 1 *Cos(Arrow(i)\Angle*#PI/180)
Arrow(i)\Position\y + 1 *Sin(Arrow(i)\Angle*#PI/180)
Next
If KeyboardPushed(#PB_Key_Escape)<>#Null : Quit=1 : EndIf
FlipBuffers()
Until Quit=1
End
Procedure.f curveangle(newangle.f,oldangle.f,increments.f)
If increments>1
If (oldangle+360)-newangle<newangle-oldangle
oldangle=360+oldangle
EndIf
If (newangle+360)-oldangle<oldangle-newangle
newangle=360+newangle
EndIf
oldangle=oldangle-(oldangle-newangle)/increments
EndIf
If increments<=1
ProcedureReturn newangle
EndIf
ProcedureReturn oldangle
EndProcedure
Procedure.f ReturnDegAngle(x1.f,y1.f,x2.f,y2.f) ; DEGREE
A.f = x1-x2
b.f = y1-y2
c.f = -Sqr(A*A+b*b)
Angle.f = ACos(A/c)*180/#PI
If y1 < y2 : Angle=360-Angle : EndIf
ProcedureReturn Abs(Angle - 360)
EndProcedure
Procedure track_SmoothPoint(*A.ENTITY,*B.ENTITY, turnspeed.f=1.0)
AngDif = ReturnDegAngle(*A\position\x,*A\position\y,*B\position\x,*B\position\y)
temp_yaw.f = curveangle(AngDif,*A\Angle,turnspeed)
*A\Angle = temp_yaw
EndProcedure
Procedure DrawArrow(Lenght.l , x.f , y.f , Angle.f)
Protected ArrowA.Point,ArrowB.Point
Protected ArrowBranchA.Point,ArrowBranchB.Point
ArrowA\x = x + (Lenght/2) * Cos(Angle*#PI/180)
ArrowA\y = y + (Lenght/2) * Sin(Angle*#PI/180)
ArrowB\x = x - (Lenght/2) * Cos(Angle*#PI/180)
ArrowB\y = y - (Lenght/2) * Sin(Angle*#PI/180)
ArrowBranchA\x = ArrowA\x - (Lenght/3) * Cos((Angle+45)*#PI/180)
ArrowBranchA\y = ArrowA\y - (Lenght/3) * Sin((Angle+45)*#PI/180)
ArrowBranchB\x = ArrowA\x - (Lenght/3) * Cos((Angle-45)*#PI/180)
ArrowBranchB\y = ArrowA\y - (Lenght/3) * Sin((Angle-45)*#PI/180)
StartDrawing(ScreenOutput())
LineXY(ArrowA\x,ArrowA\y,ArrowB\x,ArrowB\y,255)
LineXY(ArrowA\x,ArrowA\y,ArrowBranchA\x,ArrowBranchA\y,255)
LineXY(ArrowA\x,ArrowA\y,ArrowBranchB\x,ArrowBranchB\y,255)
Circle(x+1,y+1,2,255)
StopDrawing()
EndProcedure
-
- Messages : 1501
- Inscription : dim. 18/avr./2004 15:04
- Localisation : sud de la france
Re: un sprite qui se déplace vers un autre
G-rom donne Moi des cours pour crée un jeux ... tu es trop fort .
Jbernard13
Re: un sprite qui se déplace vers un autre
G-rom : merci pour ce code, il est très intéressant
.
Maintenant, je vais le simplifier pour que lorsque l'objet arrive sur la cible, il disparaisse, et aussi pour qu'il se déplace uniquement en ligne droite

Maintenant, je vais le simplifier pour que lorsque l'objet arrive sur la cible, il disparaisse, et aussi pour qu'il se déplace uniquement en ligne droite

http://blendman.blogspot.com/
Forum PB fr : http://www.purebasic.fr/french - Forum PB Eng : http://www.purebasic.fr/english
Forum PB fr : http://www.purebasic.fr/french - Forum PB Eng : http://www.purebasic.fr/english
Re: un sprite qui se déplace vers un autre
Sinon le principe est celui de l'équation de droite, pour laquelle il existe trente six algos.
Le plus simple à mon avis (donc mon préféré, celui dont je me sers pour les tests, et avant optim) : si tu as une variable u.f qui va de 0 à 1, et deux points A et B, tu obtiens ta trajectoire comme ça...
Enfantin, non ? 
Le plus simple à mon avis (donc mon préféré, celui dont je me sers pour les tests, et avant optim) : si tu as une variable u.f qui va de 0 à 1, et deux points A et B, tu obtiens ta trajectoire comme ça...
Code : Tout sélectionner
x = u * (xB - xA)
y = u * (yB - yA)

Re: un sprite qui se déplace vers un autre
c'est quoi cette variable u ? la vitesse ?djes a écrit :Sinon le principe est celui de l'équation de droite, pour laquelle il existe trente six algos.
Le plus simple à mon avis (donc mon préféré, celui dont je me sers pour les tests, et avant optim) : si tu as une variable u.f qui va de 0 à 1, et deux points A et B, tu obtiens ta trajectoire comme ça...Enfantin, non ?Code : Tout sélectionner
x = u * (xB - xA) y = u * (yB - yA)
Que dois-je faire si je veux que le sprite aille de A à B en ligne droite ? (en s'arrêtant à B)

EDIT : bon, j'ai testé ce code, normalement, ça devrait marcher :
(block() est une liste)
\vitese = 0 à la création de l'élément de la liste.
Code : Tout sélectionner
With block()
If \vitesse <=1
\position\x + \vitesse * (\cible\x - \position\x)
\position\y + \vitesse * (\cible\y - \position\y)
\vitesse +0.1
EndIf
endif
http://blendman.blogspot.com/
Forum PB fr : http://www.purebasic.fr/french - Forum PB Eng : http://www.purebasic.fr/english
Forum PB fr : http://www.purebasic.fr/french - Forum PB Eng : http://www.purebasic.fr/english
Re: un sprite qui se déplace vers un autre
La vitesse, non, c'est plutôt la position entre A et B. À 0, tu es sur A, à 1, tu es sur B, à 0.5, tu es au milieu. Dans ton exemple, la vitesse est conditionnée par le 0.1, et elle varie suivant la distance entre A et B ; c'est pour ça que tu ne peux simplement utiliser cette formule si tu veux que la vitesse soit constante quels que soient les points de départ et d'arrivée.
Re: un sprite qui se déplace vers un autre
il te manque quelques notions sur les vecteurs.
voici un petit code commenté de quoi t'éclairer sur le sujet , c'est la base.
@+
voici un petit code commenté de quoi t'éclairer sur le sujet , c'est la base.
@+
Code : Tout sélectionner
Structure Vector2
x.f
y.f
EndStructure
A.Vector2
B.Vector2
; Départ
A\x = 100
A\y = 100
;Arrivé
B\x = 650
B\y = 1450
;Direction
Direction.Vector2
; La direction se calcul entre soustrayant l'arrivé du départ
Direction\x = B\x - A\x
Direction\y = B\y - A\y
; Calcul de la longueur du vecteur Direction
Longueur.f = Sqr( Direction\x * Direction\x + Direction\y * Direction\y )
; Normalise le vecteur Direction ( Vecteur entre 0 & 1 )
If Longueur > 0
Direction\x = Direction\x / Longueur
Direction\y = Direction\y / Longueur
EndIf
; Calcul de la nouvelle position :
vitesse.f = 3.5 ; Amuse toi à changer la valeur
NouvellePosition.Vector2
NouvellePosition\x = A\x + (Direction\x * vitesse)
NouvellePosition\y = A\y + (Direction\y * vitesse)
Debug "Depart en 100x100"
Debug ""
Debug "Vitesse = "+StrF(vitesse)
Debug ""
Debug "Nouveau X = " +StrF(NouvellePosition\x)
Debug "Nouveau Y = " +StrF(NouvellePosition\y)
Re: un sprite qui se déplace vers un autre
salut G-romG-Rom a écrit :il te manque quelques notions sur les vecteurs. voici un petit code commenté de quoi t'éclairer sur le sujet , c'est la base.
Effectivement, il me manque beaucoup de notions sur les vecteurs (disons que je les ai oublié).
Merci pour ton exemple, je vais le regarder et l'étudier de prêt, histoire de voir comment cela fonctionne

j'ai enlevé la vitesse qui augmente et j'ai changé un paramètre (le previous\x et \y) et maintenant la vitesse est constantedjes a écrit :La vitesse, non, c'est plutôt la position entre A et B. À 0, tu es sur A, à 1, tu es sur B, à 0.5, tu es au milieu. Dans ton exemple, la vitesse est conditionnée par le 0.1, et elle varie suivant la distance entre A et B ; c'est pour ça que tu ne peux simplement utiliser cette formule si tu veux que la vitesse soit constante quels que soient les points de départ et d'arrivée.

Finalement, je suis moins une quiche que je ne le pensais lol.
Le code (ce qui a changé):
Code : Tout sélectionner
If ListSize(block()) <> 0
For i =0 To ListSize(block())-1
If SelectElement(block(), i)
block()\position\x + (block()\vitesse * (block()\cible\x - block()\previous\x))/100
block()\position\y + (block()\vitesse * (block()\cible\y - block()\previous\y))/100
EndIf
EndIf
ChangeCurrentElement(block(),i)
Code : Tout sélectionner
;{******************** infos ******************
; code release mouse : netmaestro
; le reste : ben, moi :)
; pb : 4.51
; déplacement de personnage (un clic and go de base) et lançage de sorts à la volée :)
;}
;{ ************************enumeration ***********************
Enumeration
#window
#player
#block
EndEnumeration
#ScreenW = 800
#ScreenH = 600
;}
;{ ************************ variables ************************
Global vitesse= 3
Global inscreen = 1
Global mouseClic = 0
ShowCursor_(1)
;}
;{ ************************ Structures ************************
Structure s_block
name.s
position.Point
previous.Point
vitesse.f
cible.Point
cible_ok.i
sprite.i
EndStructure
Global NewList block.s_block()
Global Dim player.s_block(0)
player(0)\name = "player"
player(0)\position\x = 15
player(0)\position\y = 15
player(0)\previous\x = 15
player(0)\previous\y = 15
player(0)\vitesse = 3
player(0)\cible\x=15
player(0)\cible\y=15
player(0)\sprite = #player
player(0)\cible_ok=0
;}
;{ ************************ declare ***************************
Declare gestion_souris()
Declare evenementClavier()
Declare Player_move()
Declare affichage()
Declare instance_create()
Declare Sort_move()
;}
;{ ************************ inititialisation *****************
InitKeyboard ()
InitSprite()
InitSprite3D()
InitMouse()
UsePNGImageDecoder()
;}
;{ ************************ open window *********************
OpenWindow(#window, 0, 0,#ScreenW, #ScreenH, "Collision" , #PB_Window_SystemMenu|#PB_Window_BorderLess |#PB_Window_ScreenCentered )
OpenWindowedScreen( WindowID (#window),0,0, 800,600, 1, 0,0)
;}
;{ ************************ sprite et loading ***************
LoadSprite(#player,"col.png")
LoadSprite(#block,"blockCollision.png")
TransparentSpriteColor(#player,RGB(255,0,0))
TransparentSpriteColor(#block,RGB(255,0,0))
;}
;{ ************************ boucle principale ***************
Repeat
Event= WindowEvent ()
ExamineKeyboard ()
ExamineMouse()
gestion_souris()
affichage()
evenementClavier()
Player_move()
instance_create()
Sort_move()
; With block()
; If SpritePixelCollision(#player,player(0)\position\x,player(0)\position\y,#block,\position\x,\position\y)
; player(0)\vitesse =0
; player(0)\position\x = \previous\x
; player(0)\position\y = \previous\y
; Else
; player(0)\vitesse = 3
; EndIf
; EndWith
FlipBuffers ()
ClearScreen (RGB (125,125,125))
Until Event= #PB_Event_CloseWindow Or KeyboardPushed ( #PB_Key_Escape )
;}
Procedure evenementClavier()
If KeyboardPushed ( #PB_Key_Up )
ForEach block()
With block()
If \name = "player"
\previous\y = \position\y
\position\y - \vitesse
EndIf
EndWith
Next
EndIf
If KeyboardPushed ( #PB_Key_Down )
ForEach block()
With block()
If \name = "player"
\previous\y = \position\y
\position\y + \vitesse
EndIf
EndWith
Next
EndIf
If KeyboardPushed ( #PB_Key_Left )
ForEach block()
With block()
If \name = "player"
\previous\x = \position\x
\position\x - \vitesse
EndIf
EndWith
Next
EndIf
If KeyboardPushed ( #PB_Key_Right )
ForEach block()
With block()
If \name = "player"
\previous\x = \position\x
\position\x +\vitesse
EndIf
EndWith
Next
EndIf
EndProcedure
Procedure Player_move()
If MouseButton(#PB_MouseButton_Left) =1
player(0)\cible_ok = 1
player(0)\cible\x = MouseX()
player(0)\cible\y = MouseY()
EndIf
With player(0)
If \cible_ok = 1 And \name = "player"
If \position\x < \cible\x
\position\x + \vitesse
ElseIf \position\x > \cible\x
\position\x - \vitesse
EndIf
If \position\y < \cible\y
\position\y + \vitesse/2
ElseIf \position\y > \cible\y
\position\y - \vitesse/2
EndIf
EndIf
EndWith
EndProcedure
Procedure instance_create()
If MouseButton(#PB_MouseButton_Right) =1 And mouseClic = 0
mouseClic = 1
vitesseSort = 0
;ClearList(block())
AddElement(block())
With block()
\name = "block"
\cible\x = MouseX()
\cible\y = MouseY()
\position\x = player(0)\position\x
\position\y = player(0)\position\y
\previous\x = player(0)\position\x
\previous\y = player(0)\position\y
\sprite = #block
\vitesse = 2
EndWith
nbre_element = ListSize(block())
ElseIf MouseButton(#PB_MouseButton_Right) =0
mouseClic = 0
EndIf
EndProcedure
Procedure gestion_souris()
mx = WindowMouseX(#window):my = WindowMouseY(#window)
If inscreen = 1
If mx> #ScreenW-2 Or my> #ScreenH-2 Or mx<1 Or my<1
inscreen = 0
ReleaseMouse(1)
EndIf
ElseIf mx <#ScreenW-1 And my < #ScreenH-1 And mx > 0 And my > 0
ReleaseMouse(0)
MouseLocate(mx,my)
inscreen = 1
EndIf
EndProcedure
Procedure Sort_move()
If ListSize(block()) <> 0
For i =0 To ListSize(block())-1
If SelectElement(block(), i)
block()\position\x + (block()\vitesse * (block()\cible\x - block()\previous\x))/100
block()\position\y + (block()\vitesse * (block()\cible\y - block()\previous\y))/100
EndIf
ChangeCurrentElement(block(),i)
Next
EndIf
EndProcedure
Procedure affichage()
DisplayTransparentSprite(player(0)\sprite, player(0)\position\x, player(0)\position\y)
ForEach block()
DisplayTransparentSprite(block()\sprite, block()\position\x, block()\position\y)
Next
EndProcedure
http://blendman.blogspot.com/
Forum PB fr : http://www.purebasic.fr/french - Forum PB Eng : http://www.purebasic.fr/english
Forum PB fr : http://www.purebasic.fr/french - Forum PB Eng : http://www.purebasic.fr/english
Re: un sprite qui se déplace vers un autre
Manque juste un lien sur les fichiers de sprite et ça pourra compiler... 

Only PureBasic makes it possible
Re: un sprite qui se déplace vers un autre
les 2 sprites, c'est juste 2 bêtes losanges (n'importe quel sprite irait en faitCool Dji a écrit :Manque juste un lien sur les fichiers de sprite et ça pourra compiler...

mais les voici :


http://blendman.blogspot.com/
Forum PB fr : http://www.purebasic.fr/french - Forum PB Eng : http://www.purebasic.fr/english
Forum PB fr : http://www.purebasic.fr/french - Forum PB Eng : http://www.purebasic.fr/english
Re: un sprite qui se déplace vers un autre
Ben kektafoutu ?
ça se déplace pas en ligne droite !!
C'est plus compliqué en ligne droite
Faut reprendre le code de G-Rom.
A moins que tu souhaites garder ce type de déplacement, mais les déplacements vont pas être réalistes, surtout quand tu vas introduire des obstacles à éviter...
ça se déplace pas en ligne droite !!
C'est plus compliqué en ligne droite

Faut reprendre le code de G-Rom.
A moins que tu souhaites garder ce type de déplacement, mais les déplacements vont pas être réalistes, surtout quand tu vas introduire des obstacles à éviter...
Only PureBasic makes it possible
Re: un sprite qui se déplace vers un autre
heu, c'est le sort qu'il faut regarder (clic droit, le losange rouge) pas le le losange bleuCool Dji a écrit :Ben kektafoutu ?
ça se déplace pas en ligne droite !!
C'est plus compliqué en ligne droite![]()
Faut reprendre le code de G-Rom.
A moins que tu souhaites garder ce type de déplacement, mais les déplacements vont pas être réalistes, surtout quand tu vas introduire des obstacles à éviter...

http://blendman.blogspot.com/
Forum PB fr : http://www.purebasic.fr/french - Forum PB Eng : http://www.purebasic.fr/english
Forum PB fr : http://www.purebasic.fr/french - Forum PB Eng : http://www.purebasic.fr/english
Re: un sprite qui se déplace vers un autre
Wouai, bon ça va
En revanche, ya un truc à améliorer : la vitesse de déplacement du sort est proportionnelle à l'éloignement de la cible par rapport au lancer => c'est pas bon, ça !!


En revanche, ya un truc à améliorer : la vitesse de déplacement du sort est proportionnelle à l'éloignement de la cible par rapport au lancer => c'est pas bon, ça !!
Only PureBasic makes it possible
Re: un sprite qui se déplace vers un autre
oui, je sais c'est ce que j'essaie de corrigerCool Dji a écrit :Wouai, bon ça va![]()
![]()
En revanche, ya un truc à améliorer : la vitesse de déplacement du sort est proportionnelle à l'éloignement de la cible par rapport au lancer => c'est pas bon, ça !!


Si tu as une idée, je suis preneur

EDIT : je suis en train d'essayer d'intégrer l'exemple de G-rom pour voir si j'ai bien tout compris

http://blendman.blogspot.com/
Forum PB fr : http://www.purebasic.fr/french - Forum PB Eng : http://www.purebasic.fr/english
Forum PB fr : http://www.purebasic.fr/french - Forum PB Eng : http://www.purebasic.fr/english