Random Color Balls Bouncing on Stage

Wed, Jan 25, 2012

ActionScript, Scripts

Random Color Balls Bouncing on Stage

This is a great grain to several possible games and even effects.

  • Creates predefined number of balls
  • Generates Different Colors
  • Keeps the balls moving and bouncing  inside the frame.

The script has 3 Actionscript Files:

  1. One main file that commands ball creation and enables bouncing evironment
  2. Ball Class
  3. Physics and Friction Environment

This movie requires Flash Player 9

Our source is extensively documented explaining each line and what every function does. It also explains variations and what each variable represents. By downloading you get quality, specific source code that can be used, re used, with technical support. The package comes wiht 4 files, 1 FLA main file and 3 actionscript files organized to run on the first try!

Download AS3 Random Color Bouncing Balls: $5

The code is divided in 3 Actionscript files here is the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 * Main Actionscript
 * ---------------------
 * VERSION: 1.5
 * DATE: 01/31/2012
 * AS3
 * UPDATES AND DOCUMENTATION AT: http://www.say-web.com
 **/
package
{
	import flash.display.MovieClip;
	import com.sayweb.SimplePhysics;
 
	public class Main extends MovieClip
	{
		// classes
		private var _physics:SimplePhysics
 
		public function Main()
		{
			// SimplePhysics usage:
			// new SimplePhysics(any_display_object);
			_physics = new SimplePhysics(container); // container is a movieclip on stage
 
			// create balls
			_physics.createBalls(5); // The script will place 5 balls. You may replace with any number
 
			// enable physics simulation
			_physics.enable();
		}
	}
 
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
 * Physics and Friction
 * ---------------------
 * VERSION: 1.3
 * DATE: 01/25/2012
 * AS3
 * UPDATES AND DOCUMENTATION AT: http://www.say-web.com
 **/
 
package com.sayweb
{
	import flash.display.DisplayObjectContainer;
	import com.sayweb.Ball;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.events.MouseEvent;
 
	public class SimplePhysics
 
	{
		// reference to container (stage, movieclip or sprite)
		private var _canvas:DisplayObjectContainer;
 
		// boundries
		private var _minX:int;
		private var _minY:int;
		private var _maxX:int;
		private var _maxY:int;
 
		// balls array
		private var _ballArray:Array = [];
 
		// settings
		private var _friction:Number = .98;
 
		/**
		 * Constructor
		 * @param	$canvas	Takes DisplayObjectContainer (MovieClip, Sprite, Stage)
		 */
		public function SimplePhysics($canvas:DisplayObjectContainer)
		{
			trace("SimplePhysics");
 
			_canvas = $canvas;
			setBoundries(_canvas);
		}
 
		/**
		 * Enables physics engine
		 */
		public function enable():void
		{
			_canvas.addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}
 
		/**
		 * Disables physics engine
		 */
		public function disable():void
		{
			_canvas.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
		}
 
		/**
		 * Sets container boundries
		 */
		public function setBoundries($container:DisplayObjectContainer):void
		{
			_minX = 0;
			_minY = 0;
			_maxX = $container.width;
			_maxY = $container.height;
		}
 
		/**
		 * Use this to create multiple balls
		 * @param	numberOfBalls	Number of balls to create
		 */
		public function createBalls(numberOfBalls:Number):void
		{
			trace("Create balls: " + numberOfBalls);
 
			for (var i:int = 0; i < numberOfBalls; i++)
			{
				createBall();
			}
		}
 
		/**
		 * Use this to create a single ball
		 */
		public function createBall():void
		{
			// Create new ball
			// precalculate ball properties
			var newX:Number = Math.random() * _maxX;
			var newY:Number = Math.random() * _maxY;
			var newSpeed:Number = 2;
			var newRadius:Number = Math.random() * 20 + 10;
			var newRotation:Number = Math.floor(Math.random() * 360);
 
			// Ball(x, y, radius, rotation, speed, mass)
			var ball:Ball = new Ball(newX, newY, newRadius, newRotation, newSpeed, newRadius);
 
			// test if ball can start here
			if (canStartHere(ball))
			{
				// add to display list
				_canvas.addChild(ball);
 
				// save ball in balls array
				_ballArray.push(ball)
			}
			// ball can't start here, try again
			else
			{
				createBall();
				return;
			}
		}
 
		/**
		 * Makes sure balls are not created inside other balls
		 * or outside container boundries
		 * @param	ball	Uses Ball object
		 * @return	true/false
		 */
		private function canStartHere(ball:Ball):Boolean
		{
			var retval:Boolean = true;
 
			// loop thru balls array
			for (var i:int = 0; i < _ballArray.length; i++) 			{ 				// don't test hit on self 				if (ball == _ballArray[i] as Ball) continue; 				 				// make sure we dont start inside another ball 				if (hitTestCircle(ball, _ballArray[i] as Ball)) 				{ 					retval = false; 				} 				 				// make sure we dont start outside the container 				if (ball.x + ball.radius > _maxX || ball.x - ball.radius < _minX) 				{ 					retval = false; 				} 				else if (ball.y + ball.radius > _maxY || ball.y - ball.radius < _minY)
				{
					retval = false;
				}
			}
 
			return retval;
		}
 
		/**
		 * Tests for collision between two Ball objects
		 * by calculating the distance between them
		 * @param	ball1	Uses Ball object
		 * @param	ball2	Uses Ball object
		 */
		private function hitTestCircle(ball1:Ball, ball2:Ball):Boolean
		{
			var retval:Boolean = false;
 
			var distance:Number = getDistance(ball1.x - ball2.x, ball1.y - ball2.y);
 
			if (distance <= (ball1.radius + ball2.radius))
			{
				retval = true;
			}
			return retval;
			 myBeep.play();
		}
 
		/**
		 * Update function that updates ball
		 */
		private function update():void
		{
			// define common vars
			var tempBall1:Ball;
			var i:int;
			var tempBall2:Ball;
			var k:int;
 
			// loop thru balls array
			for (i = 0; i < _ballArray.length; i++)
			{
				// save a reference to ball
				tempBall1 = _ballArray[i] as Ball;
 
				// check for collision with other balls
				for (k = 0; k < _ballArray.length; k++)
				{
					// save a reference to ball 2
					tempBall2 = _ballArray[k] as Ball;
 
					// make sure we dont test for collision against itself
					if (tempBall1 == tempBall2) continue;
 
					// check if balls are colliding by checking the distance between them
					if(hitTestCircle(tempBall1, tempBall2))
					{
						// calculate collision reaction
						collideBalls(tempBall1, tempBall2);
 
						// if balls are still touching after collision reaction,
						// try to move them apart
						if(hitTestCircle(tempBall1, tempBall2))
						{
							tempBall1.x += tempBall1.velocityX;
							tempBall1.y += tempBall1.velocityY;
							tempBall2.x -= tempBall1.velocityX
							tempBall2.y -= tempBall1.velocityY
						}
					}
				}
 
				// Bounce off walls
				// Check if we hit top
				if (((tempBall1.x - tempBall1.radius) < _minX) && (tempBall1.velocityX < 0)) 				{ 					// reverse velocity 					tempBall1.velocityX = -tempBall1.velocityX; 					  				} 				// Check if we hit bottom 				else if ((tempBall1.x + tempBall1.radius) > _maxX && (tempBall1.velocityX > 0))
				{
					// reverse velocity
					tempBall1.velocityX = -tempBall1.velocityX;
				}
				// Check if we hit left side
				if (((tempBall1.y - tempBall1.radius) < _minY) && (tempBall1.velocityY < 0)) 				{ 					// reverse velocity 					tempBall1.velocityY = -tempBall1.velocityY 				} 				// Check if we hit right side 				else if (((tempBall1.y + tempBall1.radius) > _maxY) && (tempBall1.velocityY > 0))
				{
					// reverse velocity
					tempBall1.velocityY = -tempBall1.velocityY;
				}
 
				// apply friction to ball velocity
				//tempBall1.velocityX *= _friction;
				//tempBall1.velocityY *= _friction;
 
				// update position based on velocity
				tempBall1.x += tempBall1.velocityX;
				tempBall1.y += tempBall1.velocityY;
			}
		}
 
		/**
		 * Collision reaction
		 * @param	ball1	Takes Ball object
		 * @param	ball2	Takes Ball object
		 */
		private function collideBalls(ball1:Ball, ball2:Ball):void
		{
			// calculate the distance between center of balls with the Pytagorean theorem
			var dx:Number = ball1.x - ball2.x;
			var dy:Number = ball1.y - ball2.y;
 
			// calculate the angle of the collision in radians
			var collisionAngle:Number = Math.atan2(dy, dx);
 
			// calculate the velocity vector for each ball
			// using existing ball X & Y velocities
			var speed1:Number = Math.sqrt(ball1.velocityX * ball1.velocityX + ball1.velocityY * ball1.velocityY)
			var speed2:Number = Math.sqrt(ball2.velocityX * ball2.velocityX + ball2.velocityY * ball2.velocityY)
 
			// calculate the angle in radians for each ball using it's current velocities
			// Calculate the angle formed by vector velocity of each ball, knowing your direction.
			var direction1:Number = Math.atan2(ball1.velocityY, ball1.velocityX);
			var direction2:Number = Math.atan2(ball2.velocityY, ball2.velocityX);
 
			// rotate the vectors counterclockwise so we can
			// calculate the conservation of momentum next
			var velocityX1:Number = speed1 * Math.cos(direction1 - collisionAngle);
			var velocityY1:Number = speed1 * Math.sin(direction1 - collisionAngle);
			var velocityX2:Number = speed2 * Math.cos(direction2 - collisionAngle);
			var velocityY2:Number = speed2 * Math.sin(direction2 - collisionAngle);
 
			// take the mass of each ball and update their velocities based
			// on the law of conservation of momentum
			var finalVelocityX1:Number = ((ball1.mass - ball2.mass) * velocityX1 + (ball2.mass + ball2.mass) * velocityX2) / (ball1.mass + ball2.mass);
			var finalVelocityX2:Number = ((ball1.mass + ball1.mass) * velocityX1 + (ball2.mass - ball1.mass) * velocityX2) / (ball1.mass + ball2.mass);
 
			// Y velocities stay constant
			// because this is an 1D environment collision
			var finalVelocityY1:Number = velocityY1;
			var finalVelocityY2:Number = velocityY2;
 
			// after we have our final velocities, we rotate the angles back
			// so that the collision angle is preserved
			ball1.velocityX = Math.cos(collisionAngle) * finalVelocityX1 + Math.cos(collisionAngle + Math.PI / 2) * finalVelocityY1;
			ball1.velocityY = Math.sin(collisionAngle) * finalVelocityX1 + Math.sin(collisionAngle + Math.PI / 2) * finalVelocityY1;
			ball2.velocityX = Math.cos(collisionAngle) * finalVelocityX2 + Math.cos(collisionAngle + Math.PI / 2) * finalVelocityY2;
			ball2.velocityY = Math.sin(collisionAngle) * finalVelocityX2 + Math.sin(collisionAngle + Math.PI / 2) * finalVelocityY2;
 
			// add velocity to ball positions
			ball1.x += ball1.velocityX;
			ball1.y += ball1.velocityY;
			ball2.x += ball2.velocityX;
			ball2.y += ball2.velocityY;
		}
 
		//////////////////////////////////////
		// Event Handlers
		//////////////////////////////////////
 
		/**
		 * EnterFrame handler
		 * @param	e
		 */
		private function onEnterFrame(e:Event):void
		{
			update();
		}
 
		//////////////////////////////////////
		// Utilities
		//////////////////////////////////////
 
		/**
		 * Get distance
		 * @param	delta_x
		 * @param	delta_y
		 * @return
		 */
		public function getDistance(delta_x:Number, delta_y:Number):Number
		{
			return Math.sqrt((delta_x*delta_x)+(delta_y*delta_y));
		}
 
		/**
		 * Get radians
		 * @param	delta_x
		 * @param	delta_y
		 * @return
		 */
		public function getRadians(delta_x:Number, delta_y:Number):Number
		{
			var r:Number = Math.atan2(delta_y, delta_x);
 
			if (delta_y < 0)
			{
				r += (2 * Math.PI);
			}
			return r;
		}
 
		/**
		 * Get degrees
		 * @param	radians
		 * @return
		 */
		public function getDegrees(radians:Number):Number
		{
			return Math.floor(radians/(Math.PI/180));
		}
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
 * Simple Physics
 * ---------------------
 * VERSION: 1.1
 * DATE: 07/31/2011
 * AS3
 * UPDATES AND DOCUMENTATION AT: http://www.say-web.com
 **/
package com.sayweb
{
	import flash.display.MovieClip;
 
	public class Ball extends MovieClip
	{
		// data
		private var _velocityX:Number = 0;
		private var _velocityY:Number = 0;
		private var _speed:Number;
		private var _mass:Number;
		private var _radius:Number;
		private var _radians:Number;
 
		/**
		 * Ball Constructor
		 * @param	x
		 * @param	y
		 * @param	rotation
		 * @param	speed
		 * @param	radius
		 * @param	mass
		 */
		public function Ball(x:Number, y:Number, radius:Number, rotation:Number, speed:Number, mass:Number)
		{
			// set parameters
			this.x = x;
			this.y = y;
			this.radius = radius;
			this.rotation = rotation;
			this.speed = speed;
			this.mass = mass;
 
			// calculate the other vars
			this.radians = this.rotation * Math.PI / 180;
			this.velocityX = Math.cos(this.radians) * this.speed;
			this.velocityY = Math.sin(this.radians) * this.speed;
 
			// draw ball
			this.graphics.lineStyle(1);
 
			var ranColor = Math.random() * 0xFFFFFF; // This will generate a random color
 
			this.graphics.beginFill(ranColor); // This will fill the created ball with the random color
			this.graphics.drawCircle(0, 0, radius);
			this.graphics.endFill();
		}
 
		//////////////////////////////////////
		// Getters & Setters
		//////////////////////////////////////
 
		public function get speed():Number
		{
			return _speed;
		}
 
		public function set speed(value:Number):void
		{
			_speed = value;
		}
 
		public function get mass():Number
		{
			return _mass;
		}
 
		public function set mass(value:Number):void
		{
			_mass = value;
		}
 
		public function get radius():Number
		{
			return _radius;
		}
 
		public function set radius(value:Number):void
		{
			_radius = value;
		}
 
		public function get radians():Number
		{
			return _radians;
		}
 
		public function set radians(value:Number):void
		{
			_radians = value;
		}
 
		public function get velocityX():Number
		{
			return _velocityX;
		}
 
		public function set velocityX(value:Number):void
		{
			_velocityX = value;
		}
 
		public function get velocityY():Number
		{
			return _velocityY;
		}
 
		public function set velocityY(value:Number):void
		{
			_velocityY = value;
		}
 
	}
 
}

Related Articles:

, , ,

One Response to “Random Color Balls Bouncing on Stage”


Trackbacks/Pingbacks

  1. Horse games says:

    take a look at this pictures ……

    I have found a great blog that I love!…

Free PageRank Checker

$7.49 .Com! Score Savings Cartoon Smart Tutorials

oDesk Certified Action Script Programmer oDesk Certified Adobe Flash CS3 Designer oDesk Certified Adobe Photoshop 6.0 Designer

2,757
Unique Visitors
Previous 30 Days
Powered By Google Analytics