Ball physics

Blitz3D Forums/Blitz3D Beginners Area/Ball physics

Ash_UK(Posted 2004) [#1]
Hi there could anyone please show how to go about programming ball physics. I have wanted to do this for a while now, but can't find the help anywhere. I would really appriciate it also if you could show me a code example (such as two balls bouncing properly around the screen and collision with the balls), thankyou very much for any help.

DeViL


Stevie G(Posted 2004) [#2]
Someone elses code ... I forget who ?? It handles purely elastic collisions ..

Graphics3D 640,480,16,1

Const C_BALL = 1
Const C_CUBE = 2
Const BALLS = 50
Const SPEED# = .5

Global camera,cube
Global light =CreateLight()

Type ball
	Field entity
	Field xvel#,yvel#,zvel#
End Type

Collisions C_BALL, C_BALL,1,1
Collisions C_BALL, C_CUBE,2,1

MakeStuff()

While Not KeyDown(1)

	UpdateBalls()
	UpdateWorld()
	RenderWorld()
	Flip
	
Wend

;==============================================
;==============================================
;==============================================

Function MakeStuff()
	
	;cube
	cube = CreateCube()
	ScaleMesh cube,30,30,30
	FlipMesh cube
	EntityColor cube,50,50,200
	EntityType cube,C_CUBE
	UpdateNormals cube
	
	;camera
	camera = CreateCamera()
	PositionEntity camera,0,60,0
	PointEntity camera, cube
	
	;template for balls
	temp = CreateSphere()
	EntityType temp,C_BALL
	UpdateNormals temp
	EntityShininess temp,1
	HideEntity temp
		
	;balls
	For l = 1 To BALLS
		b.ball = New ball
		b\xvel = Rnd(-SPEED,SPEED)
		b\yvel = Rnd(-SPEED,SPEED)
		b\zvel = Rnd(-SPEED,SPEED)
		b\entity = CopyEntity( temp )
		PositionEntity b\entity,Rnd(-30,30),Rnd(-30,30), Rnd(-30,30)
		EntityColor b\entity,Rand(100,255),Rand(100,255),Rand(100,255)
		radius# = Rnd( 1,4 )
		ScaleEntity b\entity,radius,radius,radius
		EntityRadius b\entity,radius
	Next

End Function

;==============================================
;==============================================
;==============================================

Function UpdateBalls()

	For b.ball = Each ball
	
		For i = 1 To CountCollisions(b\entity)
			HandleBounce(b,i)
		Next
		
		TranslateEntity b\entity,b\xvel,b\yvel,b\zvel
		
	Next

End Function

;==============================================
;==============================================
;==============================================

Function HandleBounce(b.ball,i)
	
	; Get the normal of the surface collided with. 
	Nx# = CollisionNX(b\entity, i) 
	Ny# = CollisionNY(b\entity, i) 
	Nz# = CollisionNZ(b\entity, i) 
			
	; Compute the dot product of the ball's motion vector and the normal of the surface collided with. 
	VdotN# = b\xvel*Nx + b\yvel*Ny + b\zvel*Nz 
	
	; Calculate the normal force. 
	NFx# = -2.0 * Nx# * VdotN 
	NFy# = -2.0 * Ny# * VdotN 
	NFz# = -2.0 * Nz# * VdotN 
	
	; Add the normal force to the motion vector. 
	b\xvel = b\xvel + NFx
	b\yvel = b\yvel + NFy
	b\zvel = b\zvel + NFz
	
End Function




Ash_UK(Posted 2004) [#3]
Thankyou very much Stevie, i will have a look at this and see if i can work it out :-).
Thankyou for helping me out, it's very much appriciated.

DeViL


big10p(Posted 2004) [#4]
I found this demo on my hard disc by Vincent DeCampo:

;
; Bouncing ball physics - by Vincent DeCampo 2/1/04
;

Const GRAVITY#=-.05
Const BALLS=1

Graphics3D 640,480

;*** Type for Ball ***
Type Ball_Object
	Field Entity
	Field Pivot
	Field x#
	Field y#
	Field z#
	Field dx#
	Field dy#
	Field dz#
	Field xMin#
	Field xMax#
	Field yMin#
	Field yMax#
	Field zMin#
	Field zMax#
	Field elasticity#
	Field friction#
End Type

;*** Lets create the floor ***
Room=CreateTerrain(64)
PositionEntity room,-32,0,-32
EntityColor Room, 0, 150, 0

;******* Create Initial Ball ******
Blitz.Ball_Object = New Ball_Object
InitBallVars(Blitz)
Collisions BALLS, BALLS, 1, 2

;***** Create Camera *****
camera=CreateCamera()
PositionEntity camera,0,5,-40
PointEntity camera, Blitz\Entity

;**********************************
;			 Main Loop
;**********************************
;
While Not KeyHit(1)

	If KeyHit(57) Then

		;***** Seed RND Generator *****
		SeedRnd (MilliSecs())
		
		;*** Create New Ball ***
		Blitz.Ball_Object = New Ball_Object	
		InitBallVars Blitz

	End If

	;**** Perform Room Physics ****
	For Ball.Ball_Object = Each Ball_Object
		BallPhysics (Ball)		
	Next

	UpdateWorld	

	;**** Perform Ball-on-Ball Physics ****
	CheckCollisions (Blitz)
		
	RenderWorld 
RenderWorld
	Text 0,5,"Press SPACE to throw another ball"
	Text 0,15,"Press ESC to Exit" + TrisRendered()

	Flip 1
Wend

End
Function Flipper() 
While ScanLine()<>0: Wend 
Flip False 
End Function 
;**********************************

Function CheckCollisions (Ball.Ball_Object)

	For C.Ball_Object = Each Ball_Object
				
		If EntityCollided(c\Entity, BALLS)
					
			For i = 1 To CountCollisions(c\Entity)

				Ent=CollisionEntity (c\Entity, i)

				;Get the normal of the surface which the entity collided with. 
				Nx# = CollisionNX(c\Entity, i) 
				Ny# = CollisionNY(c\Entity, i) 
				Nz# = CollisionNZ(c\Entity, i) 
			
				;Compute the dot product of the entity's motion vector And the normal of the surface collided with. 				
				VdotN# = (c\dx# * Nx# + c\dy# * Ny# + c\dz# * Nz#)
									
				;Calculate the normal force. 
				NFx# = -2.0 * Nx# * VdotN# 
				NFy# = -2.0 * Ny# * VdotN# 
				NFz# = -2.0 * Nz# * VdotN# 
										
				;Add the normal force to the direction vector. 
				c\dx# = c\dx# + NFx#/2
				c\dy# = c\dy# + NFy#/2	;Force /2 assumes balls equal in mass
				c\dz# = c\dz# + NFz#/2
								
				For Hit.Ball_Object = Each Ball_Object

					If Hit\Entity = Ent Then
						
						;Add negative force to collision entity vector		
						Hit\dx# = Hit\dx# - NFx#/2
						Hit\dy# = Hit\dy# - NFy#/2	;Force /2 assumes balls equal in mass
						Hit\dz# = Hit\dz# - NFz#/2		
											
					End If
																									
				Next

			Next
												
		EndIf
		
	Next
							
End Function

;**********************************

Function InitBallVars(Ball.Ball_Object)

	;Create Ball
	Ball\Entity=CreateSphere()
	ScaleEntity Ball\Entity, 1,1,1
	EntityType Ball\Entity, BALLS

	;txt=LoadTexture("blitzlogo.bmp")
	;EntityTexture Ball\Entity, txt
	
	;Create Pivot
	Ball\Pivot=CreatePivot()
	
	;*** Variables for Ball ***	
	Ball\x#=0
	Ball\y#=20	;set ball 20 units above floor
	Ball\z#=0
	Ball\dx#=Rand(5)
	Ball\dy#=0	;at rest
	Ball\dz#=Rand(5)
	Ball\yMin#=1
	Ball\yMax#=9999
	Ball\xMin#=-32
	Ball\xMax#=32
	Ball\zMin#=-32
	Ball\zMax#=32
	Ball\elasticity#=.75	;value from >0 to <1 (1=pure elastic collision)
	Ball\friction#=.01
	;**************************

End Function

;**********************************

Function BallPhysics (Ball.Ball_Object)

	If ball\y   =< Ball\yMin# Then
		Ball\y  =  Ball\yMin#
		Ball\dy = -Ball\dy
		Ball\dy =  Ball\dy * Ball\elasticity
	End If

	If Ball\x   =< Ball\xMin# Then
		Ball\x  =  Ball\xMin#
		Ball\dx = -Ball\dx
		Ball\dx =  Ball\dx * Ball\elasticity
		UpdatePivot (Ball)
	End If

	If  Ball\x >=  Ball\xMax# Then
		Ball\x  =  Ball\xMax#
		Ball\dx = -Ball\dx
		Ball\dx =  Ball\dx * Ball\elasticity
		UpdatePivot (Ball)
	End If
	
	If Ball\z   =< Ball\zMin# Then
		Ball\z  =  Ball\zMin#
		Ball\dz = -Ball\dz
		Ball\dz =  Ball\dz * Ball\elasticity
		UpdatePivot (Ball)
	End If

	If Ball\z  >=  Ball\zMax# Then
		Ball\z  =  Ball\zMax#
		Ball\dz = -Ball\dz
		Ball\dz =  Ball\dz * Ball\elasticity
		UpdatePivot (Ball)
	End If
	
	If Ball\y  >= Ball\yMin# Then
		Ball\dy = Ball\dy + GRAVITY
	End If	

	Ball\x = Ball\x + Ball\dx
	Ball\z = Ball\z + Ball\dz
	Ball\y  = Ball\y + Ball\dy

	Ball\dx = Ball\dx - (Ball\dx*Ball\friction)
	Ball\dz = Ball\dz - (Ball\dz*Ball\friction)

	;Move ball to new coords
	PositionEntity  Ball\Entity, Ball\x, Ball\y, Ball\z, 0

	;Rotate mesh to give appearance of rolling	
	TurnEntity Ball\Entity, Ball\dz*50,0,-Ball\Dx*50, 1
			
End Function

Function UpdatePivot (Ball.Ball_Object)

	;Move pivot to coords + deltas
	PositionEntity Ball\Pivot, Ball\x+Ball\dx, Ball\y+Ball\dy, Ball\z+Ball\dz
	
	PointEntity Ball\Entity, Ball\Pivot, 0		

End Function



Ash_UK(Posted 2004) [#5]
Thankyou so much for all kind help. Is there any way to translate this to 2d as it's a 2d game i'm making :)
Thankyou again in advance.

DeViL


WolRon(Posted 2004) [#6]
it's a 2d game i'm making
Don't you think you should have mentioned this FIRST?


..........


WolRon(Posted 2004) [#7]
it's a 2d game i'm making
Don't you think you should have mentioned this FIRST?


..........


WolRon(Posted 2004) [#8]
it's a 2d game i'm making
Don't you think you should have mentioned this FIRST?


..........


ashmantle(Posted 2004) [#9]
heh.. its easy, just remove one of the dimensions.. like Z or something.. all the same calculations still apply.


Ash_UK(Posted 2004) [#10]
Yes, you're right WolRon, i should have mentioned it to begin with, my appologies everyone :]

DeViL


Ash_UK(Posted 2004) [#11]
Could possibly tell me how to do 2d breakout-style physics for a ball please?

DeViL


QuietBloke(Posted 2004) [#12]
look in the code archives.. under algorithms.. there are a few examples of 2d collisions.. ball collisions and ball and line collisions. That should get you up and running.


Ash_UK(Posted 2004) [#13]
Thankyou quietbloke, i really appriciate your help :)

DeViL