/**
* Copyright mtok ( http://wonderfl.net/user/mtok )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/92wD
*/
package
{
import flash.display.Sprite;
import flash.events.Event;
/**
* ...
* @author Motoki Matsumoto
*/
public class FoceFieldTest extends Sprite
{
public function FoceFieldTest()
{
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
private function addedToStageHandler(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
initialize();
}
private function initialize():void
{
addChild( new ForceFieldDemo());
}
}
}
import flash.display.SpreadMethod;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.ui.ContextMenuItem;
import flash.utils.Dictionary;
class ForceFieldDemo extends Sprite {
private var _cellSize:Number;
private var _grid:Grid;
private var _mpos:Point;
public function ForceFieldDemo()
{
super();
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
addEventListener(Event.ENTER_FRAME, enterFrameHnalder);
}
private function enterFrameHnalder(e:Event):void
{
_update();
_redraw();
}
private function _update():void
{
_grid.cells.forEach(updateCell, null);
}
private function updateCell(c:Cell, i:int, ary:Vector.<Cell>):void
{
var p:Point = c.data[1];
p.x *= 0.98;
p.y *= 0.98;
}
private function _redraw():void
{
_grid.forEach(redrawCells, null);
}
private function redrawCells(cell:Cell, r:int, c:int, g:Grid):void
{
var s:Square = cell.data[0];
var p:Point = cell.data[1];
s.color = getColor(p.x, p.y);
}
private function getColor(a:Number, b:Number):uint
{
//trace(a, b);
var n:Number = 1;
var offset:Number = n * 127;
var _a:int = Math.round (( a + offset) / n);
var _b:int = Math.round (( b + offset) / n);
//trace(_a, _b);
if (_a < 0) {
_a = 0;
}
if (_a > 255) {
_a = 255;
}
if (_b < 0) {
_b = 0;
}
if (_b > 255) {
_b < 255;
}
return _a << 16 | _b;
}
private function addedToStageHandler(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
initialize();
}
private function initialize():void
{
var bg:Sprite = Square.createSquare(stage.stageWidth, 0xffffff);
addChild(bg);
addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
_mpos = new Point();
_cellSize = 30;
var r:int = Math.ceil( stage.stageWidth / _cellSize);
var c:int = Math.ceil( stage.stageHeight / _cellSize);
_grid = new Grid(r, c);
var s:Sprite;
for (var i:int = 0; i < r * c; i++) {
var cell:Cell = _grid.cells[i];
addChild(s = Square.createSquare(_cellSize) );
s.x = (i % r) * _cellSize;
s.y = Math.floor(i / r) * _cellSize;
cell.data = [s, new Point(0,0)];
}
}
private function mouseMoveHandler(e:MouseEvent):void
{
var mx:Number = Math.floor(mouseX / _cellSize);
var my:Number = Math.floor(mouseY / _cellSize);
var cell:Cell = _grid.getCellAt(mx, my);
var dx:Number = mouseX - _mpos.x;
var dy:Number = mouseY - _mpos.y;
propagation(cell, 1, dx, dy, 3);
_mpos.x = mouseX;
_mpos.y = mouseY;
}
private function propagation(cell:Cell, gain:Number, dx:Number, dy:Number, depth:int):void
{
var dic:Dictionary = new Dictionary(true);
_propagation(cell, gain, dx, dy, depth, dic);
var c:Cell;
--depth;
}
private function _propagation(cell:Cell, gain:Number, dx:Number, dy:Number, depth:int, dic:Dictionary):void
{
dic[cell] = true;
var p:Point = cell.data[1];
p.x += dx * gain;
p.y += dy * gain;
depth--;
if (depth < 0) {
return;
}
var c:Cell;
var len:int = cell.neighbors.length;
for (var i:int = 0; i < len; i++) {
if ( (c = cell.neighbors[i]) != null) {
if (dic[c]) {
}else {
dic[c] = true;
_propagation(c, gain * 0.8, dx, dy, depth, dic);
}
}
}
}
}
class Square extends Sprite {
private var _color:uint;
private var _size:Number;
public function Square()
{
super();
if (stage) {
initialize();
}else {
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
}
private function initialize():void
{
addEventListener(Event.RENDER, renderHandler);
_redraw();
}
private function addedToStageHandler(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
initialize();
}
public static function createSquare(size:Number, color:uint = 0):Square
{
var s:Square = new Square();
s._size = size;
s._color = color;
return s;
}
private function renderHandler(e:Event):void
{
_redraw();
}
public function get color():uint { return _color; }
public function set color(value:uint):void
{
_color = value;
stage.invalidate();
}
public function get size():Number { return _size; }
public function set size(value:Number):void
{
_size = value;
stage.invalidate();
}
private function _redraw():void
{
graphics.clear();
graphics.beginFill(_color);
graphics.drawRect(0, 0, _size, _size);
graphics.endFill();
}
}
class Grid {
private var _cells:Vector.<Cell>;
private var _rows:int;
private var _cols:int;
public var _dictionary:Dictionary;
/**
*
* @param rows
* @param cols
*/
public function Grid(rows:int, cols:int) {
_rows = rows;
_cols = cols;
_cells = new Vector.<Cell>(_rows * _cols);
_dictionary = new Dictionary(true);
var i:int, j:int;
for (i = 0; i < _rows * _cols; i++) {
_cells[i] = new Cell();
_cells[i].grid = this;
}
var c:Cell;
c = _cells[0];
for (j = 1; j < _rows; j++) {
c.right = _cells[j];
c = _cells[j];
}
for (i = 1; i < _cols; i++) {
c = _cells[i * _rows];
c.upper = _cells[( i - 1) * _rows];
for ( j = 1; j < _rows; j++) {
c.right = _cells[i * _rows + j];
c = c.right;
c.upper = _cells[(i - 1) * _rows + j];
}
}
}
public function forEach(f:Function, thisObj:*):void
{
for (var i:int = 0; i < _cols; i++) {
for (var j:int = 0; j < _rows; j++) {
var c:Cell = _cells[_rows * i + j];
f.call(thisObj, c, j, i, this);
}
}
}
public function getCellAt(row:int, col:int):Cell
{
//note not check index
return _cells[col*_rows + row];
}
public function getCell(obj:*):Cell
{
//data から該当するcellを取得
return _dictionary[obj];
}
public function get rows():int { return _rows; }
public function get cols():int { return _cols; }
public function get cells():Vector.<Cell> { return _cells; }
}
class Cell {
private var _data:*;
private var _neighbors:Vector.<Cell>;
private var _grid:Grid;
public function Cell()
{
_neighbors = new Vector.<Cell>(4);
}
public function get upper():Cell { return _neighbors[0]; }
public function set upper(value:Cell):void
{
_neighbors[0] = value;
value._neighbors[2] = this;
}
public function get right():Cell { return _neighbors[1]; }
public function set right(value:Cell):void
{
_neighbors[1] = value;
value._neighbors[3] = this;
}
public function get under():Cell { return _neighbors[2]; }
public function set under(value:Cell):void
{
_neighbors[2] = value;
value._neighbors[0] = this;
}
public function get left():Cell { return _neighbors[3]; }
public function set left(value:Cell):void
{
_neighbors[3] = value;
value._neighbors[2] = this;
}
public function get data():* { return _data; }
public function set data(value:*):void
{
_data = value;
_grid._dictionary[value] = this;
}
public function get grid():Grid { return _grid; }
public function set grid(value:Grid):void
{
_grid = value;
}
public function get neighbors():Vector.<Cell> { return _neighbors; }
public function set neighbors(value:Vector.<Cell>):void
{
_neighbors = value;
}
}