ジニーになってなかった
ジニーっぽいもの
真っ先に思いついた分割方法が、放射状の分割でした。
全然オブジェクト指向してなくて残念です。
出現方法間違えたけど、間違えたままにしておきます。
/**
* Copyright knd ( http://wonderfl.net/user/knd )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/u0WR
*/
package
{
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
/**
* ジニーっぽいもの
*
* 真っ先に思いついた分割方法が、放射状の分割でした。
* 全然オブジェクト指向してなくて残念です。
*
* 出現方法間違えたけど、間違えたままにしておきます。
*/
[SWF(backgroundColor="0x0")]
public class TestGenie extends Sprite
{
private var _layer:Sprite;
private var _w:Number;
private var _h:Number;
private var _seg:int = 16; //1辺の分割数
private var _4seg:int = 4 * _seg; //4辺上に打つ点の数
private var _velocity:Number = 30; //フレームあたりのピクセル速度
private var _vertices0:Vector.<Number>; //移動前の点の位置
private var _vertices:Vector.<Number>; //移動中の点の位置
private var _indices:Vector.<int>; //三角形のインデックス
private var _uvtData:Vector.<Number>; //UV座標値
private var _distance0:Vector.<Number>; //クリック位置から辺上の点までの距離
private var _distance:Vector.<Number>; //移動中の距離変化
private var _source:BitmapData;
private var _fixed:int = 0; //停止させた点の数を数える
private var _isDisplaying:Boolean = true; //表示させようとしてるところです
/**
*
*/
public function TestGenie() {
initializeSource();
initializeVectors();
draw();
stage.addEventListener(MouseEvent.CLICK, click);
}
/**
* 適当なBitmapDataを作る。
*/
private function initializeSource():void {
_w = stage.stageWidth;
_h = stage.stageHeight;
_layer = new Sprite();
var $g:Graphics = _layer.graphics;
$g.clear();
var $w:Number = _w / _seg;
var $h:Number = _h / _seg;
for (var i:int = 0; i < _seg; i++) {
for (var j:int = 0; j < _seg; j++) {
$g.beginFill(0xffffff * Math.random(), 1);
$g.drawRect(i * $w, j * $h, $w, $h);
}
}
$g.endFill();
_source = new BitmapData(_w, _h);
_source.draw(_layer);
}
/**
* 基本的なVectorを初期化する
*/
private function initializeVectors():void {
_vertices0 = new Vector.<Number>();
_vertices0.push(0, 0);
_uvtData = new Vector.<Number>();
_uvtData.push(0, 0);
var $w:Number = _w / _seg;
var $h:Number = _h / _seg;
var i:int;
for (i = 0; i < _seg; i++) {
_vertices0.push(i * $w, 0);
_uvtData.push(i / _seg, 0);
}
for (i = 0; i < _seg; i++) {
_vertices0.push(_w, i * $h);
_uvtData.push(1, i / _seg);
}
for (i = _seg; i > 0; i--) {
_vertices0.push(i * $w, _h);
_uvtData.push(i / _seg, 1);
}
for (i = _seg; i > 0; i--) {
_vertices0.push(0, i * $h);
_uvtData.push(0, i / _seg);
}
_vertices = _vertices0.concat();
_indices = new Vector.<int>();
for (i = 1; i < _4seg;) {
_indices.push(0, i, ++i);
}
_indices.push(0, _4seg, 1);
}
/**
* クリック位置から各点までの距離を計算する
*/
private function calcDistance():void {
_distance0 = new Vector.<Number>();
var $d0:Vector.<Number> = _distance0;
var $v0:Vector.<Number> = _vertices0;
var $x:Number = $v0[0];
var $y:Number = $v0[1];
var $len :int = $v0.length;
for (var i:int = 0; i < $len; i++)
{
var v0 :Number = $v0[i] - $x;
var v1 :Number = $v0[++i] - $y;
$d0.push(Math.sqrt(v0 * v0 + v1 * v1));
}
_distance = $d0.concat();
}
/**
* drawTriangles する
*/
private function draw():void {
graphics.clear();
graphics.lineStyle(0, 0xffffff, 0.25);
graphics.beginBitmapFill(_source);
graphics.drawTriangles(_vertices, _indices, _uvtData);
}
/**
*
* @param e
*/
private function click(e:MouseEvent):void {
_isDisplaying = !_isDisplaying;
if(!_isDisplaying){
_vertices0[0] = mouseX;
_vertices0[1] = mouseY;
_uvtData[0] = _vertices0[0] / _w;
_uvtData[1] = _vertices0[1] / _h;
_vertices = _vertices0.concat();
calcDistance();
}
draw();
_fixed = 0;
addEventListener(Event.ENTER_FRAME, enter);
}
/**
*
* @param e
*/
private function enter(e:Event):void {
var $d:Vector.<Number> = _distance;
var $d0:Vector.<Number> = _distance0;
var $v:Vector.<Number> = _vertices;
var $v0:Vector.<Number> = _vertices0;
var $x:Number = $v0[0];
var $y:Number = $v0[1];
var i:int;
var $0:int;
var $1:int;
var $ratio:Number;
if (!_isDisplaying) {
//辺の上にあった各点を等速運動させてクリック位置まで移動させる。
for (i = 1; i <= _4seg; i++)
{
$0 = 2 * i;
$1 = $0 + 1;
if ($d[i] == 0) continue;
$d[i] -= _velocity;
if ($d[i] > 0) {
$ratio = $d[i] / $d0[i];
$v[$0] = $ratio * ($v0[$0] - $x) + $x;
$v[$1] = $ratio * ($v0[$1] - $y) + $y;
} else {
//クリック位置まで到達した点の数をカウント
_fixed++;
$d[i] = 0;
$v[$0] = $x;
$v[$1] = $y;
}
}
draw();
} else {
//前回のクリック位置から辺上に向けて点を等速で放射する(間違い)
for (i = 1; i <= _4seg; i++)
{
$0 = 2 * i;
$1 = $0 + 1;
if ($d[i] == $d0[i]) continue;
$d[i] += _velocity;
if ($d[i] < $d0[i]) {
$ratio = $d[i] / $d0[i];
$v[$0] = $ratio * ($v0[$0] - $x) + $x;
$v[$1] = $ratio * ($v0[$1] - $y) + $y;
} else {
_fixed++;
$d[i] = $d0[i];
$v[$0] = $v0[$0];
$v[$1] = $v0[$1];
}
}
draw();
}
if (_fixed == _4seg) {
removeEventListener(Event.ENTER_FRAME, enter);
}
}
}
}