flash on 2011-10-10
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
public class Main extends Sprite
{
private var bd:BitmapData;
public function Main()
{
bd = new BitmapData(100, 100, false);
var bitmap:Bitmap = new Bitmap(bd);
bitmap.scaleX = bitmap.scaleY = 4.5;
addChild(bitmap);
stage.addEventListener(MouseEvent.CLICK, onMouseClick);
onMouseClick();
}
private function onMouseClick(event:MouseEvent = null):void
{
// 部屋を描く範囲
var rect:Rectangle = new Rectangle(10, 10, 30, 30);
// 部屋の領域を赤線で描く
bd.fillRect(rect, 0xED1A3D);
bd.fillRect(new Rectangle(rect.x + 1, rect.y + 1, rect.width - 2, rect.height - 2), 0xFFFFFF);
// Bresenhamの線分アルゴリズムで、部屋の輪郭を描く
drawIrregularShape(rect.x, rect.y, rect.width, rect.height, 20, 20);
// 内部を塗りつぶす。
bd.floodFill(rect.x + rect.width / 2, rect.y + rect.height / 2, 0x0);
}
private function drawIrregularShape(x:Number, y:Number, width:Number, height:Number, innerWidth:Number, innerHeight:Number):void
{
var outerWidth:Number = (width - innerWidth) / 2;
var outerHeight:Number = (height - innerHeight) / 2;
var points/*Array*/:Array = [[], [], [], []];
var pos:Array =
[
[outerWidth, 0, innerWidth, outerHeight],
[outerWidth + innerWidth, outerHeight, outerWidth, innerHeight],
[outerWidth, outerHeight + innerHeight, innerWidth, outerHeight],
[0, outerHeight, outerWidth, innerHeight]
];
for (var i:int = 0; i < points.length; i++)
{
var maxCount:int = Math.random() * 2 + 4;
for (var count:int = 0; count < maxCount; count++)
{
var p:Array = pos[i];
points[i].push(getRandomPoint(p[0], p[1], p[2], p[3]));
}
}
points[0].sortOn("x", Array.NUMERIC);
points[1].sortOn("y", Array.NUMERIC);
points[2].sortOn("x", Array.NUMERIC | Array.DESCENDING);
points[3].sortOn("y", Array.NUMERIC | Array.DESCENDING);
var prev:Point = new Point(x + points[0][0].x, y + points[0][0].y);
for (i = 0; i < points.length; i++)
{
for (var j:int = 0; j < points[i].length; j++)
{
drawLine(prev.x, prev.y, x + points[i][j].x, y + points[i][j].y);
prev.x = x + points[i][j].x;
prev.y = y + points[i][j].y;
}
}
drawLine(prev.x, prev.y, x + points[0][0].x, y + points[0][0].y);
}
private function getRandomPoint(x:Number, y:Number, width:Number, height:Number):Point
{
return new Point(x + width * Math.random(), y + height * Math.random());
}
public function drawLine(x0:int, y0:int, x1:int, y1:int):void
{
var steep:Boolean = Math.abs(y1 - y0) > Math.abs(x1 - x0);
var temp:int;
if (steep)
{
temp = x0;
x0 = y0;
y0 = temp;
temp = x1;
x1 = y1;
y1 = temp;
}
if (x0 > x1)
{
temp = x0;
x0 = x1;
x1 = temp;
temp = y0;
y0 = y1;
y1 = temp;
}
var dx:int = x1 - x0;
var dy:int = Math.abs(y1 - y0);
var error:Number = 0.5 * dx;
var yStep:int = (y0 < y1) ? 1 : -1;
for (var ty:int = y0, tx:int = x0; tx <= x1; tx++)
{
if (steep) bd.setPixel(ty, tx, 0x0);
else bd.setPixel(tx, ty, 0x0);
error += dy;
if (error >= dx)
{
error -= dx;
ty += yStep;
}
}
}
}
}