[習作]Liquid10000
nulldesignさんのLiquid10000 から連なるFork作品群を読みながら習作。
*
* マウスによる影響を追加。マウスの速度・ドットとの距離が影響
* Array を Vector に 変更
* 加速度マップの大きさを縮小
*
♥0 |
Line 108 |
Modified 2010-06-16 14:18:27 |
MIT License
archived:2017-03-20 11:26:05
ActionScript3 source code
/**
* Copyright ug24k8 ( http://wonderfl.net/user/ug24k8 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/u003
*/
/*
* nulldesignさんのLiquid10000 から連なるFork作品群を読みながら習作。
*
* マウスによる影響を追加。マウスの速度・ドットとの距離が影響
* Array を Vector に 変更
* 加速度マップの大きさを縮小
* */
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BitmapDataChannel;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.ColorTransform;
import flash.geom.Point;
import flash.geom.Rectangle;
import net.hires.debug.Stats;
[SWF(width="465", height="465", backgroundColor="0x000010", frameRate="60")]
public class Main extends Sprite {
private const DOT_NUM:uint = 10000;
private const ACC_RATE:Number = 0.001; // フォースマップの色→加速度変換率
private const VEL_DEG_RATE:Number = 0.995; // 速度の減衰率
private const NOISE_OCT:uint = 4; // フォースマップの複雑さ
private const FORCEMAP_SCALE:uint = 50; // フォースマップのドット率
private const MOUSE_REPULSE_RATE:Number = 0.9; // マウス斥力
private var canvas:BitmapData = new BitmapData(350, 200, false, 0x000000);
private var canvas_bmp:Bitmap = new Bitmap(canvas);
private var accelerationData:BitmapData = new BitmapData(
canvas.width/FORCEMAP_SCALE, canvas.height/FORCEMAP_SCALE, false, 0x000000);
private var dotList:Vector.<VectorDat> = new Vector.<VectorDat>(DOT_NUM, true); // 個数固定
private var blur_out:ColorTransform;
private var lastMouse:Point = new Point();
public function Main() {
var i:int;
// accelerationDataにノイズを加える。
// このノイズのR値がX方向の加速度、G値がY方向の加速度をさす
accelerationData.perlinNoise(accelerationData.width/2, accelerationData.height/2, NOISE_OCT,
Math.floor(Math.random() * 0xFFFFFFFF), false, true,
BitmapDataChannel.RED | BitmapDataChannel.GREEN);
// ランダムな点を必要分設定。速度・加速度は0
for (i = 0; i < DOT_NUM; ++i) {
var px:Number = Math.random() * canvas.width;
var py:Number = Math.random() * canvas.height;
dotList[i] = new VectorDat(new Point(px, py));
}
// 簡易ブラーとして色変換値を設定
blur_out = new ColorTransform(0.1, 0.9, 0.2, 0.9);
// canvasを貼り付ける
canvas_bmp.x = stage.stageWidth - canvas_bmp.width;
addChild(canvas_bmp);
// 加速度マップも貼り付けてみる
var acceleration_bmp:Bitmap = new Bitmap(accelerationData);
acceleration_bmp.x = canvas_bmp.x;
acceleration_bmp.y = canvas_bmp.y + canvas_bmp.height;
acceleration_bmp.scaleX = acceleration_bmp.scaleY = FORCEMAP_SCALE;
addChild(acceleration_bmp);
// 状態チェッカーも貼り付けてみる
addChild(new Stats());
// 毎フレーム処理登録
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
// 毎フレーム処理
private function onEnterFrame(evt:Event):void {
canvas.lock();
// ブラーなし
// canvas.fillRect(new Rectangle(0, 0, canvas.width, canvas.height), 0x000000);
// 簡易ブラー
canvas.colorTransform(canvas.rect, blur_out);
// マウス移動速度
var speed:Number = Point.distance(
lastMouse,
new Point(canvas_bmp.mouseX, canvas_bmp.mouseY));
// ループの回数を考慮してアクセスを減らす
var canvas_width:int = canvas.width;
var canvas_height:int = canvas.height;
for (var i:int = 0; i < DOT_NUM; ++i) {
var dot:VectorDat = dotList[i];
var acc_col:uint = accelerationData.getPixel(
dot.position.x/FORCEMAP_SCALE,
dot.position.y/FORCEMAP_SCALE);
var acc_x:Number = (((acc_col >> 16) & 0xFF) - 0x80) * ACC_RATE;
var acc_y:Number = (((acc_col >> 8) & 0xFF) - 0x80) * ACC_RATE;
// 速度の減衰
dot.velocity.x *= VEL_DEG_RATE;
dot.velocity.y *= VEL_DEG_RATE;
// 速度に加速度追加
dot.velocity.x += acc_x;
dot.velocity.y += acc_y;
// 距離を調べる
var dot_diff_x:int = dot.position.x - canvas_bmp.mouseX;
var dot_diff_y:int = dot.position.y - canvas_bmp.mouseY;
var dot_diff_pow:int = (dot_diff_x * dot_diff_x) + (dot_diff_y * dot_diff_y);
if (dot_diff_pow > 0) {
dot.velocity.x += speed * dot_diff_x / dot_diff_pow * MOUSE_REPULSE_RATE;
dot.velocity.y += speed * dot_diff_y / dot_diff_pow * MOUSE_REPULSE_RATE;;
}
// ポイントの位置を更新
dot.position.x += dot.velocity.x;
dot.position.y += dot.velocity.y;
// はみ出ないように調整
if (dot.position.x < 0) {
dot.position.x = 0;
dot.velocity.x *= -1;
}
else if (dot.position.x > canvas_width) {
dot.position.x = canvas_width;
dot.velocity.x *= -1;
}
if (dot.position.y < 0) {
dot.position.y = 0;
dot.velocity.y *= -1;
}
else if (dot.position.y > canvas_height) {
dot.position.y = canvas_height;
dot.velocity.y *= -1;
}
// 描画
canvas.setPixel(dot.position.x, dot.position.y, 0xFFFFFFFF);
// canvas.fillRect(new Rectangle(dot.position.x, dot.position.y, 1, 1), 0xFFFFFF);
}
canvas.unlock();
lastMouse.x = canvas_bmp.mouseX;
lastMouse.y = canvas_bmp.mouseY;
}
}
}
import flash.geom.Point;
class VectorDat {
public var velocity:Point;
public var position:Point;
function VectorDat(_pv:Point) {
velocity = new Point();
position = _pv;
}
}