グリッド空間にオブジェクトを配置する
マウスが領域外に出てしまうと・・・
package {
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
[SWF(width = "400", height = "400", frameRate = "60", backgroundColor = "#FFFFFF")]
public class Map extends Sprite {
private const EMPTY:int = -1;
public static const ROW:int = 8;
public static const COL:int = 8;
public static const SIZE:int = 50;
private var _map:Vector.<Vector.<int>>;
private var _chips:Vector.<Circle>;
public function Map():void {
if (stage) {
init();
} else {
addEventListener(Event.ADDED_TO_STAGE, init);
}
}
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
_map = new Vector.<Vector.<int>>();
for (var j:int = 0; j < ROW; j++) {
var line:Vector.<int> = new Vector.<int>();
for (var i:int = 0; i < COL; i++) {
line.push(EMPTY);
}
_map.push(line);
}
_chips = new Vector.<Circle>();
for (var k:int = 0; k < 5; k++) {
var circle:Circle;
do {
circle = new Circle(RandomInt(10, 20), 0xFFFFFF * Math.random());
} while (_isDuplicate(circle))
do {
circle.x = 400 * Math.random();
circle.y = 400 * Math.random();
} while (!_setChip(circle))
circle.addEventListener(MouseEvent.MOUSE_DOWN, _pickup);
circle.addEventListener(Event.CHANGE, _posChanged);
addChild(circle);
_chips.push(circle);
}
_drawGridlines();
_drawChips();
}
// ランダムな整数を取得
public function RandomInt(nInt1:Number, nInt2:Number):Number {
// 第2パラメータnInt2が指定されていない場合の処理
// nInt2が数値でなければ0を代入
if (typeof (nInt2) != "number") {
nInt2 = 0;
}
// 大きい方の値をnMaxに小さい方の値をnMinに設定
var nMax:Number = Math.max(nInt1, nInt2);
var nMin:Number = Math.min(nInt1, nInt2);
// nMinからnMaxまでのランダムな整数を返す
var nRandomInt:Number = Math.floor( Math.random() * (nMax - nMin + 1) ) + nMin;
return nRandomInt;
}
private function _pickup(e:MouseEvent):void {
// 最前面に表示されるようにする
setChildIndex(DisplayObject(e.target), numChildren - 1);
}
// オブジェクトの位置変更を検知し画面に反映する
private function _posChanged(e:Event):void {
var chip:Circle = e.currentTarget as Circle;
if (_isEmpty(chip.cur) && (chip.old != chip.cur)) {
_setEmpty(chip.old);
chip.old = chip.cur;
_setChip(chip);
} else {
chip.x = SIZE * chip.old.x;
chip.y = SIZE * chip.old.y;
}
_drawChips();
}
private function _setChip(chip:Circle):Boolean {
if (_isEmpty(chip.cur)) {
_map[chip.cur.y][chip.cur.x] = chip.id;
return true;
} else {
return false;
}
}
private function _setEmpty(pos:Point):void {
_map[pos.y][pos.x] = EMPTY;
}
private function _isEmpty(pos:Point):Boolean {
if (_map[pos.y][pos.x] == EMPTY) {
return true;
} else {
return false;
}
}
private function _isDuplicate(target:Circle):Boolean {
var temp:Vector.<Circle> = _chips.filter(
/**
* Vectorオブジェクトの重複判定用filter関数
*
* @param item vecの要素
* @param index itemが格納されているvecの添字
* @param vec 検査対象のVectorオブジェクト
* @return 検査条件を満たす要素が存在すれば真、そうでなければ偽。
*/
function(item:Circle, index:int, vec:Vector.<Circle>):Boolean {
if (item.id == target.id) {
return true;
}
return false;
}
);
if (temp.length > 0) {
return true;
} else {
return false;
}
}
private function _drawGridlines():void {
graphics.lineStyle(1, 0x000000, 1.0);
var k:int;
for (k = 0; k <= COL; k++) {
graphics.moveTo(50 * k, 0);
graphics.lineTo(50 * k, 400);
}
for (k = 0; k <= ROW; k++) {
graphics.moveTo(0, 50 * k);
graphics.lineTo(400, 50 * k);
}
}
private function _drawChips():void {
for (var k:int = 0; k < _chips.length; k++) {
var cur:Point = _chips[k].cur;
_chips[k].x = SIZE * cur.x;
_chips[k].y = SIZE * cur.y;
}
}
}
}
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.DropShadowFilter;
import flash.geom.Point;
class Circle extends Sprite {
private static const ALPHA_RATE:Number = 1.0;
private var _id:int;
private var _old:Point;
public function Circle(id:int, color:uint):void {
_id = id;
alpha = ALPHA_RATE;
graphics.beginFill(color);
graphics.drawCircle(25, 25, 25);
graphics.endFill();
addEventListener(MouseEvent.MOUSE_DOWN, _pickup);
addEventListener(MouseEvent.MOUSE_UP, _place);
addEventListener(MouseEvent.MOUSE_OVER, _handCursor);
addEventListener(MouseEvent.MOUSE_OUT, _arrowCursor);
}
public function get id():int {
return _id;
}
public function get cur():Point {
var xidx:int = _pixel2index(x);
if (xidx >= Map.COL) {
xidx = Map.COL - 1;
}
var yidx:int = _pixel2index(y);
if (yidx >= Map.ROW) {
yidx = Map.ROW - 1;
}
return new Point(xidx, yidx);
// return new Point(_pixel2index(x), _pixel2index(y));
}
public function get old():Point {
return _old;
}
public function set old(pos:Point):void {
_old = pos;
}
private function _pixel2index(pixel:int):int {
// return pixel / Main.SIZE;
return (pixel + Map.SIZE / 2) / Map.SIZE;
}
// ドラッグ処理を開始し影フィルターを付ける
private function _pickup(e:MouseEvent):void {
e.target.startDrag();
e.target.filters = [new DropShadowFilter()];
_old = cur
}
// ドラッグ処理を終了し影フィルターを外す
private function _place(e:MouseEvent):void {
e.target.stopDrag();
e.target.filters = null;
dispatchEvent(new Event(Event.CHANGE));
}
// 指差しハンドポインタ表示を有効にする
private function _handCursor(e:MouseEvent):void {
var target:Sprite = e.currentTarget as Sprite;
target.buttonMode = true;
target.useHandCursor = true;
}
// 指差しハンドポインタ表示を無効にする
private function _arrowCursor(e:MouseEvent):void {
var target:Sprite = e.currentTarget as Sprite;
target.buttonMode = false;
target.useHandCursor = false;
}
}