flash on 2011-2-21
/**
* Copyright hycro ( http://wonderfl.net/user/hycro )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/lNIa
*/
package
{
import alternativ7.engine3d.core.View;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.MouseEvent;
[SWF(width=465, height=465, backgroundColor=0xFFFFFF, frameRate=30)]
public class Sketch_20110220 extends Sprite
{
private var _model:Model;
private var _view:View;
private var _controller:Controller;
public function Sketch_20110220()
{
_model = new Model(31, 31);
_view = new View(_model, "上", "右", "下", "左");
_controller = new Controller(_model, stage);
_controller.attach();
addChild(_view);
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
}
}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.CapsStyle;
import flash.display.IBitmapDrawable;
import flash.display.LineScaleMode;
import flash.display.PixelSnapping;
import flash.display.Shape;
import flash.display.Sprite;
import flash.display.Stage;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.MouseEvent;
import flash.geom.Matrix;
import flash.geom.Rectangle;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
class Model extends EventDispatcher
{
public static const UPDATE:String = "Model.UPDATE";
public static const UP:uint = 0xFF0000;
public static const DOWN:uint = 0x00FF00;
public static const LEFT:uint = 0x0000FF;
public static const RIGHT:uint = 0x0F0F0F;
private var _data:BitmapData;
public function Model(width:uint, height:uint)
{
_data = new BitmapData(width, height, false, 0xFFFFFF);
}
public function get data():BitmapData
{
return _data;
}
public function validate():void
{
var c:uint;
var d1:uint;
var d2:uint;
var d3:uint;
var d4:uint;
var nearest:uint;
var nearestColor:uint;
for (var y:uint = 0; y < _data.height; y++) {
for (var x:uint = 0; x < _data.width; x++) {
c = _data.getPixel(x, y);
if (c != 0xFFFFFF && c != UP && c!= DOWN && c != LEFT && c != RIGHT) {
d1 = distance(c, UP);
d2 = distance(c, DOWN);
d3 = distance(c, LEFT);
d4 = distance(c, RIGHT);
if (d1 < d2) {
nearest = d1;
nearestColor = UP;
} else {
nearest = d2;
nearestColor = DOWN;
}
if (d3 < nearest) {
nearest = d3;
nearestColor = LEFT;
}
if (d4 < nearest) {
nearest = d4;
nearestColor = RIGHT;
}
_data.setPixel(x, y, nearestColor);
}
}
}
}
private function distance(c1:uint, c2:uint):Number
{
var r1:uint;
var r2:uint;
var g1:uint;
var g2:uint;
var b1:uint;
var b2:uint;
r1 = (c1 & 0xFF0000) >> 16;
g1 = (c1 & 0x00FF00) >> 8;
b1 = (c1 & 0x0000FF);
r2 = (c2 & 0xFF0000) >> 16;
g2 = (c2 & 0x00FF00) >> 8;
b2 = (c2 & 0x0000FF);
return Math.abs(r1 - r2) + Math.abs(g1 - g2) + Math.abs(b1 - b2);
}
}
class Controller
{
private const _LengthThreshold:Number = 3.0;
private var _stage:Stage;
private var _model:Model;
private var _tmpCanvas:Shape;
private var _dragFlag:Boolean;
private var _prevMouseX:uint;
private var _prevMouseY:uint;
private var _scaleMatrix:Matrix;
public function Controller(model:Model, stage:Stage)
{
if (model == null || stage == null) {
throw new ArgumentError;
}
_stage = stage;
_model = model;
_dragFlag = false;
_tmpCanvas = new Shape();
_scaleMatrix = new Matrix();
_scaleMatrix.scale(_model.data.width / _stage.stageWidth, _model.data.height / _stage.stageHeight);
}
public function attach():void
{
_stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
_stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
_stage.addEventListener(MouseEvent.ROLL_OUT, mouseOutHandler);
_stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
_stage.addEventListener(Event.RESIZE, stageResizeHandler);
}
public function detach():void
{
_stage.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
_stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
_stage.removeEventListener(MouseEvent.ROLL_OUT, mouseOutHandler);
_stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
_stage.removeEventListener(Event.RESIZE, stageResizeHandler);
}
// MOUSE DOWN
private function mouseDownHandler(event:MouseEvent):void
{
_dragFlag = true;
_prevMouseX = event.stageX;
_prevMouseY = event.stageY;
}
// MOUSE UP
private function mouseUpHandler(event:MouseEvent):void
{
_dragFlag = false;
}
// MOUSE OUT
private function mouseOutHandler(event:MouseEvent):void
{
_dragFlag = false;
}
// MOUSE MOVE
private function mouseMoveHandler(event:MouseEvent):void
{
if (_dragFlag) {
var currMouseX:uint = event.stageX;
var currMouseY:uint = event.stageY;
if (currMouseX < 0 || _stage.stageWidth <= currMouseX ||
currMouseY < 0 || _stage.stageHeight <= currMouseY) {
return;
}
// マウスの移動距離を計算
var dx:int = currMouseX - _prevMouseX;
var dy:int = currMouseY - _prevMouseY;
var d:Number = Math.sqrt(dx*dx + dy*dy);
// 線の太さを決定
var tickness:uint;
if (d < 3) {
return;
} else if (d < 6) {
tickness = 1;
} else if (d < 9) {
tickness = 2;
} else if (d < 12) {
tickness = 3;
} else {
tickness = 4;
}
// 線の色を決定
var color:uint;
if (Math.abs(dx) < Math.abs(dy)) {
if (dy < 0) {
color = Model.UP;
} else {
color = Model.DOWN;
}
} else {
if (dx < 0) {
color = Model.LEFT;
} else {
color = Model.RIGHT;
}
}
// 線を描画
_tmpCanvas.graphics.clear();
_tmpCanvas.graphics.lineStyle(tickness, color, 1.0, true, LineScaleMode.NONE, CapsStyle.NONE);
_tmpCanvas.graphics.moveTo(_prevMouseX, _prevMouseY);
_tmpCanvas.graphics.lineTo(currMouseX, currMouseY);
// データの更新
_model.data.draw(_tmpCanvas, _scaleMatrix);
_model.validate();
_model.dispatchEvent(new Event(Model.UPDATE));
// マウス位置の記録
_prevMouseX = currMouseX;
_prevMouseY = currMouseY;
}
}
private function stageResizeHandler(evt:Event):void
{
_scaleMatrix = new Matrix();
_scaleMatrix.scale(_model.data.width / _stage.stageWidth, _model.data.height / _stage.stageHeight);
}
}
class View extends Sprite
{
private var _model:Model;
private var _canvas:Bitmap;
private var _format:TextFormat;
private var _tfUp:TextField;
private var _tfDown:TextField;
private var _tfLeft:TextField;
private var _tfRight:TextField;
private var _tfWidth:Number;
private var _tfHeight:Number;
public function View(model:Model, up:String, right:String, down:String, left:String)
{
_model = model;
_model.addEventListener(Model.UPDATE, modelUpdateHandler);
_format = new TextFormat("小塚明朝 Pro L,明朝");
_tfUp = new TextField();
_tfDown = new TextField();
_tfLeft = new TextField();
_tfRight = new TextField();
setText(up, down, left, right);
this.addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
private function addedToStageHandler(evt:Event):void
{
this.removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
stage.addEventListener(Event.RESIZE, stageResizeHandler);
_canvas = new Bitmap(new BitmapData(stage.stageWidth, stage.stageHeight));
addChild(_canvas);
_tfWidth = stage.stageWidth / _model.data.width;
_tfHeight = stage.stageHeight / _model.data.height;
}
private function stageResizeHandler(evt:Event):void
{
_canvas.bitmapData.dispose();
removeChild(_canvas);
_canvas = new Bitmap(new BitmapData(stage.stageWidth, stage.stageHeight));
addChild(_canvas);
_tfWidth = stage.stageWidth / _model.data.width;
_tfHeight = stage.stageHeight / _model.data.height;
}
public function setText(up:String, down:String, left:String, right:String):void
{
_tfUp.text = up.charAt();
_tfDown.text = down.charAt();
_tfLeft.text = left.charAt();
_tfRight.text = right.charAt();
_tfUp.setTextFormat(_format);
_tfDown.setTextFormat(_format);
_tfLeft.setTextFormat(_format);
_tfRight.setTextFormat(_format);
}
private function modelUpdateHandler(evt:Event):void
{
_canvas.bitmapData.fillRect(_canvas.bitmapData.rect, 0xFFFFFF);
draw(4, _model.data.clone());
}
private function draw(size:int, data:BitmapData):void
{
if (size <= 0) {
return;
}
var dataWidth:int = data.width-size;
var dataHeight:int = data.height-size;
var color:uint;
var matrix:Matrix;
var tf:TextField;
for (var j:int = 0; j < dataHeight; j++) {
for (var i:int = 0; i < dataWidth; i++) {
color = check(data, i, j, size);
if (color) {
switch (color) {
case Model.UP:
tf = _tfUp;
break;
case Model.DOWN:
tf = _tfDown;
break;
case Model.LEFT:
tf = _tfLeft;
break;
case Model.RIGHT:
tf = _tfRight;
break;
default:
continue;
}
matrix = new Matrix();
matrix.scale(size, size);
matrix.translate(i*_tfWidth, j*_tfHeight);
_canvas.bitmapData.draw(tf, matrix);
i+=size-1;
}
}
}
draw(size-1, data);
}
private function check(data:BitmapData, x:int, y:int, size:int):uint
{
var color:uint = data.getPixel(x, y);
if (color == 0xFFFFFF) {
return 0;
}
var tmp:uint;
for (var j:int = 0; j < size; j++) {
for (var i:int = 1; i < size; i++) {
tmp = data.getPixel(x+i, y+j);
if (tmp == 0xFFFFFF || color != tmp) {
return 0;
}
color = tmp;
}
}
data.fillRect(new Rectangle(x, y, size, size), 0xFFFFFF);
return color;
}
}