バネっぽく跳ね返るかもしれない、丸の群れ
なんか長くなり過ぎたな、、、。
@author naoto koshikawa
package
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
[SWF(width = "465", height = "465", backgroundColor = "0xFFFFFF", frameRate = "24")]
/**
* なんか長くなり過ぎたな、、、。
* @author naoto koshikawa
*/
public class PhysicalSomething3 extends MovieClip
{
// _____________________________________________________ Property
/** particle count */
private static const PARTICLE_COUNT:uint = 10;
/** particle min size */
private static const PARTICLE_SIZE_MIN:uint = 15;
/** particle max size */
private static const PARTICLE_SIZE_MAX:uint = 30;
/** particle list */
private var _particles:Array;
/** for index */
private var _i:uint;
private var _j:uint;
// _____________________________________________________ Method
/**
* constructor
*/
public function PhysicalSomething3()
{
_particles = [];
Physics.init(stage);
createParticles();
addEventListener(Event.ENTER_FRAME, enterFrameListener);
}
/**
* create particles
*/
private function createParticles():void
{
for (var i:uint = 0; i < PARTICLE_COUNT; i++)
{
var size:Number = Math.floor(Math.random() * (PARTICLE_SIZE_MAX - PARTICLE_SIZE_MIN + 1 )) + PARTICLE_SIZE_MIN;
var particle:MovieClip = new Particle(size);
Physics.base.addChild(particle);
var position:Object = Physics.getRandomPosition(particle);
particle.alpha = 0.7;
particle.x = position.x;
particle.y = position.y;
_particles.push(particle);
}
}
// _____________________________________________________ Listener
/**
* Event.ENTER_FRAME event listener
* @param event
*/
private function enterFrameListener(event:Event):void
{
for (_i = 0; _i < _particles.length - 1; _i++)
{
for (_j = _i + 1; _j < _particles.length; _j++)
{
var dx:Number = _particles[_j].x - _particles[_i].x;
var dy:Number = _particles[_j].y - _particles[_i].y;
var dist:Number = Math.sqrt(dx * dx + dy * dy);
var collisionDist:Number = _particles[_j].size + _particles[_i].size;
if (dist < collisionDist)
{
var radian:Number = Math.atan2(dy, dx);
_particles[_i].ax = -((_particles[_i].x + Math.cos(radian) * collisionDist) - _particles[_j].x) * Physics.SPRING;
_particles[_i].ay = -((_particles[_i].y + Math.sin(radian) * collisionDist) - _particles[_j].y) * Physics.SPRING;
_particles[_j].ax = ((_particles[_i].x + Math.cos(radian) * collisionDist) - _particles[_j].x) * Physics.SPRING;
_particles[_j].ay = ((_particles[_i].y + Math.sin(radian) * collisionDist) - _particles[_j].y) * Physics.SPRING;
}
}
}
for (_i = 0; _i < _particles.length; _i++)
{
_particles[_i].x += _particles[_i].vx * Physics.t + 0.5 * _particles[_i].ax * Physics.t * Physics.t;
_particles[_i].y += _particles[_i].vy * Physics.t + 0.5 * _particles[_i].ay * Physics.t * Physics.t;
_particles[_i].vx += _particles[_i].ax * Physics.t;
_particles[_i].vy += _particles[_i].ay * Physics.t;
// bound horizontally
if (Physics.right < _particles[_i].x + _particles[_i].width / 2)
{
_particles[_i].vx *= Physics.BOUNCE;
_particles[_i].x = Physics.right - _particles[_i].width / 2;
}
else if (_particles[_i].x - _particles[_i].width / 2 < Physics.left)
{
_particles[_i].vx *= Physics.BOUNCE;
_particles[_i].x = Physics.left + _particles[_i].width / 2;
}
// bound vertically
if (Physics.bottom < _particles[_i].y + _particles[_i].height / 2)
{
_particles[_i].vy *= Physics.BOUNCE;
_particles[_i].y = Physics.bottom - _particles[_i].height / 2;
}
else if (_particles[_i].y - _particles[_i].height / 2 < Physics.top)
{
_particles[_i].vy *= Physics.BOUNCE;
_particles[_i].y = Physics.top + _particles[_i].height / 2;
}
_particles[_i].ax = 0;
_particles[_i].ay = 0;
}
}
}
}
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.Shape;
import flash.display.Sprite;
import flash.display.Stage;
import flash.events.Event;
import flash.utils.getTimer;
class Physics {
// _____________________________________________________ Property
/** gravity accerator */
internal static const GRAVITY:Number = 980;
/** firiction */
internal static const FRICTIION:Number = 0.0;
/** bounce */
internal static const BOUNCE:Number = -0.9;
/** spring */
internal static const SPRING:Number = 30;
/** boundary of top position */
private static var _top:Number;
public static function get top():Number
{
if (!_init) throwError();
return _top;
}
/** boundary of left postion */
private static var _left:Number;
public static function get left():Number
{
if (!_init) throwError();
return _left;
}
/** boundary of bottom position */
private static var _bottom:Number;
public static function get bottom():Number
{
if (!_init) throwError();
return _bottom;
}
/** boundary of right postion */
private static var _right:Number;
public static function get right():Number
{
if (!_init) throwError();
return _right;
}
/** initialized flag */
private static var _init:Boolean;
/** real stage */
private static var _stage:Stage;
/** virtual stage */
private static var _base:Sprite;
public static function get base():Sprite
{
if (!_init) throwError();
return _base;
}
/** time */
private static var _prevtime:Number;
private static var _t:Number;
public static function get t():Number
{
if (!_init) throwError();
return _t;
}
// _____________________________________________________ Method
/**
* init
*/
public static function init(stage:Stage):void
{
_stage = stage;
_prevtime = flash.utils.getTimer();
createBase();
_init = true;
}
/**
* get random poisition
* @param target target object whicth you wanna get random position
* @param parent target.parent
* @return
*/
public static function getRandomPosition(target:DisplayObject, parent:DisplayObjectContainer=null):Object
{
if (!_init) throwError();
if (!parent) parent = _base;
var position:Object = { x:0, y:0 };
position.x = Math.random() * (parent.width - target.width) + target.width / 2 - parent.x;
position.y = Math.random() * (parent.height - target.height) + target.width / 2 - parent.y;
return position;
}
/**
* throw error
*/
private static function throwError():void
{
throw(new Error("please invoke Physics.init, first"));
}
/**
* create base object
*/
private static function createBase():void
{
_base = new Sprite();
_base.x = _stage.stageWidth / 2;
_base.y = _stage.stageHeight / 2;
var dotData:BitmapData = new BitmapData(2, 2, true, 0x00000000);
dotData.setPixel32(0, 0, 0x33000000 | 0x00FFFFFF * Math.random());
var dot:Shape = new Shape();
dot.graphics.beginBitmapFill(dotData);
dot.graphics.drawRect(-_base.x, -_base.y, _stage.stageWidth, _stage.stageHeight);
_base.addChild(dot);
_stage.addChild(_base);
_top = -_base.height/2;
_left = - _base.width/2 ;
_bottom = _base.height / 2;
_right = _base.width / 2;
_base.addEventListener(Event.ENTER_FRAME, enterFrameListener, false, int.MIN_VALUE, true);
}
// _____________________________________________________ Listener
/**
* Event.ENTER_FRAME event listener
* @param event
*/
private static function enterFrameListener(event:Event):void
{
_t = (getTimer() - _prevtime) / 1000;
_prevtime = getTimer();
}
}
import flash.display.Graphics;
import flash.display.MovieClip;
class Particle extends MovieClip {
// _____________________________________________________ Property
public var vx:Number = 0;
public var vy:Number = 0;
public var ax:Number = 0;
public var ay:Number = 0;
public var size:Number;
// _____________________________________________________ Method
/**
* constructor
*/
public function Particle(size:Number=20):void
{
this.size = size;
var gr:Graphics = graphics;
gr.beginFill(0xEEEEEE * Math.random(), 0.9);
gr.drawCircle(0, 0, size);
var radian:Number = Math.random() * Math.PI * 2;
var radius:Number = Math.random() * size * 10 + 30; // temporary action ...
vx = Math.cos(radian) * radius;
vy = Math.sin(radian) * radius;
}
}