boid(精子風味)
/**
* Copyright satoru.net ( http://wonderfl.net/user/satoru.net )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/o7MG
*/
package {
import com.bit101.components.*;
import flash.display.*;
import flash.events.*;
import flash.utils.*;
import flash.geom.*;
[SWF(width="500", height="500", frameRate="100")]
public class main extends Sprite{
var NUM_BOIDS:int = 30;
var DIST_THRESHOLD1:int = 10;
var DIST_THRESHOLD2:int = 20;
var DIST_THRESHOLD3:int = 30;
var FACTOR_COHESION = 100;
var FACTOR_SEPARATION = 10;
var FACTOR_ALINGMENT = 10;
var VELOCITY_LIMIT = 3;
var TRAIL_SCALE = 2;
var prePosLength = 10;
var flock:Array;
var sh = new Sprite();
var bmp = new Bitmap(new BitmapData(500,500,true,0x000000));
var black = new BitmapData(500, 500, false, 0x000000);
var gr = sh.graphics;
function main() {
addChild(sh);
addChild(bmp);
init();
addEventListener(Event.ENTER_FRAME, interval);
stage.addEventListener(MouseEvent.MOUSE_DOWN, doReset);
}
function init(){
flock = new Array();
for(var n=0;n<NUM_BOIDS;n++){
var b = Boid();
flock.push(b);
}
}
function setValue(key,val){
for(var i in flock){
flock[i][key] = val;
}
}
function doReset(e:*){
for(var i in flock){
flock[i].remove();
flock[i] = null;
}
init();
}
function interval(e:*) {
bmp.bitmapData.draw(black);
for(var i in flock){
flock[i].update();
}
}
function getRandom(low,high){
return low+Math.floor(Math.random()*((high-low)));
}
function Boid(){
var r1 = 1.0 //cohesion.value; // Cohesion: pull to center of flock
var r2 = 0.8 //separation.value; // Separation: avoid bunching up
var r3 = 0.1 //alingment.value; // Alingment: match average flock speed
var o = {
"shape":new Shape(),
"v1":Vector(),
"v2":Vector(),
"v3":Vector(),
"r1":r1,
"r2":r2,
"r3":r3,
"vx":getRandom(-5, 5),
"vy":getRandom(-5, 5),
"xpos":getRandom(0,stage.stageWidth),
"ypos":getRandom(0,stage.stageHeight),
"prePos":new Array()
};
init();
function init(){
//o.gr = sh.graphics;
o.gr = o.shape.graphics;
return o;
}
o.remove = function(){
o = null;
return;
}
o.update = function(){
updatePosition();
savePosition();
drawPoint();
}
function savePosition(){
o.prePos.unshift({x:o.xpos,y:o.ypos});
if(o.prePos.length >prePosLength){
o.prePos.length = prePosLength;
}
}
function drawPoint(){
o.gr.clear();
o.gr.lineStyle(4,0xFFFFFF);
o.gr.moveTo(o.xpos, o.ypos);
o.gr.lineTo(o.xpos-TRAIL_SCALE*o.vx, o.ypos-TRAIL_SCALE*o.vy);
for(var i in o.prePos){
var X = o.prePos[i].x;
var Y = o.prePos[i].y;
o.gr.lineStyle(1,0xFF00000);
o.gr.moveTo(X, Y);
o.gr.lineTo(X-TRAIL_SCALE*o.vx, Y-TRAIL_SCALE*o.vy);
}
bmp.bitmapData.draw(o.shape);
}
function limitVelocity(){
var velocity = Math.sqrt(Math.pow(o.vx,2) + Math.pow(o.vy,2));
if(velocity > VELOCITY_LIMIT){
o.vx = (o.vx/velocity)*VELOCITY_LIMIT;
o.vy = (o.vy/velocity)*VELOCITY_LIMIT;
}
}
function updatePosition(){
if(o.isStop){
return;
}
o.v1.x = o.v1.y = o.v2.x = o.v2.y = o.v3.x = o.v3.y = 0;
rule1();
rule2();
rule3();
// add vectors to velocities
o.vx += o.r1*o.v1.x + o.r2*o.v2.x + o.r3*o.v3.x;
o.vy += o.r1*o.v1.y + o.r2*o.v2.y + o.r3*o.v3.y;
limitVelocity();
o.xpos += o.vx;
o.ypos += o.vy;
if(o.xpos < 0){
o.xpos = stage.stageWidth;
} else if(o.xpos > stage.stageWidth){
o.xpos = 0;
}
if(o.ypos < 0){
o.ypos = stage.stageHeight;
} else if(o.ypos > stage.stageHeight){
o.ypos = 0;
}
}
// Cohesion
function rule1(){
var count = 0;
for(var i in flock){
if(o !== flock[i]){
var len = Point.distance(new Point(o.xpos, o.ypos), new Point(flock[i].xpos, flock[i].ypos));
if(len > DIST_THRESHOLD2 && len < DIST_THRESHOLD3){
o.v1.x += flock[i].xpos;
o.v1.y += flock[i].ypos;
count++;
}
}
}
if(count > 0){
o.v1.x /= count;
o.v1.y /= count;
o.v1.x = (o.v1.x - o.xpos) / FACTOR_COHESION;
o.v1.y = (o.v1.y - o.ypos) / FACTOR_COHESION;
}
}
function rule2(){
for(var i in flock){
if(o !== flock[i]){
var len = Point.distance(new Point(o.xpos, o.ypos), new Point(flock[i].xpos, flock[i].ypos));
if(len < DIST_THRESHOLD1){
o.v2.x -= (flock[i].xpos - o.xpos)/FACTOR_SEPARATION;
o.v2.y -= (flock[i].ypos - o.ypos)/FACTOR_SEPARATION;
}
}
}
}
// Alingment()
function rule3(){
var count = 0;
for(var i in flock){
if(o !== flock[i]){
var len = Point.distance(new Point(o.xpos, o.ypos), new Point(flock[i].xpos, flock[i].ypos));
if(len > DIST_THRESHOLD1 && len < DIST_THRESHOLD2){
o.v3.x += flock[i].vx;
o.v3.y += flock[i].vy;
count++;
}
}
}
if(count > 0){
o.v3.x /= count;
o.v3.y /= count;
o.v3.x = (o.v3.x - o.vx)/FACTOR_ALINGMENT;
o.v3.y = (o.v3.y - o.vy)/FACTOR_ALINGMENT;
}
}
return o;
}
function Vector(){
return {x:0,y:0};
}
}
}