Diablo, THANKS!!
It all works now!
YES!
Check this out!
Requires: Vector2D.bmx (See my first post above)
It all works now!
YES!
Check this out!
Requires: Vector2D.bmx (See my first post above)
Strict Include "Vector2D.bmx" Include "Circle2D.bmx" '''''''''' seting Lines Global Vector:Vector2D[10] Vector[0] = Vector2d.create(4.0000000000000000 , 1.0000000000000000) Vector[1] = Vector2d.create(204.00000000000000 , 369.00000000000000) Vector[2] = Vector2d.create(197.00000000000000 , 238.00000000000000) Vector[3] = Vector2d.create(634.00000000000000 , 0.0000000000000000) Vector[4] = Vector2d.create(122.00000000000000 , 448.00000000000000) Vector[5] = Vector2d.create(499.00000000000000 , 448.00000000000000) Vector[6] = Vector2d.create(499.00000000000000 , 448.00000000000000) Vector[7] = Vector2d.create(499.00000000000000 , 225.00000000000000) Vector[8] = Vector2d.create(122.00000000000000 , 448.00000000000000) Vector[9] = Vector2d.create(122.00000000000000 , 221.00000000000000) '''''''''''''''''' Ball stuff and gravity Global Grav:Vector2d = Vector2d.create(0, 0.000098) Global Ball:Circle2d = Circle2d.create(400 , 20 , 10) Global BallVelocity:Vector2d = Vector2d.create(0,0) '''''''''''''''''''''''''''''''''''''''''Graphics and main Loop Graphics 640 , 480, 0, 60 While Not KeyHit(KEY_ESCAPE) Cls '''''''''' Drawing SetScale 1.0 , 1.0 DrawText MouseX() + " " + MouseY() , 10 , 10 For Local i = 0 To Vector.Length - 1 Step 2 SetColor 0 , 255 , 0 DrawLine Vector[i].x , Vector[i].y , Vector[i+1].x , Vector[i+1].y SetColor 200 , 150 , 100 DrawText i , Vector[i].x , Vector[i].y DrawText i + 1 , Vector[i + 1].x , Vector[i + 1].y Next SetColor 0 , 0 , 255 Ball.Draw() '''''' Forces BallVelocity.add( Grav ) CheckCollision() SetColor 255,255,255 'BallVelocity.DrawModify( Ball.Position, 1000, 0 ) '''''' Update Positions and store data for the old ones Local PreBall:Vector2D = Ball.position.copy() Ball.position.add(BallVelocity) ''''''' Positionning Lines ''''''''''''''''''Line[0] If KeyDown(Key_0) Vector[0].x = MouseX() Vector[0].y = MouseY() End If If KeyDown(Key_1) Vector[1].x = MouseX() Vector[1].y = MouseY() End If ''''''''''''''''''Line[1] If KeyDown(Key_2) Vector[2].x = MouseX() Vector[2].y = MouseY() End If If KeyDown(Key_3) Vector[3].x = MouseX() Vector[3].y = MouseY() End If ''''''''''''''''''Line[1] If KeyDown(Key_4) Vector[4].x = MouseX() Vector[4].y = MouseY() End If If KeyDown(Key_5) Vector[5].x = MouseX() Vector[5].y = MouseY() End If ''''''''''''''''''Line[3] If KeyDown(Key_6) Vector[6].x = MouseX() Vector[6].y = MouseY() End If If KeyDown(Key_7) Vector[7].x = MouseX() Vector[7].y = MouseY() End If ''''''''''''''''''Line[4] If KeyDown(Key_8) Vector[8].x = MouseX() Vector[8].y = MouseY() End If If KeyDown(Key_9) Vector[9].x = MouseX() Vector[9].y = MouseY() End If ''''''''''''''''''''''' Psitionning Ball If MouseDown(1) Ball.Position.set( MouseX() , MouseY() ) BallVelocity.set(0,0) End If Flip 1 Wend '''''''''''' To copy paste this to the setting Line section on the top and have the costom MAP Print "" Print "copy paste the below" Print "''''''''''''''''''''''''''''''''''''''''''''" Print "Local Vector:Vector2d[10]" For Local i:Byte = 0 To Vector.Length - 1 Local printout$ = "" Printout:+ "Vector[" + i +"] = Vector2d.create(" + Vector[i].x + " , " + Vector[i].y + ")" Print printout ' Vector[0] = Vector2d.create(100 , 300) ' Vector[1] = Vector2d.create(300 , 300) Next End Function CheckCollision() For Local i = 0 To Vector.Length - 1 Step 2 ' ' 1. Detect collision ' Makes sure that with our current velocity and shape ( this time we are a circle ) ' we do not pass through any lines ' This function does not check that, but this works if our velocity is not larger than or cirles radius ' The check for collision rutine need improvement! ' 'Local OverlapDist! = MinDistPointLine(Ball.position.x , Ball.position.y , Vector[i].x , Vector[i].y , Vector[i +1].x , Vector[i +1].y) Local VectorToLine:Vector2D = VectorToLine(Ball.position.x , Ball.position.y , Vector[i].x , Vector[i].y , Vector[i +1].x , Vector[i +1].y) If VectorToLine.Length() < Ball.Radius SetColor 255 , 0 , 0 'Just for fun SetScale 1.0 , 1.0 DrawText "\__ COLLIDE" , Ball.position.x , Ball.position.y ' Just for fun ' 2. Project out of collision 'Move backwards along the velocity vector until we are out of collision. ''''''''''''''''''''''''Local DistIntoWall = Ball.Radius - OverlapDist 'Make velocity unit vector '''''''Local ProjectVector:Vector2D = CreateUnitVector( BallVelocity ) '''''''ProjectVector.Reverse() Ball.Position.subtract( VectorToLine ) 'We are now right where we are supposed to be. (right before the wall) VectorToLine.Normalize() VectorToLine.Multiply( Ball.Radius - VectorToLine.Length() ) Ball.Position.add( VectorToLine ) ' 3. Get the line's surface normal Local Surface:Vector2D = Vector2D.CreateFrom( Vector[i] , Vector[i +1] ) Local SurfaceNormal:Vector2D = Surface.CreateRightNormal() 'BallVelocity = BallVelocity.Reflect( SurfaceNormal ) ' 4. Apply response on velocity ( reflect ) ApplyResponse( BallVelocity, SurfaceNormal, 0.00, 0.2 )' 0,0 would be Perfect Slide 'Now before we move we should check that this new Velocity does not collide in something else. Ball.Position.add( BallVelocity )' It is safe to move ( Not really!) ' Right now we only check against the remaining lines - which could be none or all ' End If Next EndFunction Function DistanceCircleLine( Circle:Circle2D, LineStart:Vector2D, LineEnd:Vector2D ) 'In progress EndFunction '----------------------------------------------------------------- ''''Collision Handling 'Calculated the distance from a point to a line Function MinDistPointLine!(px!,py!,x1!,y1!,x2!,y2!) ''This function found in Blitz's forum Code Archive If x1 = x2 And y1 = y2 Then Return PointToPointDist(px,py,x1,y1) Local sx! = x2-x1 Local sy! = y2-y1 Local q! = ((px-x1) * (x2-x1) + (py - y1) * (y2-y1)) / (sx*sx + sy*sy) If q < 0.0 Then q = 0.0 If q > 1.0 Then q = 1.0 Return PointToPointDist(px,py,(1-q)*x1+q*x2,(1-q)*y1 + q*y2) End Function '----------------------------------------------------------------- Function pointToPointDist!(x1! , y1! , x2! , y2!) Return Sqr( (x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1) ) End Function Function VectorToLine:Vector2D(px!,py!,x1!,y1!,x2!,y2!) If x1 = x2 And y1 = y2 Then Return Vector2D.Create( x1-px, y1-py ) Local sx! = x2-x1 Local sy! = y2-y1 If sx = 0 And sy = 0 Then Return Local q! = ((px-x1) * (x2-x1) + (py - y1) * (y2-y1)) / (sx*sx + sy*sy) If q < 0.0 Then q = 0.0 If q > 1.0 Then q = 1.0 Local Xx! = (1-q)*x1 + q*x2 Local Xy! = (1-q)*y1 + q*y2 Return Vector2D.Create(Xx - Px, Xy - Py ) End Function Rem Friction! from 0 to 1 ; 1 = Total Friction (get stuck), 0 = No Friction Elasticy! from 0 to 1 ; 1 = Perfect Bounce, 0 = No Bounce USE: If CollideSurface( SurfaceNormal,....) ApplyResponse( Tank.Velocity, SurfaceNormal, 0, 0.5 ) Endif EndRem Function ApplyResponse( Velocity:Vector2D Var, SurfaceNormal:Vector2D, Friction!, Elasticity! ) SurfaceNormal.Normalize() Velocity.Mirror( SurfaceNormal ) If Elasticity < 0 Then Elasticity = 0'Slide If Elasticity > 1 Then Elasticity = 1'Perfect Bounce Local Bounce:Vector2D = CreateVector(0,0) Bounce.ProjectionOf( Velocity, SurfaceNormal ) Bounce.Multiply( Elasticity ) ' Apply Elasticy, to the perpendicular part of velocity If Friction < 0 Then Friction = 0 If Friction > 1 Then Friction = 1 Friction = 1 - Friction'' Case 1, now: 0, Case 0, now: 1 Local Slide:Vector2D = CreateVector() SurfaceNormal.MakeLeftNormal()'Convert the normal to the surface! Slide.ProjectionOf( Velocity, SurfaceNormal )' Project to surface Slide.Multiply( Friction ) ' Apply Friction, to the parallel part of velocity Velocity.Set(0,0) Velocity.Add( Slide ) Velocity.Add( Bounce ) 'FOR DEBUGGING ONLY ' SetColor 0,0,255'GREEN ' Slide.Draw ( Ball.Position ) ' SetColor 255,255,0'YELLOW ' Bounce.Draw ( Ball.Position ) EndFunction