反転
http://wonderfl.net/code/902745be6bdc6c46aa1845c5b8bfe87caba406c7
* にインスパイアされました
/**
* Copyright Aquioux ( http://wonderfl.net/user/Aquioux )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/7zEh
*/
/**
* http://wonderfl.net/code/902745be6bdc6c46aa1845c5b8bfe87caba406c7
* にインスパイアされました
*/
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.PixelSnapping;
import flash.display.Sprite;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
[SWF(width = "465", height = "465", frameRate = "60", backgroundColor = "#FFFFFF")]
public class Main extends Sprite {
private const ROW:uint = 100; // 横方向の数
private const COL:uint = 100; // 縦方向の数
private const RADIUS_OF_REVERSE:uint = 75; // 反転の半径
private const SPRING:Number = 0.05; // バネ係数
private const FRICTION:Number = 0.75; // 摩擦係数
private var explain:ExplainTextField; // 事前説明文
private var fillColor:uint; // ステージ塗り色
private var pixelColor:uint; // ピクセル色
private var canvasBitmapData:BitmapData;
private var particleArray:Array;
// コンストラクタ
public function Main() {
Wonderfl.capture_delay(10);
// Particle クラスのセットアップ
Particle.spring = SPRING;
Particle.friction = FRICTION;
Particle.distanceOfReaction = RADIUS_OF_REVERSE;
// ステージの操作
stage.scaleMode = StageScaleMode.NO_SCALE;
// 色の決定
fillColor = (Math.random() < 0.5) ? 0xFFFFFF : 0x000000;
pixelColor = (fillColor - 0xFFFFFF) * -1;
// キャンバスの生成
canvasBitmapData = new BitmapData(stage.stageWidth, stage.stageHeight, false, fillColor);
addChild(new Bitmap(canvasBitmapData, PixelSnapping.NEVER));
// 事前説明文
addChild(explain = createExplain());
// パーティクルの生成
createParticle();
draw();
// 最初のイベントリスナー
stage.addEventListener(MouseEvent.CLICK, startClickHandler);
}
// 事前説明文の生成
private function createExplain():ExplainTextField{
var explain:ExplainTextField = new ExplainTextField();
explain.text = "first CLICK stage,\nthen MOVE_MOUSE while (MOUSE_DOWN or MOUSE_UP)";
explain.color = pixelColor;
explain.build();
return explain;
}
// パーティクルの生成
private function createParticle():void{
var offsetX:uint = (stage.stageWidth - ROW) / 2;
var offsetY:uint = (stage.stageHeight - COL) / 2;
particleArray = [];
for (var i:uint = 0; i < ROW; i++) {
for (var j:uint = 0; j < COL; j++) {
var particle:Particle = new Particle(i + offsetX + 0.5, j + offsetY + 0.5, pixelColor);
particleArray.push(particle);
}
}
}
// 最初のイベントリスナー
private function startClickHandler(e:MouseEvent):void {
// このイベントリスナーを削除
stage.removeEventListener(MouseEvent.CLICK, startClickHandler);
// 事前説明文の削除
removeChild(explain);
explain = null;
// 各種イベントリスナーの登録
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
private function mouseDownHandler(e:MouseEvent):void {
Particle.toggle();
}
private function mouseUpHandler(e:MouseEvent):void {
Particle.toggle();
}
private function enterFrameHandler(e:Event):void {
var mousex:Number = mouseX;
var mousey:Number = mouseY;
for each (var particle:Particle in particleArray) {
particle.update(mousex, mousey);
}
draw();
}
// パーティクルの描画
private function draw():void {
canvasBitmapData.lock();
canvasBitmapData.fillRect(canvasBitmapData.rect, fillColor);
for each (var particle:Particle in particleArray) {
canvasBitmapData.setPixel(particle.x, particle.y, pixelColor);
}
canvasBitmapData.unlock();
}
}
}
class Particle {
public static var spring:Number = 0.05; // バネ係数
public static var friction:Number = 0.9; // 摩擦係数
public static var distanceOfReaction:Number = 100; // 反応距離
private static var _toggle:int = 1;
// 既定座標
private var localX:Number;
private var localY:Number;
// 色
private var _color:uint;
// 速度
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, color:uint) {
_x = localX = x;
_y = localY = y;
_color = color;
}
public function update(mousex:Number, mousey:Number):void {
// 反転計算
var distX:Number = mousex - localX;
var distY:Number = mousey - localY;
var distXY:Number = distX * distX + distY * distY;
var distanceBetweenMouse:Number = Math.sqrt(distXY);
var distanceAfterReverse:Number = distanceOfReaction * distanceOfReaction / distanceBetweenMouse * _toggle;
var radian:Number = Math.atan2(distY, distX);
var dx:Number = Math.cos(radian) * distanceAfterReverse + localX;
var dy:Number = Math.sin(radian) * distanceAfterReverse + localY;
// 移動
move(dx, dy, spring, friction);
}
// 移動
private function move(dx:Number,dy:Number,spring:Number,friction:Number):void{
_vx += (dx - _x) * spring;
_vy += (dy - _y) * spring;
_vx *= friction;
_vy *= friction;
_x += _vx;
_y += _vy;
}
public static function toggle():void {
_toggle *= -1;
}
public function get x():Number { return _x; }
public function get y():Number { return _y; }
public function get color():uint { return _color; }
}
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
class ExplainTextField extends TextField {
private var _font:String = "_sans";
private var _size:uint = 12;
private var _color:uint = 0x000000;
private var _align:String = TextFormatAlign.LEFT;
public function ExplainTextField() {
text = "CLICK stage";
autoSize = TextFieldAutoSize.LEFT;
selectable = false;
}
public function build():void {
var textFormat:TextFormat = new TextFormat(_font, _size, _color);
textFormat.align = _align;
textFormat.leading = uint(_size / 2);
setTextFormat(textFormat);
}
// TextFormat のプロパティ
public function set font(value:String):void { _font = value; }
public function set size(value:uint):void { _size = value; }
public function set color(value:uint):void { _color = value; }
public function set align(value:String):void{ _align = value; }
}