une voiture dans une map

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

une voiture dans une map

Message par Thyphoon »

Bon voilà j'ai un petit souci !

Toujours pour mon jeu, je cherche a intégrer la gestion de véhicule.
Le problème est ce dernier, ma map est constitué de Bloc de 32x32 pixels. Les obstacles sont géré au niveau des bloc (le bloc est ou sol ou mur) Et mon véhicule lui est dans un sprite de 256x256 comment gérer les collisions ????

J'utilise déjà la technique dont on a parlé ici
Collision avec un rectangle qui peut rotater !
pour faire en sorte que les personnages ne passe pas sur le vehicule. Mais c'est quand même assez gourmand en ressource...
Mais maintenant comment faire lorsque le vehicule se déplace réagisse au obstacle (ne passe pas, voir rebondire...)

Toute les idées sont les bienvenus. Je me demande comment ils font dans jeu de voiture pour gerer autant de paramètre et garder un FPS correcte lollllllll

Merci d'avance
Anonyme

Message par Anonyme »

Vecteur ? box collision ? ma fois , je ne peut t'aider sans code :wink:
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Cpl.Bator a écrit :Vecteur ? box collision ? ma fois , je ne peut t'aider sans code :wink:
Oui c'est bien ce que je pensais... mais je sais pas trop comment ressortir facilement le code de mon jeu ...

donc voici le code
http://yann.lebrun.club.fr/Planetes_Aliens_source.zip
le fichier principal est main.pb
la gestion des vehicules est dans le fichier vehicule.pb
une fois le jeu lancé, on peu dirigé le vehicule avec le pavé numérique
8 avance
2 freine
4 tourne a gauche
6 tourne a droite
Space remet le vehicule a sa position d'origine
Anonyme

Message par Anonyme »

cherches collisions glissantes sur le forum :wink:
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Cpl.Bator a écrit :cherches collisions glissantes sur le forum :wink:
Merci pour le tuyau :)
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Bon je suis aller etudier l'histoire des collisions glissantes. En verité sans le savoir c'est déjà ce que je faisais pour mes perso ...
Mais bon ça marche tant que tu n'utilise pas de rotatesprite()

là je rappel que le sprite qui se deplace fait 256x256 et peut tourner sur 360° et que les case de la map sont de 32x32. Et qu'une case peut être vide (0) ou bien avec un obstacle (1) donc pour la detection des collisions là je suis un peu perdu. sans compter que j'aurais aimé ! mais bon si c'est pas possible je ferais sans...que la voiture réagisse en fonction de l'endroit ou elle rentre en collision .. vous comprenez ?

là j'ai pas le temps mais je vais essayer de faire un code simplifier pour vous montrer ça ...
Anonyme

Message par Anonyme »

Voici une première mouture de code :

Code : Tout sélectionner

If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
  End
EndIf


OpenWindow(0,0,0,640,480,"Collision glisantes",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(0),0,0,640,480,1,0,0)
ShowCursor_(1) : ReleaseMouse(1)

Structure Vector2
  x.f
  y.f
EndStructure

Structure Segment
  P1.Vector2
  P2.Vector2
EndStructure

Structure box
  Position.Vector2
  SizeX.f
  SizeY.f
  Angle.f
  Segment_A.Segment
  Segment_B.Segment
  Segment_C.Segment
  Segment_D.Segment
EndStructure

;***********************************************************
; MATHS UTILS (DISTANCE & ANGLE)
;***********************************************************
Procedure Distance(x1,y1,z1,x2,y2,z2)
  Protected Result.f
  Result = Sqr(  (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) + (z1-z2)*(z1-z2) )
  ProcedureReturn Result
EndProcedure

Procedure.f ReturnAngle(x1.f,y1.f,x2.f,y2.f)
  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 
;***********************************************************
; GENERIC FUNCTION FOR DRAW OR MOVE & TURN BOX
;***********************************************************
Procedure DrawBox(*Box.box,Color.l)
  With *Box
    LineXY(\Segment_A\P1\x,\Segment_A\P1\y,\Segment_A\P2\x,\Segment_A\P2\y,Color)
    LineXY(\Segment_B\P1\x,\Segment_B\P1\y,\Segment_B\P2\x,\Segment_B\P2\y,Color)
    LineXY(\Segment_C\P1\x,\Segment_C\P1\y,\Segment_C\P2\x,\Segment_C\P2\y,Color)
    LineXY(\Segment_D\P1\x,\Segment_D\P1\y,\Segment_D\P2\x,\Segment_D\P2\y,Color)
  EndWith
EndProcedure

Procedure SetBox(*Box.box,x.f,y.f)
  With *Box
    \Position\x     = x
    \Position\y     = y
   
    
    ; Calculs des coordonées sphérique des vertices
    
    Xa.f = \Position\x-(\SizeX/2) : Xb.f = \Position\x+(\SizeX/2) : Xc.f = \Position\x+(\SizeX/2) : Xd.f = \Position\x-(\SizeX/2) 
    Ya.f = \Position\y-(\SizeY/2) : Yb.f = \Position\y-(\SizeY/2) : Yc.f = \Position\y+(\SizeY/2) : Yd.f = \Position\y+(\SizeY/2)
    
    Dist_A.f = Distance(Xa,Ya,0,\Position\x,\Position\y,0)
      Dist_B.f = Distance(Xb,Yb,0,\Position\x,\Position\y,0)
        Dist_C.f = Distance(Xc,Yc,0,\Position\x,\Position\y,0)
          Dist_D.f = Distance(Xd,Yd,0,\Position\x,\Position\y,0)
    
    AngA.f = ReturnAngle(Xa,Ya,\Position\x,\Position\y)
      AngB.f = ReturnAngle(Xb,Yb,\Position\x,\Position\y)
        AngC.f = ReturnAngle(Xc,Yc,\Position\x,\Position\y)
          AngD.f = ReturnAngle(Xd,Yd,\Position\x,\Position\y)
     
      Xa =  \Position\x + Dist_A * Cos( (\Angle+AngA) *#PI/180)
      Ya =  \Position\y + Dist_A * Sin( (\Angle+AngA) *#PI/180)
    
      Xb =  \Position\x + Dist_B * Cos( (\Angle+AngB) *#PI/180)
      Yb =  \Position\y + Dist_B * Sin( (\Angle+AngB) *#PI/180)
      
      Xc =  \Position\x + Dist_C * Cos( (\Angle+AngC) *#PI/180)
      Yc =  \Position\y + Dist_C * Sin( (\Angle+AngC) *#PI/180)
      
      Xd =  \Position\x + Dist_D * Cos( (\Angle+AngD) *#PI/180)
      Yd =  \Position\y + Dist_D * Sin( (\Angle+AngD) *#PI/180)
      
      \Segment_A\P1\x = Xa : \Segment_A\P2\x = Xb
      \Segment_A\P1\y = Ya : \Segment_A\P2\y = Yb
                           
      \Segment_B\P1\x = Xb : \Segment_B\P2\x = Xc
      \Segment_B\P1\y = Yb : \Segment_B\P2\y = Yc
                           
      \Segment_C\P1\x = Xc : \Segment_C\P2\x = Xd
      \Segment_C\P1\y = Yc : \Segment_C\P2\y = Yd
                           
      \Segment_D\P1\x = Xd : \Segment_D\P2\x = Xa
      \Segment_D\P1\y = Yd : \Segment_D\P2\y = Ya
      
  EndWith
EndProcedure


Procedure MoveBox(*Box.box,Speed.f)
  With *Box
    \Position\x=\Position\x+Speed*Cos((\Angle+270)*#PI/180)
    \Position\y=\Position\y+Speed*Sin((\Angle+270)*#PI/180)
  EndWith
EndProcedure

Procedure TurnBox(*Box.box,Angle.f)
  With *Box
   \Angle=\Angle+Angle
  EndWith
EndProcedure

;***********************************************************
; COLLISION SECTION (ORIGINAL CODE BY COMTOIS) : CollisionSegmentSegment()
;***********************************************************

Procedure.l Signe(A.l)
  If A>0
    ProcedureReturn 1
  ElseIf A=0
    ProcedureReturn 0
  Else
    ProcedureReturn -1
  EndIf
EndProcedure

Procedure CollisionSegmentSegment(*S1.Segment,*S2.Segment)
  ;Test Collision encadrement
    R1.f=((*S2\P1\x-*S1\P1\x)*(*S1\P2\y-*S1\P1\y))-((*S2\P1\y-*S1\P1\y)*(*S1\P2\x-*S1\P1\x))
    R2.f=((*S2\P2\x-*S1\P1\x)*(*S1\P2\y-*S1\P1\y))-((*S2\P2\y-*S1\P1\y)*(*S1\P2\x-*S1\P1\x))
    R3.f=((*S1\P1\x-*S2\P1\x)*(*S2\P2\y-*S2\P1\y))-((*S1\P1\y-*S2\P1\y)*(*S2\P2\x-*S2\P1\x))
    R4.f=((*S1\P2\x-*S2\P1\x)*(*S2\P2\y-*S2\P1\y))-((*S1\P2\y-*S2\P1\y)*(*S2\P2\x-*S2\P1\x))
    If (Signe(R1)*Signe(R2)<=0) And (Signe(R3)*Signe(R4)<=0)
      Resultat = #True
    EndIf
  ProcedureReturn Resultat
EndProcedure


Procedure CollisionBoxBox(*BoxA.box,*BoxB.box)
  
  If CollisionSegmentSegment(*BoxA\Segment_A,*BoxB\Segment_A) : ProcedureReturn 1 : EndIf
  If CollisionSegmentSegment(*BoxA\Segment_A,*BoxB\Segment_B) : ProcedureReturn 1 : EndIf
  If CollisionSegmentSegment(*BoxA\Segment_A,*BoxB\Segment_C) : ProcedureReturn 1 : EndIf
  If CollisionSegmentSegment(*BoxA\Segment_A,*BoxB\Segment_D) : ProcedureReturn 1 : EndIf
  
  If CollisionSegmentSegment(*BoxA\Segment_B,*BoxB\Segment_A) : ProcedureReturn 1 : EndIf
  If CollisionSegmentSegment(*BoxA\Segment_B,*BoxB\Segment_B) : ProcedureReturn 1 : EndIf
  If CollisionSegmentSegment(*BoxA\Segment_B,*BoxB\Segment_C) : ProcedureReturn 1 : EndIf
  If CollisionSegmentSegment(*BoxA\Segment_B,*BoxB\Segment_D) : ProcedureReturn 1 : EndIf
  
  If CollisionSegmentSegment(*BoxA\Segment_C,*BoxB\Segment_A) : ProcedureReturn 1 : EndIf
  If CollisionSegmentSegment(*BoxA\Segment_C,*BoxB\Segment_B) : ProcedureReturn 1 : EndIf
  If CollisionSegmentSegment(*BoxA\Segment_C,*BoxB\Segment_C) : ProcedureReturn 1 : EndIf
  If CollisionSegmentSegment(*BoxA\Segment_C,*BoxB\Segment_D) : ProcedureReturn 1 : EndIf
  
  If CollisionSegmentSegment(*BoxA\Segment_D,*BoxB\Segment_A) : ProcedureReturn 1 : EndIf
  If CollisionSegmentSegment(*BoxA\Segment_D,*BoxB\Segment_B) : ProcedureReturn 1 : EndIf
  If CollisionSegmentSegment(*BoxA\Segment_D,*BoxB\Segment_C) : ProcedureReturn 1 : EndIf
  If CollisionSegmentSegment(*BoxA\Segment_D,*BoxB\Segment_D) : ProcedureReturn 1 : EndIf

EndProcedure







MyBox.box
MyBox\SizeX=64
MyBox\SizeY=128
MyBox\Angle=0

MyBox\Position\x=100
MyBox\Position\y=100
      

MyBox2.box
MyBox2\SizeX=64
MyBox2\SizeY=64
MyBox2\Angle=0

MyBox2\Position\x=300
MyBox2\Position\y=300
      


Repeat
  ExamineKeyboard() : ExamineMouse() 
  ClearScreen(#White)
  event = WindowEvent()
  
  
  
  
  If CollisionBoxBox(MyBox,MyBox2)=0
     
      OldX=MyBox\Position\x
      OldY=MyBox\Position\y
      OldA=MyBox\Angle
      
      If KeyboardPushed(#PB_Key_Up)    : MoveBox(MyBox,5)   : EndIf
      If KeyboardPushed(#PB_Key_Down)  : MoveBox(MyBox,-2)  : EndIf
      
      If KeyboardPushed(#PB_Key_Right) : TurnBox(MyBox,5)   : EndIf
      If KeyboardPushed(#PB_Key_Left)  : TurnBox(MyBox,-5)  : EndIf
      
      SetBox(MyBox,MyBox\Position\x,MyBox\Position\y)
    
    Else
      
       SetBox(MyBox,OldX,OldY)
       MyBox\Angle = OldA
      
  EndIf
  
      
    
      
      
      SetBox(MyBox2,300,300)
      StartDrawing(ScreenOutput())
        DrawBox(MyBox,#Blue)
          DrawBox(MyBox2,#Blue)
            StopDrawing()
    
    
  
    
    FlipBuffers()
  Until KeyboardReleased(#PB_Key_Escape) Or event = #PB_Event_CloseWindow
  
  
  
  
  

j'utilise la detection de segment de notre Comtois :wink:
C'est très pratique, reste plus qu'a l'améilliorer pour faire glissé notre cube :wink:
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

bon j'arrive à ça
http://herved25.free.fr/sources/Voiture.exe

C'est pas terrible, y'a encore du boulot pour l'améliorer, mais j'ai pas le temps, ça sera pour cet hiver :)

Je mettrai le code en ligne en fin de semaine.
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Merci Cpl.Bator et comtois !

C'est pas mal du tout ! ça m'a donné une idée... je vais faire quelques tests !
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Merci a tous ceux qui se sont penché sur le problème le problème est resolu .. :o) J'ai utilisé la méthode de comtois ..et ça marche tres bien...j'ai du adapter a mon code mais c'est parfait !!
Répondre