Poursuite d'un point

Programmation avancée de jeux en PureBasic
Anonyme

Poursuite d'un point

Message par Anonyme »

Voici un p'tit snippet montrant comment faire suivre un point A sur un point B tout en appliquant une rotation "douce"

Code : Tout sélectionner

; Cpl.Bator
; PureBasic 4.10

#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




Repeat
ClearScreen(0)
ExamineKeyboard()
ExamineMouse()


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
Je vais voir si je peut ajouté une formation de vol à nos flêches pour pas qu'elles se rentrent dedans :D
beauregard
Messages : 1307
Inscription : dim. 08/juil./2007 18:32
Localisation : Toulouse

Message par beauregard »

cool, dans le sens inverse d'une aiguille d'une montre, çà marche bien. Mais dans l'autre sens...
Avatar de l’utilisateur
Polux
Messages : 440
Inscription : mer. 21/janv./2004 11:17
Localisation : france
Contact :

Message par Polux »

tip top! excellent cpl, ça m'interesse cette technique :wink:
Avatar de l’utilisateur
Ar-S
Messages : 9540
Inscription : dim. 09/oct./2005 16:51
Contact :

Message par Ar-S »

Très planant, très intéressant :)
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

Merci pour ce code :)
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Message par Ollivier »

Avec un peu de retard (vu la date du post...), je me permets aussi de dire que ces fonctions sont très intéressantes pour adoucir les mouvements. Merci Cpl.Bator!

Ollivier
Répondre