forked from: 円
http://linkalink.jp/enok/
/**
* Copyright PINOPINO ( http://wonderfl.net/user/PINOPINO )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/ppU7
*/
// forked from enok's 円
// http://linkalink.jp/enok/
package {
import flash.display.;
[SWF(backgroundColor="0xffffff", frameRate="32")]
public class FlashTest extends Sprite {
public function FlashTest() {
var _trick:Sprite = new Kyu( this, stage.stageWidth / 2, stage.stageHeight / 2, -10, 3, 0x333333, 1, 3.0);
addChild( _trick );
}
}
}
import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.events.Event;
class Kyu extends Sprite {
//parent stage
private var _w:int;
private var _h:int;
private var _center_x:Number;
private var _center_y:Number;
//main
private var _nami_color:uint //波の色
private var _cell_w:int = 1; //波の横幅
private var _cell_h:int = 1; //波の縦幅
private var _cell_amout:int; //セルの横幅
private var _cell_cnt:int; //セルの数
private var _cell_list:Array = new Array(); //波セルのリスト
private var _mouse_area:Number = 20.0;
//nami
private var _period:Number = 5.0; //周期T
private var _a_min:Number = 0.0; //振幅の最小値(まるめ)
private var _f:Number = 5.0; //振幅数
private var _t:int = 1; //波時間
private var _nami_spring:Number = 0.2; //ばね
private var _nami_friction:Number = 0.5; //跳ね
private var _up_rate:Number;
//kyu
private var _kyu_radius:int = 200; //球の半径
private var _kyu_line:int //球の長さ
private var _kyu_def_posi:Array = new Array(); //球のデフォルトポジション
//nami patter
private var _motion_y:Number = 0.0;
private var _motion_vy:Number = 0.0;
//count
private var _enter_nami_cnt:int = 0; //Nami EnterFrame回数
private var _motion_cnt:int = 5; //自動波用カウント
//mouse
private var _mousex_now:Number;
private var _mousey_now:Number;
private var _mousex_pre:Number;
private var _mousey_pre:Number;
//const
private const DEBUG:Boolean = true; //デバッグモード
private const AROUND_NAMI_A:Number = 0.2;
private const AROUND_NAMI_POSI:Number = 0.3;
public function Kyu( p_s:DisplayObjectContainer, p_x:int, p_y:int, p_w:int, p_h:int, p_color:uint, p_amount:int, p_up_rate:Number ) {
//WORLD系
_w = p_s.stage.stageWidth; _h = p_s.stage.stageHeight;
_center_x = p_x; _center_y = p_y;
//波系
_nami_color = p_color;
_cell_w = p_w;
_cell_h = p_h;
_cell_amout = p_amount;
_up_rate = p_up_rate;
//球系
_kyu_line = 2 * Math.PI * _kyu_radius;
//セル系
_cell_cnt = _kyu_line / _cell_amout;
//マウス系
_mousex_now = _center_x;
_mousey_now = _center_y;
_mousex_pre = _center_x;
_mousey_pre = _center_y;
init();
}
private function init():void {
setCell();
addEventListener( Event.ENTER_FRAME, onEnterFrameNami );
}
//セルをセット
private function setCell():void {
var i:uint;
var cell:Cell;
var x:Number, y:Number, dx:Number, dy:Number, angle:Number, rotation:Number;
//セルの配置
for (i = 0; i < _cell_cnt; i++ ) {
//セルのデフォルト位置を定義
/*var red:uint = 255 / _cell_cnt * i;
var color:uint = i << 16 | 0 << 8 | 0;*/
cell = new Cell( _cell_w, _cell_h, _nami_color );
//セルのバーチャル位置セット
cell._x = i * _cell_amout;
cell._y = _center_y;
//球のデフォルト位状態をセット
angle = Math.PI * 2 / _cell_cnt * i - Math.PI / 2;
x = _kyu_radius * Math.cos(angle) + _center_x;
y = _kyu_radius * Math.sin(angle) + _center_y;
dx = x - _center_x;
dy = y - _center_y;
angle = Math.atan2(dy, dx);
rotation = ( angle - Math.PI / 2 ) * 180 / Math.PI;
_kyu_def_posi.push(new Array(x-cell._x, y-cell._y, x, y, rotation));
//_kyu_def_posi.push(new Array(0, 0, cell._x, cell._y, 0));
//セル配置
addChild(cell);
_cell_list.push(cell);
//if (DEBUG) cell.x = x; cell.y = y; cell.rotation = rotation; //デバッグ表示
}
}
private function onEnterFrameNami(e:Event):void {
mouseSet();
namiMove(); //描画
_enter_nami_cnt++;
}
private function mouseSet():void {
_mousex_pre = _mousex_now;
_mousey_pre = _mousey_now;
_mousex_now = mouseX;
_mousey_now = mouseY;
}
//波を動かす処理
private function namiMove():void {
var i:uint, x:Number, y:Number, dx:Number, dy:Number, dist:Number ,angle:Number;
for (i = 0; i < _cell_cnt; i++ ) {
//○目がうまくいっていない
dx = _cell_list[i].x - _kyu_def_posi[i][2];
dy = _cell_list[i].y - _kyu_def_posi[i][3];
dist = Math.sqrt( dx * dx + dy * dy );
if ( Math.abs(_cell_list[i]._a) <= AROUND_NAMI_A && dist <= AROUND_NAMI_POSI) {
//丸め処理
_cell_list[i].x = _kyu_def_posi[i][2];
_cell_list[i].y = _kyu_def_posi[i][3];
_cell_list[i]._a = 0;
}else {
//定常波の方程式
y = _cell_list[i]._a * Math.sin( _t / _period - i * _cell_amout / _f );
angle = _kyu_def_posi[i][4] * Math.PI / 180 - Math.PI / 2;
x = Math.cos(angle) * y;
y = Math.sin(angle) * y;
y += _center_y;
_cell_list[i]._v_x = _cell_list[i]._x + x;
_cell_list[i]._v_y = y; //描画
//加速度をばねる
springA(_cell_list[i]); //振幅を変化
//一時変換
var flg:int = 1;
if (flg == 1) {
//ここに処理を追加 CPU減
_cell_list[i].x = _cell_list[i]._v_x + _kyu_def_posi[i][0];
_cell_list[i].y = _cell_list[i]._v_y + _kyu_def_posi[i][1];
_cell_list[i].rotation = _kyu_def_posi[i][4];
}else if(flg==2){
_cell_list[i].x = _cell_list[i]._x;
_cell_list[i].y = _cell_list[i]._y;
}
}
//マウスチェック
//addMouseValue(_cell_list[i]);
checkWave( i, mouseX, mouseY, _up_rate );
}
_t++; //波時間を進める
}
//波の振幅をばねで計算
private function springA( p_cell:Cell ):void {
var dx:Number, ax:Number;
dx = _a_min - p_cell._a;
ax = dx * _nami_spring;
p_cell._vx += ax;
p_cell._vx *= _nami_friction;
p_cell._a += p_cell._vx;
}
private function addMouseValue( p_cell:Cell ):void{
var dx:Number, dy:Number, dist:Number, max:Number, per:Number;
max = _w;
dx = p_cell.x - _mousex_now;
dy = p_cell.y - _mousey_now;
dist = Math.sqrt( dx * dx + dy * dy );
per = ( max - dist ) / max;
p_cell._a += (_mousex_now - _mousex_pre) * per * 0.1;
}
//マウスチェック
private function checkWave(p_i:int, p_target_x:Number, p_target_y:Number, nami_rate:Number ):void {
var dx:Number = _cell_list[p_i].x - p_target_x;
var dy:Number = _cell_list[p_i].y - p_target_y;
var dist:Number = Math.sqrt( dx * dx + dy * dy );
if (dist < _mouse_area) {
addWave(p_i, nami_rate);
}
}
//波追加
private function addWave(target:int,up_rate:Number):void {
wavePattern1(target,up_rate);
}
//波パターン
private function wavePattern1(p_i:int, up_rate:Number):void {
var i:uint, y:Number;
var start_i:int = p_i - 100; if (start_i < 0) { start_i = 0; }
var end_i:int = p_i + 100; if (end_i > _cell_cnt) { end_i = _cell_cnt; }
var dist:Number;
for (i = start_i; i < end_i; i++) {
dist = Math.abs((p_i - i)); if (dist == 0) { dist = 1.0; }
y = 1 / dist * up_rate;
_cell_list[i]._a += y;
}
}
}
import flash.display.Sprite;
class Cell extends Sprite {
public var _x:Number = 0;
public var _y:Number = 0;
public var _v_x:Number = 0;
public var _v_y:Number = 0;
public var _w:int = 0;
public var _h:int = 0;
public var _rotaion:Number = 0;
public var _color:int = 0;
public var _a:Number = 0.0; //振幅
public var _vx:Number = 0.0; //速度
public function Cell( p_w:Number = 1, p_h:Number = 1, p_color:uint = 0xffffff ) {
_w = p_w;
_h = p_h;
_color = p_color;
graphics.beginFill(_color);
graphics.drawRect(-_w/2, 0, _w, _h);
}
}