HourGlass
// forked from saharan's 流砂
/**
* Flash初作品です。
* 以前作った流砂のシミュレーションをASで実装してみるテスト。
* 右クリックメニューから描くタイプを選べます。
*/
package {
import flash.ui.*;
import fl.controls.*;
import flash.text.*;
import flash.geom.*;
import flash.events.*;
import flash.display.*;
[SWF(width = 465, height = 465, frameRate = 60)]
public class Sand extends Sprite {
private const WIDTH:int = 465;
private const HEIGHT:int = 465;
private const BACK:int = 0x000000;
private const WALL:int = 0x333333;
private const SAND:int = 0xff0000;
private var draw:int;
private var prevMouseX:int;
private var prevMouseY:int;
private var world:BitmapData;
private var bitmap:Bitmap;
private var count:int;
private var mousePressed:Boolean;
private var sandBitmap:BitmapData;
public function Sand() {
initialize();
}
private function initialize():void {
var sand:ContextMenuItem = new ContextMenuItem("Sand");
sand.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, function():void {
draw = SAND;
});
var wall:ContextMenuItem = new ContextMenuItem("Wall");
wall.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, function():void {
draw = WALL;
});
var erase:ContextMenuItem = new ContextMenuItem("Erase");
erase.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, function():void {
draw = BACK;
});
sandBitmap = new BitmapData(2, 2);
sandBitmap.setPixel(0, 0, 0xffff00);
sandBitmap.setPixel(1, 0, 0xffffff);
sandBitmap.setPixel(0, 1, 0xff5500);
sandBitmap.setPixel(1, 1, 0x55ff00);
contextMenu = new ContextMenu();
contextMenu.hideBuiltInItems();
contextMenu.customItems = [sand, wall, erase];
draw = SAND;
count = 0;
world = new BitmapData(WIDTH, HEIGHT, false, 0);
world.draw(stage);
bitmap = new Bitmap(world);
addChild(bitmap);
stage.addEventListener(MouseEvent.MOUSE_DOWN,
function():void {
mousePressed = true;
});
stage.addEventListener(MouseEvent.MOUSE_UP,
function():void {
mousePressed = false;
});
addEventListener(Event.ENTER_FRAME, frame);
stage.quality = StageQuality.LOW;
drawHourGlass();
}
private function drawHourGlass():void
{
var s:Sprite = new Sprite;
world.lock();
s.graphics.beginBitmapFill( sandBitmap );
s.graphics.moveTo( 100, 100 );
s.graphics.lineTo( 300, 100 );
s.graphics.curveTo( 300, 200, 203, 200 );
s.graphics.lineTo( 196, 200 );
s.graphics.curveTo( 100, 200, 100, 100 );
s.graphics.endFill();
s.graphics.lineStyle( 6, WALL );
s.graphics.moveTo( 100, 100 );
s.graphics.lineTo( 300, 100 );
s.graphics.curveTo( 300, 200, 203, 200 );
s.graphics.lineTo( 203, 250 );
s.graphics.curveTo( 300, 250, 300, 350 );
s.graphics.lineTo( 100, 350 );
s.graphics.curveTo( 100, 250, 196, 250 );
s.graphics.lineTo( 196, 200 );
s.graphics.curveTo( 100, 200, 100, 100 );
world.draw(s);
}
private function frame(e:Event):void {
//TODO
var s:Sprite = new Sprite();
world.lock();
if(mousePressed) {
if(draw == SAND) {
s.graphics.beginBitmapFill(sandBitmap);
s.graphics.drawEllipse(mouseX - 3, mouseY - 3, 6, 6);
s.graphics.endFill();
s.graphics.lineStyle(6);
s.graphics.lineBitmapStyle(sandBitmap);
s.graphics.moveTo(prevMouseX, prevMouseY);
s.graphics.lineTo(mouseX, mouseY);
world.draw(s);
} else {
s.graphics.beginFill(draw);
s.graphics.drawEllipse(mouseX - 3, mouseY - 3, 6, 6);
s.graphics.endFill();
s.graphics.lineStyle(6, draw);
s.graphics.moveTo(prevMouseX, prevMouseY);
s.graphics.lineTo(mouseX, mouseY);
world.draw(s);
}
}
prevMouseX = mouseX;
prevMouseY = mouseY;
var i:int;
var j:int;
if(count % 2 == 0)
for(j = HEIGHT - 1; j >= 0; j--) {
for(i = 0; i < WIDTH; i++) {
doPixel(i, j, true);
}
}
else
for(j = HEIGHT - 1; j >= 0; j--) {
for(i = WIDTH - 1; i >= 0; i--) {
doPixel(i, j, false);
}
}
count = (count + 1) % 2;
world.unlock();
}
private function doPixel(x:int, y:int, flip:Boolean):void {
var pixel:int = world.getPixel(x, y);
switch(pixel) {
case BACK:
case WALL:
break;
default:
if(Math.random() > 0.05) {
if(flip) {
if(world.getPixel(x, y + 1) == BACK) {
world.setPixel(x, y + 1, pixel);
world.setPixel(x, y, BACK);
} else if(world.getPixel(x + 1, y + 1) == BACK) {
world.setPixel(x + 1, y + 1, pixel);
world.setPixel(x, y, BACK);
} else if(world.getPixel(x - 1, y + 1) == BACK) {
world.setPixel(x - 1, y + 1, pixel);
world.setPixel(x, y, BACK);
} else if(world.getPixel(x + 1, y) == BACK) {
world.setPixel(x + 1, y, pixel);
world.setPixel(x, y, BACK);
} else if(world.getPixel(x - 1, y) == BACK) {
world.setPixel(x - 1, y, pixel);
world.setPixel(x, y, BACK);
}
} else {
if(world.getPixel(x, y + 1) == BACK) {
world.setPixel(x, y + 1, pixel);
world.setPixel(x, y, BACK);
} else if(world.getPixel(x - 1, y + 1) == BACK) {
world.setPixel(x - 1, y + 1, pixel);
world.setPixel(x, y, BACK);
} else if(world.getPixel(x + 1, y + 1) == BACK) {
world.setPixel(x + 1, y + 1, pixel);
world.setPixel(x, y, BACK);
} else if(world.getPixel(x - 1, y) == BACK) {
world.setPixel(x - 1, y, pixel);
world.setPixel(x, y, BACK);
} else if(world.getPixel(x + 1, y) == BACK) {
world.setPixel(x + 1, y, pixel);
world.setPixel(x, y, BACK);
}
}
}
break;
}
}
}
}