Trouver la direction /angle d'un déplacement

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Trouver la direction /angle d'un déplacement

Message par blendman »

salut

J'essaie de trouver une direction ou un angle depuis un déplacement clavier.
Je sais le faire si j'ai une "cible" :

Code : Tout sélectionner

Degree(ATan2((cible_y- player\y),(cible_x- player\x)))
Mais si je n'ai pas de cible, je n'ai pas encore trouvé :

Code : Tout sélectionner

#win = 0
#speed= 4
InitSprite() : InitSprite3D() :InitKeyboard()

OpenWindow(#win,0,0,800,600, "Direction_deplacement", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#win),0,0,800,600,0,0,0)

CreateSprite(0,64,64,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(0))
Box(0,0,64,64,#White)
StopDrawing()
CreateSprite3D(0,0)

Repeat
  event =WaitWindowEvent(10)
  ExamineKeyboard()
  ;{ keyboard
  If KeyboardPushed(#PB_Key_Up)
    y - #speed  
  ElseIf KeyboardPushed(#PB_Key_Down)
    y + #speed
  EndIf
  If KeyboardPushed(#PB_Key_Right)
    x + #speed
  ElseIf KeyboardPushed(#PB_Key_Left)
    x - #speed
  EndIf
  direction.f = Degree(ATan2(x,y)); ici, je bloque ^^
  ;}
  ClearScreen(RGB(125,125,125))
  
  Start3D()
  DisplaySprite3D(0,x,y)
  RotateSprite3D(0,direction,0)
  Stop3D()
  StartDrawing(ScreenOutput())
  DrawingMode(#PB_2DDrawing_Transparent)
  DrawText(10,10,"Direction : "+Str(direction),#black)
  StopDrawing()
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) Or event = #PB_Event_CloseWindow
Vous auriez une idée (sans prendre en compte les touche du clavier, car je souhaite que ce soit utilisable en fait avec une manette et un stick directionnel :)).
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Trouver la direction /angle d'un déplacement

Message par G-Rom »

Code : Tout sélectionner

#win = 0
#speed= 4
InitSprite() : InitSprite3D() :InitKeyboard()

OpenWindow(#win,0,0,800,600, "Direction_deplacement", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#win),0,0,800,600,0,0,0)

CreateSprite(0,64,64,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(0))
Box(0,0,64,64,#White)
StopDrawing()
CreateSprite3D(0,0)


Angle.f = 0
Speed.f = 0
x.f     = 0
y.f     = 0

Repeat
  event =WaitWindowEvent(10)
  ExamineKeyboard()
  ;{ keyboard
  If KeyboardPushed(#PB_Key_Up)
    Speed = #speed
  ElseIf KeyboardPushed(#PB_Key_Down)
    Speed = -#speed
  Else 
    Speed = 0
  EndIf
  
  If KeyboardPushed(#PB_Key_Right)
    Angle + 1
  ElseIf KeyboardPushed(#PB_Key_Left)
    Angle - 1
  EndIf
  
  
  x = x + Speed * Cos(Angle * #PI / 180)
  y = y + Speed * Sin(Angle * #PI / 180)
  
    
  ClearScreen(RGB(125,125,125))
  
  Start3D()
  DisplaySprite3D(0,x,y)
  RotateSprite3D(0,Angle,0)
  Stop3D()
  StartDrawing(ScreenOutput())
  DrawingMode(#PB_2DDrawing_Transparent)
  DrawText(10,10,"Direction : "+Str(angle),#Black)
  StopDrawing()
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) Or event = #PB_Event_CloseWindow
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Trouver la direction /angle d'un déplacement

Message par G-Rom »

Avec un peu plus de trigo :

Code : Tout sélectionner

Structure bullet
  x.f
  y.f
  ttl.i
  DirectionX.f
  DirectionY.f
  speed.f
EndStructure

Global NewList bullet.bullet()
  
  

#win = 0
#speed= 4
InitSprite() : InitSprite3D() :InitKeyboard()

OpenWindow(#win,0,0,800,600, "Direction_deplacement", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#win),0,0,800,600,0,0,0)

CreateSprite(0,64,64,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(0))
Box(0,0,64,64,#White)
StopDrawing()
CreateSprite3D(0,0)


Angle.f = 0
Speed.f = 0
x.f     = 0
y.f     = 0

Repeat
  event =WaitWindowEvent(10)
  ExamineKeyboard()
  ;{ keyboard
  If KeyboardPushed(#PB_Key_Up)
    Speed = #speed
  ElseIf KeyboardPushed(#PB_Key_Down)
    Speed = -#speed
  Else 
    Speed = 0
  EndIf
  
  If KeyboardPushed(#PB_Key_Right)
    Angle + 4
  ElseIf KeyboardPushed(#PB_Key_Left)
    Angle - 4
  EndIf
  
  
  x = x + Speed * Cos(Angle * #PI / 180)
  y = y + Speed * Sin(Angle * #PI / 180)
  
    
  ClearScreen(RGB(125,125,125))
  
  Start3D()
  DisplaySprite3D(0,x,y)
  RotateSprite3D(0,Angle,0)
  Stop3D()
  StartDrawing(ScreenOutput())
  DrawingMode(#PB_2DDrawing_Transparent)
  DrawText(10,10,"Angle degrée : "+Str(angle),#Black)
  
  Circle(x+32,y+32,2,$FF)
  
  
  Avant_X.f = (x + 32 * Cos(Angle * #PI / 180)) + 32
  Avant_Y.f = (y + 32 * Sin(Angle * #PI / 180)) + 32 
  
  Circle(Avant_X,Avant_Y,4,$00FF00)
  
  
  ; Avec des vecteurs 2D ( marche aussi en 3D)
  
  ; Creation du vecteur direction (entre le centre et l'avant du sprite):
  DirectionX.f = Avant_X - (x+32)
  DirectionY.f = Avant_Y - (y+32)
  
  ; Longueur du vecteur ou sa norme
  Longueur.f = Sqr( (Avant_X - (x+32) ) * (Avant_X - (x+32) )  +  (Avant_Y - (y+32) ) * (Avant_Y - (y+32) ) )
 
  
  ; Normalisation du vecteur direction ( TRES IMPORTANT DE TRAVAILER AVEC DES VECTEURS NORMALISE ( -1.0f à 1.0f )
  If Longueur > 1e-08
     invLongueur.f = 1  / Longueur
     DirectionX * invLongueur
     DirectionY * invLongueur
  EndIf 
    
  
  
  If Timer < ElapsedMilliseconds()
    
    Timer = ElapsedMilliseconds() + 100
    
    AddElement(bullet())
    
    bullet()\x = Avant_X
    bullet()\y = Avant_Y
    
    bullet()\DirectionX = DirectionX
    bullet()\DirectionY = DirectionY
    
    
    bullet()\ttl   = ElapsedMilliseconds() + 1000
    bullet()\speed = 5 + Speed
    
  EndIf 
  
  
  ForEach bullet()
    
    If bullet()\ttl > ElapsedMilliseconds()
      
       bullet()\x = bullet()\x + bullet()\DirectionX * bullet()\speed  
       bullet()\y = bullet()\y + bullet()\DirectionY * bullet()\speed  

       Circle( bullet()\x, bullet()\y, 4, 0)
       
       LineXY(bullet()\x, bullet()\y,Avant_X,Avant_Y,$FF0000)
      
     Else
       
       DeleteElement(bullet(),1)
      
    EndIf 
    
  Next 
  
  
  
      DrawText(10,30,"Direction par vecteur 2D normalisé : "+StrF(DirectionX,2)+"  :  "+StrF(DirectionY,2),#Black)
  
  StopDrawing()
  FlipBuffers()
  
  
  
Until KeyboardPushed(#PB_Key_Escape) Or event = #PB_Event_CloseWindow

Pour connaitre une direction :

- Connaitre le point de départ
- Connaitre le point d'arrivé
- Calculé la direction en faisant une soustraction des 2 points cité plus haut ( arrivée - départ )
- Calculé la longueur du vecteur ( départ / arrivé ) , c'est la norme du vecteur. sqr( (x1-x2)^2 + (y1-y2)^2 )
- Normalisé la direction en la divisant par la norme

tu obtiendras un nombre entre -1 et 1 pour chaque axes (xy) ou (xyz)
la nouvelle position se calcul ainsi :
new_position = direction * vitesse
en PB :

Code : Tout sélectionner

x = x + DirectionX * speed  
y = y + DirectionY * speed  
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Trouver la direction /angle d'un déplacement

Message par blendman »

salut

Merci G-rom pour ton explication.
En fait, je savais déjà tout cela, car tu me l'avais déjà expliqué et c'est déjà de cette manière que je fais pour pas mal de choses dans mon jeu ;).

Je recherchai la possibilité de détecter un angle à partir du stick directionnel d'une manette, histoire d'avoir un code compatible pour purebasic ou c# (pour la version Xbox).

Et c'est cool, car c'est compatible, j'ai pu me servir de ça :

Code : Tout sélectionner

angle.f = ATan2((y2- y1),(x2- x1))

sort()\position\x + Sin(angle)* sort()\vitesse
sort()\position\y + Cos(angle)* sort()\vitesse 
Répondre