TGC Codebase Backup



Timer() controlled BALL Physics demo by walaber

14th Jan 2004 9:35
Summary

A simple 2D example of trajectory physics. throw a ball around in a room an watch it bounce off the walls with friction and gravity. timer controlled to ensure performance on a wid



Description

no media is required. This is basically aimed at beginners who want to see an example of simple gravity, etc. also useful for learning how to make your game run the same speed on different speed systems, using a very simple timer() technique!

play around with the various settings at the beginning of the program and see the results! you can adjust the gravity, bounciness of the ball, even add basic wind!



Code
                                    ` This code was downloaded from The Game Creators
                                    ` It is reproduced here with full permission
                                    ` http://www.thegamecreators.com
                                    
                                    REMSTART

	This is a simple BALL physics program... there are a couple progams
	like this one in the codebase, But this one incorporates the timer()
	to maintain the same ball speed regardless of system speed, which I
	think makes it stand out.
	
	This program is still pretty simple, it could be adjusted to have the
	ball bounce off of oddly shaped objects, air friction could be added, etc.
	
	If the codes helps you in any way, I'm glad!  if you have any questions
	or comments (especially improvements) e-mail me at tfitzrandolph@yahoo.co.jp
	
	thanks, Walaber
REMEND


sync on : sync rate 0
set display mode 640,480,32

`just some constants to make handling the code easier!
#constant Ready = 1
#constant Flying = 2
#constant Resetting = 3


` OK these types are exactly the same, I separated them solely because I think it's good to keep
` positions ans vectors separate in my head!
Type 2DVector
x as float
y as float
ENDTYPE

Type 2DPoint
x as float
y as float
ENDTYPE

TYPE Object
status as byte
Pos as 2DPoint
Vel as 2DVector
ENDTYPE

`Initialize the BALL (that circle on the screen) object with its current status, etc.
Ball as Object

Ball.Pos.x = 30
Ball.Pos.y = 380
Ball.Vel.x = 0
Ball.Vel.y = 0
Ball.status = Ready

startangle = -45
startvel = 10

Gravity as 2DVector
Gravity.y = 1000
`In This case Gravity has no effect on the X component... you can try changing this value
`to create a wind-like effect on the ball! 
Gravity.x = 0
` because of my timer() system, the units above (and everywhere else) are UNITS(pixels) PER SECOND!


` percentage of energy retained when the ball bounces (loss of energy due to friction/etc)
` you can try changing this value to see the effects on the ball too.
bounceconstant# = 0.80

`just to make sure the first loop has a valid ElapsedInSec# value
oldtimer = timer() - 100


` MAIN LOOP!!!!
do

	` Calculate the amout of time that has elapsed since the last program loop...
	Elapsed = (timer() - oldtimer) : ` time elapsed in MILLISECONDS
	oldtimer = timer()
	
	ElapsedInSec# = Elapsed / 1000.0 : ` time elapsed in SECONDS
	
	
	cls
	
	` HANDLE THE BALL....
	select Ball.status 
		` USER IS SETTING THE ANGLE AND VELOCITY OF THE BALL...
		case Ready
			startangle = wrapvalue(startangle+(downkey()-upkey()))
			inc startvel, (rightkey()-leftkey())
			
			`X and Y components of the angle				
			currentx = cos(startangle) * startvel
			currenty = sin(startangle) * startvel					
			
			`USER wants to throw the BALL...
			if returnkey()
				Ball.Vel.x = currentx * 10 : `this makes the velocity more reasonable (x10)
				Ball.Vel.y = currenty * 10
				Ball.status = Flying
				start = timer()
			endif
						
			` Update the screen with the ball, angle indicator, walls, etc
			circle Ball.Pos.x,Ball.Pos.y,5			
			line Ball.Pos.x,Ball.Pos.y,Ball.Pos.x+currentx,Ball.Pos.y+currenty			
			line 0,400,639,400
			line 0,20,639,20
			line 620,20,620,400
			line 20,20,20,400
			
			text 10,410,"Angle: "+str$(wrapvalue(360-startangle))
			text 10,420,"Velocity: "+str$(startvel)	
			text 10,430,"UP/DOWN to change angle, RIGHT/LEFT to change velocity"
			text 10,440,"Press RETURN to throw the BALL!!!!"	
		endcase
		
		` BALL is flying through the air, calculate its variables.
		case Flying
			inc Ball.Vel.x,Gravity.x * ElapsedInSec# : `subtract gravity
			inc Ball.Vel.y,Gravity.y * ElapsedInSec#
			
			inc Ball.Pos.x,Ball.Vel.x * ElapsedInSec# : `calculate new position
			inc Ball.Pos.y,Ball.vel.y * ElapsedInSec#
			
			` check for if the ball hits any of the walls...
			if Ball.Pos.y > 395
				Ball.Pos.y = 395
				Ball.Vel.y = Ball.Vel.y * ((-1)*bounceconstant#)
				Ball.Vel.x = Ball.Vel.x * bounceconstant#
			endif
			
			if Ball.Pos.y < 25
				Ball.Pos.y = 25
				Ball.Vel.y = Ball.Vel.y * ((-1)*bounceconstant#)
				Ball.Vel.x = Ball.Vel.x * bounceconstant#
			endif
			
			if Ball.Pos.x < 25
				Ball.Pos.x = 25
				Ball.Vel.x = Ball.Vel.x * ((-1)*bounceconstant#)
				Ball.Vel.y = Ball.Vel.y * bounceconstant#
			endif
			
			if Ball.Pos.x > 615
				Ball.Pos.x = 615
				Ball.Vel.x = Ball.Vel.x * ((-1)*bounceconstant#)
				Ball.Vel.y = Ball.Vel.y * bounceconstant#
			endif
			
			`if the ball is out of energy, then RESET!
			if Ball.Pos.y = 395.0
				if Ball.Vel.y < 0.0 and abs(Ball.Vel.x) < 0.05 then Ball.status = Resetting : finish = timer()
			endif
			
			` update screen...
			circle Ball.Pos.x,Ball.Pos.y,5			
			line 0,400,639,400
			line 0,20,639,20
			line 620,20,620,400
			line 20,20,20,400
			
			text 10,410,"XVel: "+str$(Ball.Vel.x)
			text 10,420,"YVel: "+str$(Ball.Vel.y)
			text 10,430,"Elap: "+str$(ElapsedInSec#)
		endcase
		
		` Ball has died, reset the variables!
		case Resetting
			if returnkey()
				Ball.Pos.x = 30
				Ball.Pos.y = 380
				Ball.Vel.x = 0
				Ball.Vel.y = 0

				startangle = -45
				startvel = 10
			
				Ball.status = Ready
				
				repeat
				until returnkey()=0
			endif
			
			circle Ball.Pos.x,Ball.Pos.y,5			
			line 0,400,639,400
			line 0,20,639,20
			line 620,20,620,400
			line 20,20,20,400
							
			text 10,410,"TimeElapsed: "+str$((finish-start)/1000.0)+" seconds"
			text 10,420,"PRESS RETURN..."
						
		endcase
	endselect

	text 300,410,"FPS "+str$(screen fps())
	sync
loop