2D Physics: Ideas for a Community Project

BlitzMax Forums/BlitzMax Programming/2D Physics: Ideas for a Community Project

A simple demo with only very simple vector math. Don't look to much at the code, I was lazy when I did this, see this only as a first demo.

Tech Demo
' Have a ball that is affected by grafity and bounces against the sides of the screen
' Make the ball apply an acceleration towards your mouse
' Bigger the further away, but only if the ball is below the mouse!
Strict 

Type Vector
	Field X#,Y#
		
	Function Create:Vector( X#=0, Y#=0 )
		Local NewVector:Vector = New Vector
		NewVector.X = X
		NewVector.Y = Y
		Return NewVector
	EndFunction
	
	Method Add( OtherVector:Vector ) X:+ OtherVector.X ; Y:+ OtherVector.Y EndMethod
	
	Method Multiply( Value# ) X:*Value; Y:*Value	EndMethod

	Method Visulize( Start:Vector , Multiply# = 20 , Xtra = 0)
		DrawLine Start.X + Xtra, Start.Y, Start.X + Xtra + X* Multiply , Start.Y + Y* Multiply 
	EndMethod
	
'	Method Draw( Start:Vector )
'		DrawLine Start.X, Start.Y, Start.X + X , Start.Y + Y 		
'	EndMethod

	Method ReverseX() 	X = -X EndMethod
	
	Method ReverseY() 	Y = -Y EndMethod
	
	Method Set( X#=0, Y#=0) Self.X = X;Self.Y = Y	EndMethod

	Method Length#() 
		Return Sqr( X*X + Y*Y )'Pythagoras
	EndMethod
	
	Method VectorFrom( Position1:Vector , Position2:Vector)
		X = ( Position2.X - Position1.X ) 	
		Y = ( Position2.Y - Position1.Y )		
	EndMethod
	
	'Decrease a vector until it is zero
	Method Break( Amount# )
		If Amount = 0 Return'We don't brake..
		If Amount >= Length(); Self.Set(0,0) Return'No matter how much you brake you'll never go backwards
						
		Local Break:vector = Vector.Create( X / Length() , Y / Length() )
		Break.Multiply( -Amount# )
		Self.Add( Break )	
	EndMethod
End Type


Type TBounceBall

	Field TopLeft:Vector	'Not in use, I think
	Field Position:Vector 		
	Field Velocity:Vector 		'I hope these are self-explainatory
	Field Acceleration:Vector
	Field Force:Vector
	Field Mass#			
	Field Radius 'Size of ball
	
	Method New()
		TopLeft		= Vector.Create( 0 , 0)
		Position 		= Vector.Create( 50, 250)
		Velocity 		= Vector.Create( 0 , 0)
		Acceleration 	= Vector.Create()
		Force		= Vector.Create()
		Radius		= 30
		Mass 		= 1
	EndMethod
	
	Method Draw( )
		DrawOval( Position.X - Radius/2, Position.Y - Radius/2, Radius, Radius )
		'Draws a oval around the ball's position
		'If I wouldn't take X - radius/2 the oval would be draw from the middle.. Try it
	EndMethod
	
	Method Update()
		Force.Multiply( Float(1.0/Mass) )
		Acceleration.Add( Force )' a = F/m  ; F =  m*a ; m = F/a
		Velocity.Add( Acceleration )
		Position.Add( Velocity )		
									
		' D I S P L A Y    V E C T O R S	
		'-----------------------------------------------------					
		'Draw and magnify the vectors so we can see them		
		'_____________________________________________________
		SetColor 0,255,0
		DrawText "GREEN Vector is the Velocity Vector"+Velocity.Length(),10,80
		Velocity.Visulize( Position ,4 )
							
		SetColor 255,0,0
		DrawText "RED Line is the Acceleration Vector. Lenght: "+Acceleration.Length(),10,50
		Acceleration.Visulize( Position  ,50, -1)
		'_____________________________________________________
		
		SetColor 255,255,255
		
		Force.Set
		Acceleration.Set			
		'Velocity.Set
		
	EndMethod	
	
	Method CollideWalls()
		If Position.X < 0' And Velocity.X > 0'Left
			CollideVerticalWall( 0 )		
		Else If Position.X > GraphicsWidth()' And Velocity.X < 0'Right
			CollideVerticalWall( GraphicsWidth() )	
		Else If Position.Y < 0' And Velocity.Y > 0'Top
			CollideHorisontalWall( 0 )		
		Else If Position.Y > GraphicsHeight() 'And Velocity.Y < 0'Bottom
			CollideHorisontalWall( GraphicsHeight() )	
		EndIf		

	EndMethod
	
	Method CollideVerticalWall( WallX )
			Velocity.ReverseX()
			Velocity.Multiply(0.8)' Fotball bounce - 1 for super bounce, 0 for no bounce
			Acceleration.ReverseX()			
			Local DistanceIntoWall = (Position.X - WallX) 
			Position.X:- 2*DistanceIntoWall		
	EndMethod
	
	Method CollideHorisontalWall( WallY )
			Velocity.ReverseY()
			Velocity.Multiply(0.8)' Fotball bounce 0.5 - 1 for super bounce, 0 for no bounce
			Acceleration.ReverseY()			
			Position.Y:- 2*(Position.Y - WallY) ' (Position.Y - WallY) = DistanceIntoWall		
	EndMethod
	
EndType




Local Ball:TBounceBall = New TBounceBall
Local MousePosition:Vector = Vector.Create( MouseX(), MouseY() )
Local MouseForce:Vector    = Vector.Create()
Local GravityAcc:Vector    = Vector.Create( 0 , 0.2 ) 'Constant Acceleration Downwards

Local Gravity = False 'Activate with [ G ] key
Local Friction = False 'Toggle Friction [ F ] Key

Graphics 500,500,0 'Window debug Mode

While Not KeyDown(Key_Escape)
	
	MousePosition.Set MouseX() , MouseY()
	MouseForce.VectorFrom( Ball.Position, MousePosition )
	MouseForce.Multiply( 0.01 )'0.1%

	If KeyDown( Key_MouseLeft ) Ball.Force.Add( MouseForce )
	If KeyDown( Key_X ) Ball.Force.X = 2
	If KeyDown( Key_A ) Ball.Velocity.X = 2
	If KeyDown( Key_Z ) Ball.Acceleration.X = 2
	


	If KeyHit( Key_G )
		If Gravity = False Then Gravity = True Else Gravity = False
	EndIf
			
	If Gravity
		Ball.Acceleration.Add( GravityAcc )
		'We only have one object
		'In a normal case you would loop this for every object affected by gravity
		'NOTE: Gravity is an accleration; independant of Mass - it is not a force!
	EndIf
	
	If KeyHit( Key_F ) 	
		If Friction = False Then Friction= True Else Friction = False
	EndIf
	
	If Friction'Apply Friction unless SPACE is hold down
		Ball.Velocity.Break( 0.1 )'FRICTION
		'This is not very good air friction, but should work
		'good for pool balls or rolling minigolf balls.
	EndIf

	
	Ball.Draw		' Draw Ball
	
	SetColor 0,0,255
	DrawText "All BLUE Lines is Force Vectors",10,20
	SetColor 0,100,255
	MouseForce.Visulize( Ball.Position, 10 )		
	SetColor 25,25,155
	Ball.Force.Visulize( Ball.Position, 10 )	

	Ball.Update	' Update the balls velocity, acceleration and position
	Ball.CollideWalls

	DrawText "Press G to Toggle Gravity ON/OFF",10,150
	DrawText "Press F to Toggle Friction ON/OFF",10,180
	DrawText "Press LeftMouse to draw the ball toward the cursor",10,210
		
	DrawText "MEM: "+MemAlloced(),10,GraphicsHeight()-20
	
	Flip;Cls;FlushMem
Wend