forked from: 波

by hacker_ni1uncin forked from (diff: 1)
めちゃめちゃ重くてすいません。
♥0 | Line 139 | Modified 2010-02-14 19:19:58 | MIT License
play

ActionScript3 source code

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

// forked from enok's 波
// めちゃめちゃ重くてすいません。

package { 

import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.events.Event;

[SWF(backgroundColor="0xffffff", frameRate="24")] 

public class Nami extends Sprite {
	//parent stage
	private var _parent_stage_w:int;
	private var _parent_stage_h:int;
	//main
	private var _nami_color:uint //なみの色
	private var _nami_h:int; //波の縦幅
	private var _cell_y:Number; //波のY位置
	private var _cell_cnt:int; //波の数
	private var _cell_list:Array = new Array(); //波セルのリスト 
	private var _mouse_area:Number = 20.0;
	//nami
	private var _period:Number = 2.0; //周期T
	private var _a_min:Number = 0.0; //振幅の最小値(まるめ)
	private var _f:Number = 20.0; //振幅数
	private var _t:int = 1; //波時間
	private var _nami_spring:Number = 0.1; //ばね
	private var _nami_friction:Number = 0.8; //跳ね
	//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 = 0; //自動波用カウント
	
	//const
	private const CELL_W:int = 1;
	private const AROUND_NAMI_A:Number = 0.3;
	private const AROUND_NAMI_Y:Number = 0.2;
	
	public function Nami() {	
		var p_h:int = 250;
		var p_color:uint = 0x000000;

		//クラス変数にセット
		_parent_stage_w = 500; 
		_parent_stage_h = 500;
		_nami_color = p_color; 
		_nami_h = p_h;
		_cell_cnt = _parent_stage_w / CELL_W;
		_cell_y = _parent_stage_h - p_h;
		
		init();
	}
	
	private function init():void {
		setCell();
		addEventListener( Event.ENTER_FRAME, onEnterFrameNami );
		addChild( this );
	}
	
	//セルをセット
	private function setCell():void {
		var i:uint;
		var cell:Cell;
		
		for (i = 0; i < _cell_cnt; i++ ) {
			cell = new Cell( CELL_W, _nami_h * 2.5, _nami_color );
			cell.x = i * CELL_W;
			cell.y = _cell_y;
			
			addChild(cell);
			_cell_list.push(cell);
		}
	}
	
	//NamiのEnterFrame
	private function onEnterFrameNami(e:Event):void {
		namiMove(); //描画
		setMotion();
		_enter_nami_cnt++;
	}
	
	//波を動かす処理
	private function namiMove():void {
		var i:uint, y:Number;
		
		for (i = 0; i < _cell_cnt; i++ ) {
			if (!(_cell_list[i].y == _cell_y && _cell_list[i]._a == 0)) {
				if ( Math.abs(_cell_list[i]._a) <= AROUND_NAMI_A && Math.abs(_cell_list[i].y) <= _cell_y + AROUND_NAMI_Y) {
					//丸め処理
					_cell_list[i].y = _cell_y;
					_cell_list[i]._a = 0;
				}else {
					//定常波の方程式
					y = _cell_list[i]._a * Math.sin( _t / _period - i * CELL_W / _f );
					y += _cell_y;						
					_cell_list[i].y = y; //描画
				}
				
				//加速度をばねる
				springA(_cell_list[i]); //振幅を変化
			}
			//マウスチェック
			checkWave( i, mouseX, mouseY, 3.0 );
		}
		_t++; //波時間を進める
	}
	
	//波の振幅をばねで計算
	private function springA( p_cell:Cell ):void {
		var dx:Number = _a_min - p_cell._a;
		var ax:Number = dx * _nami_spring;
		p_cell._vx += ax;
		p_cell._vx *= _nami_friction;
		p_cell._a += p_cell._vx;
	}
	
	//マウスチェック
	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;
		}
	}
	
	//自動波セット
	private function setMotion():void {
		var i:uint, dx:Number;
		var target_x:Number = _motion_cnt * CELL_W * 25; //波をチェックする時のX対象
		
		if(target_x < _cell_cnt){
			for (i = 0; i < _cell_cnt; i++ ) {
				//波のチェックYを計算
				dx = _cell_y - _motion_y;
				_motion_vy += dx;
				_motion_y += _motion_vy;
				
				//チェックする
				checkWave(i, target_x, _motion_y, 5.5);
			}
			
		}
		
		if (_motion_cnt > 100) {
			_motion_cnt = 0;
		}
		
		_motion_cnt++;
	}
}

} 

import flash.display.Sprite;

class Cell extends Sprite {
	public var _w:int = 0;
	public var _h:int = 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(0, 0, _w, _h);  
	}		
}