Code archives/Algorithms/Vectors part 5

This code has been declared by its author to be Public Domain code.

Download source code

Vectors part 5 by Jesse2011
ball to circular wall collision and response.
based on tutorials by TonyPa: http://tonypa.pri.ee/vectors/tut09.html
'*************************************************************
'  Ball to roundWall Collision
'
'  author: Jesus Perez
' created: 10/11/2010
' based on tutorial Vectors for Flash by TonyPa
' tutorial located at: http://tonypa.pri.ee/vectors/tut09.html
'*************************************************************


SuperStrict


'Create game Object
Global game:Tgame = Tgame.Create(300, 180, 10)
'Function To draw the points And balls
Graphics game.stageW,game.stageH

Repeat
	Cls
	runMe()
	Flip()
Until KeyDown(key_escape)


Type Tpoint
	Field x:Float
	Field y:Float
End Type

Type Tvector
	Field p0:Tpoint
	Field p1:Tpoint
	Field vx:Float
	Field vy:Float
	Field dx:Float
	Field dy:Float
	Field length:Float
	Field rx:Float
	Field ry:Float
	Field lx:Float
	Field ly:Float
	
	Field b:Float
	Field f:Float
	
	Method New()
		p0 = New Tpoint
		p1 = New Tpoint
	End Method

End Type

Type TroundWall Extends Tvector
	Field r:Float
	
	Function Create:TroundWall(x:Float,y:Float,r:Float)
		Local w:TroundWall = New TroundWall
		w.p0.x = x
		w.p0.y = y
		w.r = r
		Return w
	End Function 
	
End Type

Type Tball Extends Tvector
	Field r:Float
	Field lastTime:Float
	Field timeFrame:Float
	
	Function Create:Tball(x:Float,y:Float,r:Float,vx:Float,vy:Float)
		Local b:Tball = New Tball
		b.p0.x = x
		b.p0.y = y
		b.r = r
		b.vx = vx
		b.vy = vy
		b.lastTime = MilliSecs()
		Return b
	End Function
End Type

Type Tgame
	Field stageW:Float
	Field stageH:Float
	Field maxV:Float
	Field ball:Tball
	Field wall:TroundWall[4]
	Field gravity:Float
	
	
	Function Create:Tgame(w:Float,h:Float,MaxV:Float)
		Local g:Tgame = New Tgame
		g.stageW = w
		g.stageH = h
		g.maxV = maxV
		'Create Object
		'point p0 is its starting point in the coordinates x/y
		g.ball = Tball.Create(150,30,20,5,5)
		g.ball.lastTime = MilliSecs()
		
		g.wall[0] = TroundWall.Create(100, 100, 30)
		g.wall[1] = TroundWall.Create(200, 100, 40)
		g.wall[2] = TroundWall.Create(250, 50, 20)
		g.wall[3] = TroundWall.Create(50, 100, 15)
		g.gravity = 0
		Return g		
	End Function
	
End Type


Function drawAll()
	Local b:Tball = game.ball
	For Local w:TroundWall = EachIn game.wall
		drawCircle(w.p0.x,w.p0.y,w.r)
	Next
	drawCircle(b.p0.x,b.p0.y,b.r)
End Function
'Main Function
Function runMe()

	'start To calculate movement
	Local ob:Tball = game.ball
	'dont let it go over Max speed
	If (ob.vx>game.maxV)
		ob.vx = game.maxV
	Else If (ob.vx<-game.maxV)
		ob.vx = -game.maxV
	EndIf
	If (ob.vy>game.maxV)
		ob.vy = game.maxV
	Else If (ob.vy<-game.maxV)
		ob.vy = -game.maxV
	EndIf
	'update the vector parameters
	updateObject(ob)
	'check the balls For collisions
	For Local w:TroundWall = EachIn game.wall
	
		Local v:Tvector = ball2ball(ob, w)
		Local pen:Float = ob.r+w.r-v.length
		'If we have hit the ball
		If (pen>=0)
		
			'move Object away from the ball
			ob.p1.x :+ v.dx*pen
			ob.p1.y :+ v.dy*pen
			'change movement, bounce off from the normal of v
			Local vbounce:Tvector = New Tvector
			vbounce.dx =  v.dy
			vbounce.dy = -v.dx
			vbounce.lx = v.dx
			vbounce.ly = v.dy
			Local vb:Tvector = bounce(ob, vbounce)
			ob.vx = vb.vx
			ob.vy = vb.vy
		EndIf
	Next
	'reset Object To other side If gone out of stage
	If (ob.p1.x>game.stageW+ob.r)
		ob.p1.x = -ob.r
	Else If (ob.p1.x<-ob.r)
		ob.p1.x = game.stageW+ob.r
	EndIf
	If (ob.p1.y>game.stageH+ob.r)
		ob.p1.y = -ob.r
	Else If (ob.p1.y<-ob.r)
	
		ob.p1.y = game.stageH+ob.r
	EndIf
	'draw it
	drawAll()
	'make End point equal To starting point For Next cycle
	ob.p0 = ob.p1
	'save the movement without time
	ob.vx :/ ob.timeFrame
	ob.vy :/ ob.timeFrame
End Function

Function updateObject(v:Tball)

	'find time passed from last update
	Local thisTime:Float = MilliSecs()
	Local time:Float = (thisTime-v.lastTime)/100
	'we use time, Not frames To move so multiply movement vector with time passed
	v.vx :* time
	v.vy :* time
	'add gravity, also based on time
	v.vy = v.vy+time*game.gravity
	'find End point coordinates
	v.p1.x = v.p0.x+v.vx
	v.p1.y = v.p0.y+v.vy
	'length of vector
	v.Length = Sqr(v.vx*v.vx+v.vy*v.vy)
	'normalized unti-sized components
	v.dx = v.vx/v.length
	v.dy = v.vy/v.length
	'Right hand normal
	v.rx = -v.vy
	v.ry = v.vx
	'Left hand normal
	v.lx = v.vy
	v.ly = -v.vx
	'save the Current time
	v.lastTime = thisTime
	'save time passed
	v.timeFrame = time
End Function

'find collision of 2 balls
Function ball2ball:Tvector(b1:Tvector, b2:Tvector)

	'vector between centers of balls
	Local v3:Tvector = New Tvector
	v3.vx = b1.p1.x-b2.p0.x
	v3.vy = b1.p1.y-b2.p0.y
	v3.length = Sqr(v3.vx*v3.vx+v3.vy*v3.vy)
	v3.dx = v3.vx/v3.length
	v3.dy = v3.vy/v3.length
	Return v3
End Function

'find New vector bouncing from v2
Function bounce:Tvector(v1:Tvector, v2:Tvector)

	'projection of v1 on v2
	Local proj1:Tvector = projectVector(v1, v2.dx, v2.dy)
	'projection of v1 on v2 normal
	Local proj2:Tvector = projectVector(v1, v2.lx, v2.ly)
	Local proj:Tvector = New Tvector
	'reverse projection on v2 normal
	proj2.length = Sqr(proj2.vx*proj2.vx+proj2.vy*proj2.vy)
	proj2.vx = v2.lx*proj2.length
	proj2.vy = v2.ly*proj2.length
	'add the projections
	proj.vx = proj1.vx+proj2.vx
	proj.vy = proj1.vy+proj2.vy
	Return proj
End Function
'project vector v1 on unit-sized vector dx/dy
Function projectVector:Tvector(v1:Tvector, dx:Float, dy:Float)

	'find dot product
	Local dp:Float = v1.vx*dx+v1.vy*dy
	Local proj:Tvector = New Tvector
	'projection components
	proj.vx = dp*dx
	proj.vy = dp*dy
	Return proj
End Function

Function drawcircle(x:Float,y:Float,r:Float)
	For Local a:Float = 0 Until 360
		Local vx:Float = Cos(a)*r
		Local vy:Float = Sin(a)*r
		Plot x+vx,y+vy
	Next
End Function

Comments

None.

Code Archives Forum