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
C'est très pratique, reste plus qu'a l'améilliorer pour faire glissé notre cube