つぶつぶぅ

by Dorara
パラメータ調整してないBoidsモデル的な、いや、違うか。。
ちゃんと調整すればいい動きしてくれるはず、たぶん。
♥0 | Line 135 | Modified 2009-11-15 02:06:47 | MIT License
play

ActionScript3 source code

/**
 * Copyright Dorara ( http://wonderfl.net/user/Dorara )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/cmbs
 */

// パラメータ調整してないBoidsモデル的な、いや、違うか。。
// ちゃんと調整すればいい動きしてくれるはず、たぶん。
package {
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.TimerEvent;
	import flash.utils.Timer;


	[SWF(width="465", height="465", backgroundColor="0x000000", frameRate="60")]
	public class Boids extends Sprite
	{
		private var agents:Array;
		private var spagent:Array;
		private var Num:int;
		private var K1:Number, K2:Number, K3:Number;
		private var msp:Sprite;

		public function Boids()
		{
			this.stage.scaleMode = StageScaleMode.NO_SCALE;
			this.stage.align = StageAlign.TOP_LEFT;

			Num = 120;
			K1 = 100.0; //はなれろー
			K2 = 20.0; //あわせろー
			K3 = 30.0; //ちかづけー

			// 初期設定
			agents = new Array(Num);
			spagent = new Array(Num);
			for(var i:int = 0; i < Num; i++)
			{
				agents[i] = new agent();
				agents[i].x = Math.random() * 465;
				agents[i].y = Math.random() * 465;
				var sp:Sprite = new Sprite();
				sp.graphics.beginFill(0xffffff);
				sp.graphics.drawCircle(0, 0, 1);
				sp.graphics.endFill();
				sp.x = Math.round(agents[i].x);
				sp.y = Math.round(agents[i].y);
				spagent[i] = sp;
				this.addChild(spagent[i]);
			}
			msp = new Sprite();
			msp.graphics.beginFill(0x990099);
			msp.graphics.drawCircle(0, 0, 5);
			msp.graphics.endFill();
			this.addChild(msp);
			
			var timer:Timer = new Timer(30);
			timer.addEventListener(TimerEvent.TIMER, nextcalc);
			timer.start();
		}
		

		// エージェントの描画
		public function show_agent():void
		{
			for(var i:int = 0; i < Num; i++)
			{
				spagent[i].x = Math.round(agents[i].x);
				spagent[i].y = Math.round(agents[i].y);
			}
		}
		
		// タイマーコールバック
		public function nextcalc(e:TimerEvent):void
		{
			calc();
			show_agent();
		}
		
		// 1ステップごとの処理
		public function calc():void
		{	
			var mx:int = this.stage.mouseX;
			var my:int = this.stage.mouseY;
			msp.x = mx;
			msp.y = my;
			
			for(var i:int = 0; i < Num; i++)
			{
				// 力
				var fx:Number = 0;
				var fy:Number = 0;
				var gx:Number = 0;
				var gy:Number = 0;
				var d:Number;
				var numBoid:int = 0;
				
				for(var j:int = 0; j < Num; j++)
				{
					if(i != j)
					{
						d = Math.sqrt((agents[j].x-agents[i].x)*(agents[j].x-agents[i].x)+(agents[j].y-agents[i].y)*(agents[j].y-agents[i].y));
						if(d < 40)
						{
							fx = fx - K1*(agents[j].x-agents[i].x)/d/d;
							fy = fy - K1*(agents[j].y-agents[i].y)/d/d;
							fx = fx + K2*(agents[j].vx-agents[i].vx);
							fy = fy + K2*(agents[j].vy-agents[i].vy);
							gx = gx + agents[j].x;
							gy = gy + agents[j].y;
							numBoid++;
						}
					}
				}
				if(numBoid>0)
				{
					var dgx:Number = gx/numBoid - agents[i].x;
					var dgy:Number = gy/numBoid - agents[i].y;
					var dg:Number = Math.sqrt(dgx*dgx + dgy*dgy);
					fx = fx + K3*dgx/dg;
					fy = fy + K3*dgy/dg;
				}
				
				fx = fx - (agents[i].x - mx)*20.0;
				fy = fy - (agents[i].y - my)*20.0;

				if(fx > 80.0) fx = 80.0;
				if(fx < -80.0) fx = -80.0;
				if(fy > 80.0) fy = 80.0;
				if(fy < -80.0) fy = -80.0;

				agents[i].vx = agents[i].vx + fx * 0.03;
				agents[i].vy = agents[i].vy + fy * 0.03;
				
				if(agents[i].vx > 50.0) agents[i].vx = 50.0;
				if(agents[i].vx < -50.0) agents[i].vx = -50.0;
				if(agents[i].vy > 50.0) agents[i].vy = 50.0;
				if(agents[i].vy < -50.0) agents[i].vy = -50.0;
				
				
				agents[i].x = agents[i].x + agents[i].vx * 0.03;
				agents[i].y = agents[i].y + agents[i].vy * 0.03;
			}
		}
	}
}
	
class agent
{
	public var x:Number;
	public var y:Number;
	public var vx:Number;
	public var vy:Number;
	public var ax:Number;
	public var ay:Number;
	public function agent()
	{
		x = 0;
		y = 0;
		vx = 0;
		vy = 0;
		ax = 0;
		ay = 0;
	}
}