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:
- One main file that commands ball creation and enables bouncing evironment
- Ball Class
- Physics and Friction Environment
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;
}
}
} |




One Response to “Random Color Balls Bouncing on Stage”
Trackbacks/Pingbacks
take a look at this pictures ……
I have found a great blog that I love!…