forked from: Elastic Pixels(残像版)
Elastic Pixels 2 残像版
Elastic Pixels 1
あちこちのコードをパッチワーク
// Elastic Pixels 2 残像版
// forked from Aquioux's Elastic Pixels
// Elastic Pixels 1
// あちこちのコードをパッチワーク
package {
/**
* @author YOSHIDA, Akio
*/
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.ColorTransform;
[SWF(width = "465", height = "465", frameRate = "60", backgroundColor = "#000000")]
public class Main1 extends Sprite {
private var aryParticle:Array; // パーティクル格納配列
private var row:uint = 60; // 横方向の数
private var col:uint = 60; // 縦方向の数
private var isMouseDown:Boolean = false; // マウスをダウンしているか否か
private var distanceOfReaction:uint = 75; // マウスに反応する距離
private var spring:Number = 0.048; // バネ係数
private var friction:Number = 0.94; // 摩擦係数
private var bmdCaptured:BitmapData; // Particle を打つ BitmapData
private var bmdDisplay:BitmapData; // 表示する BitmapData
private const TONEDOWN:ColorTransform = new ColorTransform(1, 1, 1, 0.8);
// コンストラクタ
public function Main1() {
var w:uint = stage.stageWidth;
var h:uint = stage.stageHeight;
bmdCaptured = new BitmapData(w, h, true, 0xff000000);
bmdDisplay = new BitmapData(w, h, true, 0xff000000);
addChild(new Bitmap(bmdDisplay));
var interval:uint = 5;
var offsetX:Number = (w - (row - 1) * interval) / 2;
var offsetY:Number = (h - (col - 1) * interval) / 2;
aryParticle = [];
for (var i:int = 0; i < row; i++) {
for (var j:int = 0; j < col; j++) {
var particle:Particle = new Particle(interval * i + offsetX, interval * j + offsetY);
aryParticle.push(particle);
}
}
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
private function enterFrameHandler(e:Event):void {
bmdCaptured.lock();
bmdCaptured.fillRect(bmdCaptured.rect, 0x00000000);
var mousePoint:Point = new Point(mouseX, mouseY);
for each (var particle:Particle in aryParticle) {
particle.update(mousePoint, isMouseDown, distanceOfReaction, spring, friction);
bmdCaptured.setPixel32(particle.x, particle.y, 0xff33ff99);
}
bmdCaptured.unlock();
bmdDisplay.colorTransform(bmdDisplay.rect, TONEDOWN);
bmdDisplay.draw(bmdCaptured);
}
private function mouseDownHandler(e:MouseEvent):void {
isMouseDown = true;
}
private function mouseUpHandler(e:MouseEvent):void {
isMouseDown = false;
}
}
}
import flash.geom.Point;
class Particle {
// 既定座標
private var localX:Number;
private var localY:Number;
// ベロシティ
private var vx:Number = 0;
private var vy:Number = 0;
// 現在座標
private var _x:Number;
private var _y:Number;
public function Particle(x:Number, y:Number) {
_x = localX = x;
_y = localY = y;
}
public function update(mousePoint:Point, isMouseDown:Boolean, distanceOfReaction:uint, spring:Number, friction:Number):void {
// 到達値
var dx:Number;
var dy:Number;
var distance:Number = Point.distance(mousePoint, new Point(localX, localY));
var direction:Number = isMouseDown ? 1 : -1;
if (distance < distanceOfReaction) {
var diff:Number = distance * direction * (distanceOfReaction - distance) / distanceOfReaction;
var radian:Number = Math.atan2(mousePoint.y - localY, mousePoint.x - localX);
var diffPoint:Point = Point.polar(diff, radian);
dx = localX + diffPoint.x;
dy = localY + diffPoint.y;
} else{ // 位置を元に戻す
dx = localX;
dy = localY;
}
vx += (dx - _x) * spring;
vy += (dy - _y) * spring;
vx *= friction;
vy *= friction;
_x += vx;
_y += vy;
}
public function get x():Number { return _x; }
public function get y():Number { return _y; }
}