forked from: forked from: forked from: forked from: バネる (修正版)
こっちをもう一回Forkしてみる。
* あとついでにVector使ったことないので、
* 配列での処理部分をVector使って自分なりに改良してみる。
* さらに表現もあそんでみる。
黒い順にソートしてみました
// forked from esukei's forked from: forked from: forked from: バネる (修正版)
// forked from KonKiKi's forked from: forked from: バネる (修正版)
// forked from KonKiKi's forked from: バネる (質量値を追加してみたらプルプルになった。)
// forked from KonKiKi's バネる
/**
* こっちをもう一回Forkしてみる。
* あとついでにVector使ったことないので、
* 配列での処理部分をVector使って自分なりに改良してみる。
* さらに表現もあそんでみる。
*/
// 黒い順にソートしてみました
package{
import flash.display.*;
import flash.events.*;
public class BaneBane extends Sprite{
//ArrayでなくてVectorにしてみる。
private var balls:Vector.<Ball>;
private var n:uint = 1000;
//バネ定数
private var springConst:Number = 0.3;
//抵抗値
private var damp:Number = 0.8;
//マウスに反応する半径
//広げてぶるんぶるんさせてみた。
private var limitLeng:Number = 450;
//バネで伸びる半径の最大値
private var expansion:Number = 15;
//コンストラクタ
public function BaneBane(){
balls = new Vector.<Ball>();
//init()やめて直書き
for(var i:uint=0; i<n; i++){
var myX:Number = Math.random() * stage.stageWidth;
var myY:Number = Math.random() * stage.stageHeight;
var mass:Number = Math.pow(Math.random(),2); // 小さいのを増やす
balls.push( new Ball(myX,myY,mass) );
//balls Vectorの一番最後をステージに表示
//stage.addChild(balls[balls.length - 1]);
}
// 黒い順にソート
balls.sort(compare);
for(i = 0; i < n-1; i++) addChild(balls[i]);
stage.addEventListener(Event.ENTER_FRAME,onLoop);
}
private function compare(a:Ball, b:Ball):Number {
return a.width - b.width;
}
private function onLoop(eventObj:Event):void {
//for文の代わりにforEachをつかってみる。
//どっちが早いんだろう?
balls.forEach(function(item:Ball, index:int, vector:Vector.<Ball>):void{
var xx:Number = item._tagX - stage.mouseX;
var yy:Number = item._tagY - stage.mouseY;
var DIST:Number = Math.sqrt( xx * xx + yy * yy );
if(DIST < limitLeng){
var ANGLE:Number = Math.atan2( yy, xx );
var LENG:Number = (expansion / (limitLeng * limitLeng)) * (DIST - limitLeng) * (DIST - limitLeng);
item._myX = item._tagX + LENG * Math.cos(ANGLE);
item._myY = item._tagY + LENG * Math.sin(ANGLE);
//距離によって大きさ変えるのをやめてみる。
}else {
item._myX = item._tagX;
item._myY = item._tagY;
}
item._xVal = valElastic(item.x, item._myX, item._xVal, item._mass);
item._yVal = valElastic(item.y, item._myY, item._yVal, item._mass);
item.x += item._xVal;
item.y += item._yVal;
});
}
private function valElastic(orig:Number, dist:Number, elas:Number, mass:Number):Number {
var force:Number = -springConst * (orig - dist);
var acceleration:Number = force / mass;
return damp * (elas + acceleration);
}
}
}
import flash.display.Shape;
class Ball extends Shape{
//質量値
public var _mass:Number;
public var _myX:Number;
public var _myY:Number;
public var _tagX:Number;
public var _tagY:Number;
public var _xVal:Number;
public var _yVal:Number;
//カラー追加
private var _color:int;
//コンストラクタ
public function Ball(tx:Number,ty:Number,mass:Number){
this.x = _myX = _tagX = tx;
this.y = _myY = _tagY = ty;
_xVal = _yVal = 0;
//質量適当に調整
_mass = mass + 0.1;
//色が灰色~黒ぐらいになるように設定
var tmpColor:int = 192 - mass * 192;
_color = tmpColor << 16 | tmpColor << 8 | tmpColor;
//質量値によってballの色をかえるようにかえる。
//重いのは重そうな色にしてみた。
this.graphics.beginFill(_color, 1);
this.graphics.drawCircle(0, 0, 4 * _mass + 2);
this.graphics.endFill();
}
}