[RESOLU] (& meme + :))un sprite qui se déplace vers un autre

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: un sprite qui se déplace vers un autre

Message par G-Rom »

tu regardes pas les codes que je poste ou quoi ?
je t'ai fait un exemple , avec des vecteurs qui règle se problème...

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 = 20000
B\y = 20000

;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 

Debug Direction\x
Debug Direction\y

change
B\x = 20000
B\y = 20000
avec 200 , ton débugger te sortira la meme valeur.
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: un sprite qui se déplace vers un autre

Message par blendman »

G-Rom a écrit :tu regardes pas les codes que je poste ou quoi ?
Mais si puisque j'ai écrit :
"je suis en train d'essayer d'intégrer l'exemple de G-rom pour voir si j'ai bien tout compris "

Par contre, avant tout, je préfère essayer de comprendre au mieux l'exemple, même si je dois tâtonner un peu. parce que juste recopier bêtement un code sans le comprendre, ça ne sert pas à grand chose (enfin, des fois c'est utile, c'est sûr) :)

Je suis en train de corriger mon fichier, donc, je dois l'adapter ;)
Avatar de l’utilisateur
Cool Dji
Messages : 1126
Inscription : ven. 05/sept./2008 11:42
Localisation : Besançon
Contact :

Re: un sprite qui se déplace vers un autre

Message par Cool Dji »

vi,

Je redis que la manière la plus efficace est celle présentée par G-Rom...avec une nécessaire prise en compte des angles...
à moins de lancer des objets uniquement en vertical et horizontal

Sinon, réfléchis à ce principe :
Calcul la longueur totale de déplacement.
Divise cette longueur par la vitesse de déplacement du sort par boucle
Tu obtiens le nombre de boucle nécessaire pour que le sort atteigne la cible avec une vitesse constante

Ex : Distance entre lanceur et cible : 100 pixels
le sort se déplace avec une vitesse de 5 pixels par boucle (cycle).
Il faudra donc 20 cycles au sort pour atteindre sa cible.
Il faut donc calculer un deltaX et un deltaY au lancement du sort et tu mets à jour les positions X et Y pendant 20 cycles.

Le code de G-Rom doit recalculer les X et Y à chaque boucle. ça permet de prendre en compte des déplacements de la cible (ex missile à tete chercheuse). Mais tu peux l'utiliser pour calculer tes Deltax et DeltaY.
Only PureBasic makes it possible
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: un sprite qui se déplace vers un autre

Message par G-Rom »

Je vais essayer de t'expliquer clairement.

Tu as un point (A) en 100x100 pixels
il veut se diriger vers le point (B) en 200x200

il faut déterminé la direction à prendre :
Direction = B - A
une fois que tu as cette direction , il nous faut connaitre la "longueur" qui sépare B & A
SQR ( Direction.x² + Direction.y² )
une fois que l'on connais sa longueur , on normalise la direction , c'est à dire qu'on ramène sa valeur entre [0 & 1]
pour cela on divise la direction par sa longueur.
Normalise = Direction / Longueur
Normalise à donc une valeur entre 0 & 1 , grâce à cela tu peut bouger ton point A vers le point B :
A + ( Normalise * vitesse )
ton point A en fonction de sa vitesse , ira naturellement vers le point B



@+
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: un sprite qui se déplace vers un autre

Message par blendman »

G-Rom a écrit :Je vais essayer de t'expliquer clairement.
salut

Merci pour ton explication :) (j'étais en train de comprendre ton exemple, mais ton explication m'a confirmé ce que j'avais compris).

J'ai donc, modifié mon exemple, et effectivement, la vitesse est normalisée. Mais il se pose un nouveau problème : les angles ne fonctionnent plus.

En fait, avec cet exemple, seuls les angles n*45° sont pris en compte.

voici mon code, peut être ai-je fait une erreur quelque part, je continue à regarder :

Code : Tout sélectionner

;{******************** infos ******************
;
; déplacement de personnage (un clic and go de base) et lançage de sorts à la volée :)
;
; code release mouse : netmaestro
; aide sur le déplacement (purebasic): G-rom, Djes
; aide sur le déplacement (general) : D-z
; le reste : ben, moi :)
;
; pb : 4.51
;
;}


;{ ************************enumeration ***********************
#window = 0
Enumeration
#player 
#block
#ennemi
EndEnumeration
#ScreenW = 800
#ScreenH = 600
;}

;{ ************************ variables ************************

Global vitesse= 3
Global inscreen = 1
Global mouseClic = 0

ShowCursor_(1)
;}

;{ ************************ Structures ************************

Structure s_block
  id.i ; l'id (le numero) de l'objet >> doublon avec la position de la liste ?
  name.s ; le nom de l'objet
  sprite.i ; le sprite
  
  position.Point ; la position x, y
  previous.Point ; la position de depart ou d'avant
  cible.Point ; la position vers laquelle on veut aller (arrivee)
  direction.Point ; la direction dans laquelle on se déplace
  distance_A_Parcourir.f ; la distance entre le depart (previous) et l'arrivee (cible)
  distance_restante.f
  cible_ok.i ; pas utile ?
  vitesse.f ; la vitesse de déplacement
EndStructure

Global NewList block.s_block()

Global NewList ennemi.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 ***************
;on charge les sprites
LoadSprite(#player,"col.png")
LoadSprite(#block,"blockCollision.png")
LoadSprite(#ennemi,"ennemi.png")

For i =0 To 2 ; on 3 types d'objets (player, block (=sort) et ennemi)
  TransparentSpriteColor(i,RGB(255,0,0)) ; on rend la couleur rouge transprante
Next i
;}

;{ ************************ boucle principale ***************

Repeat

Event= WindowEvent ()

ExamineKeyboard ()
ExamineMouse()
gestion_souris()

affichage()

evenementClavier()
Player_move()
instance_create()
Sort_move()

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
 
;  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
;     
;  
 
 
 
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"
        \sprite = #block        
        
        \previous\x = player(0)\position\x ;depart 
        \previous\y = player(0)\position\y ; depart 
        \cible\x = MouseX() ; arrivee 
        \cible\y = MouseY() ; arrivée
        
        \position\x = player(0)\position\x ; position actuelle
        \position\y = player(0)\position\y ; position actuelle
        
        \direction\x = \cible\x - \previous\x ; la direction
        \direction\y = \cible\y - \previous\y ; la direction
        \distance_A_Parcourir =  Sqr( \direction\x * \direction\x    +    \direction\y * \direction\y ) ; la distance à parcourir entre l'arrivée et le départ
        
        \direction\x = \direction\x / \distance_A_Parcourir ; la direction normalisée en x
        \direction\y = \direction\y / \distance_A_Parcourir ; la direction normalisée en y
        \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()\direction\x))
        block()\position\y  + (block()\vitesse * (block()\direction\y))
    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  

En tout cas, encore merci pour ton explication (et ta patience ;))

pour tester, il faut faire un clic droit, puisque c'est sur le "sort" que je travaille.
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: un sprite qui se déplace vers un autre

Message par G-Rom »

En attendant que je réponde à ton code plus haut voici un autre code que je viens de te faire :

Code : Tout sélectionner

InitSprite() : InitMouse() : InitKeyboard()

ExamineDesktops()
OpenScreen(DesktopWidth(0), DesktopHeight(0), DesktopDepth(0),"")


CompilerIf #PB_Compiler_OS = #PB_OS_Linux
  KeyboardMode(#PB_Keyboard_International)
  If Subsystem("opengl")=0
    CloseScreen()
    MessageRequester("Erreur","must use opengl subsystem")
    End
  EndIf 
CompilerEndIf


X.f  = 500
Y.f  = 500


TimeA.f = 0
TimeB.f = 0

Repeat

  ExamineMouse() : ExamineKeyboard()
    ClearScreen(RGB(64,128,255))
    
    
    
      Mx = MouseX()
      My = MouseY()

      Dx.f = Mx - X   ; La direction
      Dy.f = My - Y

      L.f  = Sqr( Dx*Dx + Dy*Dy ) ; La longueur ( en pixel )
      
      Nx.f = Dx / L ; La normalisation
      Ny.f = Dy / L
      
      
      ; pour le fun , on ajuste la vitesse suivant la distance
      speed.f = L * 20 / 200
      ; sinon , pour une vitesse constante :
      ;speed.f = 5 
           
      
      X + (Nx * speed) ; Le repositionnement
      Y + (Ny * speed)
      
      
      StartDrawing(ScreenOutput())
      Circle(Mx,My,8,RGB(255,128,64))
      
      
      ; juste pour le fun , le cercle grossi des que L < 100
      If L > 100
        Circle(X,Y,8,RGB(255,0,64))
      Else 
        Circle(X,Y,16,RGB(255,0,64))
      EndIf 
      
      StopDrawing()
      
  
      FlipBuffers()
ElapsedMilliseconds()
Until KeyboardPushed(#PB_Key_Escape)

CloseScreen()

End
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: un sprite qui se déplace vers un autre

Message par blendman »

G-Rom a écrit :En attendant que je réponde à ton code plus haut voici un autre code que je viens de te faire
c'est sympa ;)

Mais la vitesse n'est pas constante sur ce code ;)

On le voit mieux, en modifiant légèrement (il faut cliquer pour que le point rouge bouge) :

Code : Tout sélectionner

#ScreenW = 800
#ScreenH = 600
#window = 0
ShowCursor_(1)
InitSprite() : InitMouse() : InitKeyboard()

ExamineDesktops()
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)



CompilerIf #PB_Compiler_OS = #PB_OS_Linux
  KeyboardMode(#PB_Keyboard_International)
  If Subsystem("opengl")=0
    CloseScreen()
    MessageRequester("Erreur","must use opengl subsystem")
    End
  EndIf
CompilerEndIf


X.f  = 500
Y.f  = 500


TimeA.f = 0
TimeB.f = 0

Repeat

  ExamineMouse() : ExamineKeyboard()
    ClearScreen(RGB(64,128,255))
   
   
   
    If MouseButton(#PB_MouseButton_Left)
      Mx = MouseX()
      My = MouseY()
    EndIf
    

      Dx.f = Mx - X   ; La direction
      Dy.f = My - Y

      L.f  = Sqr( Dx*Dx + Dy*Dy ) ; La longueur ( en pixel )
     
      Nx.f = Dx / L ; La normalisation
      Ny.f = Dy / L
     
     
      ; pour le fun , on ajuste la vitesse suivant la distance
      speed.f = L * 20 / 200
      ; sinon , pour une vitesse constante :
      ;speed.f = 5
           
     
      X + (Nx * speed) ; Le repositionnement
      Y + (Ny * speed)
     
     
      StartDrawing(WindowOutput(#window))
      Circle(Mx,My,8,RGB(255,128,64))
     
     
      ; juste pour le fun , le cercle grossi des que L < 100
      If L > 100
        Circle(X,Y,8,RGB(255,0,64))
      Else
        Circle(X,Y,16,RGB(255,0,64))
      EndIf
     
      StopDrawing()
     
 
      FlipBuffers()
ElapsedMilliseconds()
Until KeyboardPushed(#PB_Key_Escape)

CloseScreen()

End 
Encore merci de prendre du temps pour m'aider ;)
Dernière modification par blendman le mer. 09/mars/2011 18:40, modifié 1 fois.
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: un sprite qui se déplace vers un autre

Message par G-Rom »

A la louche , je ne peut pas testé le code sous linux :
Point est une structure windaube , les membres x & y sont des integers , pas des float
utilise une structure autre que point pour tes vecteurs

structure vector2
x.f
y.f
endstructure
@+
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: un sprite qui se déplace vers un autre

Message par blendman »

G-Rom a écrit :A la louche , je ne peut pas testé le code sous linux :
Point est une structure windaube , les membres x & y sont des integers , pas des float
utilise une structure autre que point pour tes vecteurs
c'est ça !! yes, merci beaucoup :D !!!!!
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: un sprite qui se déplace vers un autre

Message par Ollivier »

Mon conseil c'est d'éviter les structures: c'est trop long...

Compare par toi-même:

Code : Tout sélectionner

Define.I HerosS3
Define.F HerosX, HerosY
DisplaySprite3D(HerosS3, HerosX, HerosY)

Code : Tout sélectionner

Structure Heros
S3.I
X.F
Y.F
EndStructure
Define.Heros Heros
With Heros
DisplaySprite3D(\S3, \X, \Y)
EndWith
Après, tu as peut-être un autre regard que moi...
En plus, les structures sont plus lentes...

Je vais te montrer un exemple quand j'aurai deux minutes...
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: un sprite qui se déplace vers un autre

Message par blendman »

Ollivier a écrit :Mon conseil c'est d'éviter les structures: c'est trop long...
trop long dans quel sens ? en terme de lignes de code ?
En fait, je dois utiliser les structures car je vais avoir par exemple 50 à 100 ennemi sur une map. Donc, je ne sais pas si définir 100 * 15 variables n'est pas plus long que de définir une structure à 15 variable et de l'utiliser dans un tableau de 100 éléments. Il fut que je fasse des essais. Mais c'est vrai qu'au premier abord, les structures c'est long :)

Après, peut être que l'on peut utiliser les variables dans un tableau, et utiliser tout ça dans une procédure, auquel cas, je ferai plusieurs essais pour comparer :).
Je vais te montrer un exemple quand j'aurai deux minutes...
ok, j'attends de voir ça. Merci ;)
Avatar de l’utilisateur
Cool Dji
Messages : 1126
Inscription : ven. 05/sept./2008 11:42
Localisation : Besançon
Contact :

Re: un sprite qui se déplace vers un autre

Message par Cool Dji »

Blendman, t'as intérêt à nous faire un bon truc avec toute l'aide que t'as :D
Mais c'est clair que ça donne envie de filer un coup de main à quelqu'un comme toi qui déjà s'exprime correctement et qui tient compte des remarques et conseils.
On est aussi pressé de voir un truc avec tes graphs :mrgreen:
Only PureBasic makes it possible
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: un sprite qui se déplace vers un autre

Message par G-Rom »

blendman a écrit :
Ollivier a écrit :Mon conseil c'est d'éviter les structures: c'est trop long...
trop long dans quel sens ? en terme de lignes de code ?
En fait, je dois utiliser les structures car je vais avoir par exemple 50 à 100 ennemi sur une map. Donc, je ne sais pas si définir 100 * 15 variables n'est pas plus long que de définir une structure à 15 variable et de l'utiliser dans un tableau de 100 éléments. Il fut que je fasse des essais. Mais c'est vrai qu'au premier abord, les structures c'est long :)

Après, peut être que l'on peut utiliser les variables dans un tableau, et utiliser tout ça dans une procédure, auquel cas, je ferai plusieurs essais pour comparer :).
Je vais te montrer un exemple quand j'aurai deux minutes...
ok, j'attends de voir ça. Merci ;)

écoute pas ces conneries , c'est juste pour être en contradiction avec ce que j'ai dis.
les structures sont primordiale pour un jeu un tant soit peu évolué , on ne parle pas d'un pong là.
Quand à la vitesse d'exécution c'est de la couille en barre , demande à un dev pro si pour une question de rapidité
il n'utilise pas les structures...
il faut être complétement à la masse pour insinuer de tel choses... , te lances pas dans des tests pourris pour comparé le nombres
de cycles CPU pour vérifié la rapidité, ca n'a aucun sens pour ton projet.
cette personne aime lancer des topics pourris et aime à ce que les "sanguins" lui rentre dedans dans la foulée , ignorons le tout simplement, sa parole
n'a aucune valeur.

@+
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: un sprite qui se déplace vers un autre

Message par blendman »

Cool Dji a écrit :Blendman, t'as intérêt à nous faire un bon truc avec toute l'aide que t'as :D
héhé, c'est bien ce que j'espère :)
Mais c'est clair que ça donne envie de filer un coup de main à quelqu'un comme toi qui déjà s'exprime correctement et qui tient compte des remarques et conseils.
S'exprimer correctement c'est important pour être compris, même si des fois, j'ai un peu de mal quand même :).
Et remercier et tenir compte des remarques et des conseils, c'est aussi important, sinon, ça ne servirait à rien de demander ces conseils ou de poser une question :).
On est aussi pressé de voir un truc avec tes graphs :mrgreen:
moi aussi lol

Sinon, je viens de trouver ça dans l'aide et ça m'a l'air très intéressant pour le déplacement d'objet : ATan2(x,y)
Visiblement cela renvoie l'angle (ou la direction dans notre exemple), si je ne dis pas de bêtise :).

G-rom qu'en penses-tu ? On pourrait utiliser cet Atan2() je crois bien :)

Code : Tout sélectionner

Structure vector
  x.f
  y.f
EndStructure

A.vector
B.vector

A\x = 1
A\y = 1
B\x = 2
B\y = 2

Debug Degree(ATan2(Bx-A\x,B\y-A\y))
Je viens de tester dans mon code, et ça marche vraiment bien :)
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: un sprite qui se déplace vers un autre

Message par G-Rom »

je découvre la fonction Degree()... :D
je faisait <Radian * 180 / #pi>
bref, c'est bon , sauf que je considère de la droite de l'écran(en partant du centre) est l'angle 0 , le bas l'angle 90 , etc , dans le sens des aiguilles d'une montre
Rajoute -90 à ton résultat. ( sa colle au rotation des sprites 3D comme ca. )
Répondre