Home > Archives > 2010-09-06

2010-09-06

経路探索 + クォータービュー

iso

クォータービューでの経路探索を試作。いまさらですが。
青い障害物を避け、クリックした箇所に赤い箱が移動します。
障害物はランダムに配置されます。
iso + A*

見てお分かりの通り詳解 ActionScript 3.0アニメーションの3章・4章の組み合わせです。

メインとなるソースコードのみ貼っておきます。他の使用しているクラスは書籍と同じなので省きます。

package {
	import com.friendsofed.isometric.DrawnIsoBox;
	import com.friendsofed.isometric.DrawnIsoTile;
	import com.friendsofed.isometric.IsoUtils;
	import com.friendsofed.isometric.IsoWorld;
	import com.friendsofed.isometric.Point3D;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.MouseEvent;
	import flash.geom.Point;
	import org.libspark.betweenas3.BetweenAS3;
	import org.libspark.betweenas3.easing.Linear;
	import org.libspark.betweenas3.tweens._iTween;

	[SWF(backgroundColor=0xFFFFFF, width=830, height=500, frameRate=60)]
    public class GameIso extends Sprite {
		private static const _NUM_COLS:int = 20;
		private static const _NUM_ROWS:int = 20;
		private static const _CELL_SIZE:int = 20;
		private static const _BOX_HEIGHT:int = 22;

		private var _world:IsoWorld;
        private var _grid:Grid;
        private var _player:DrawnIsoBox;
        private var _index:int;
        private var _path:Array;
		private var _iTween:_iTween;

        public function GameIso() {
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;

			_world = new IsoWorld();
            _world.x = stage.stageWidth / 2;
            _world.y = 50;
            addChild(_world);

            makePlayer();
            makeGrid();
			drawGrid();

            _world.addEventListener(MouseEvent.CLICK, onGridClick);
        }

        private function makePlayer():void {
			_player = new DrawnIsoBox(_CELL_SIZE, 0xff0000, _BOX_HEIGHT);
            _player.x = _CELL_SIZE * int(Math.random() * _NUM_COLS);
            _player.z = _CELL_SIZE * int(Math.random() * _NUM_ROWS);
            _world.addChildToWorld(_player);
        }

        private function makeGrid():void {
            _grid = new Grid(_NUM_COLS, _NUM_ROWS);
            for (var i:int = 0; i < 60; i++) {
                _grid.setWalkable(Math.floor(Math.random() * _NUM_COLS),
                                  Math.floor(Math.random() * _NUM_COLS),
                                  false);
            }
        }

        private function drawGrid():void {
            for (var i:int = 0; i < _grid.numCols; i++) {
                for (var j:int = 0; j < _grid.numRows; j++) {
                    var node:Node = _grid.getNode(i, j);
					if (node.walkable) {
						var tile:DrawnIsoTile = new DrawnIsoTile(_CELL_SIZE, 0xffffff);
						tile.position = new Point3D(i * _CELL_SIZE, 0, j * _CELL_SIZE);
						_world.addChildToFloor(tile);
					}
					else {
						var box:DrawnIsoBox = new DrawnIsoBox(_CELL_SIZE, 0x336699, _BOX_HEIGHT);
						box.x = i * _CELL_SIZE;
						box.z = j * _CELL_SIZE;
						_world.addChildToWorld(box);
					}
                }
            }
        }

        private function onGridClick(event:MouseEvent):void {
			var p:Point3D = IsoUtils.screenToIso(new Point(_world.mouseX, _world.mouseY));

			var xpos:int = Math.floor((p.x + _CELL_SIZE / 2) / _CELL_SIZE);
            var ypos:int = Math.floor((p.z + _CELL_SIZE / 2) / _CELL_SIZE);
            _grid.setEndNode(xpos, ypos);

			xpos = Math.floor((_player.x + _CELL_SIZE / 2) / _CELL_SIZE);
            ypos = Math.floor((_player.z + _CELL_SIZE / 2) / _CELL_SIZE);

            _grid.setStartNode(xpos, ypos);
            findPath();
        }

        /**
         * AStarのインスタンスを生成して、経路探索に用いる。
         */
        private function findPath():void {
            var astar:AStar = new AStar();
            if (astar.findPath(_grid)) {
				if(_iTween && _iTween.isPlaying) _iTween.stop();
                _path = astar.path;
                _index = -1;
				move();
            }
        }

		private function move():void {
			if (_path[++_index]) {
				var targetX:Number = _path[_index].x * _CELL_SIZE;
				var targetY:Number = _path[_index].y * _CELL_SIZE;

				_iTween = BetweenAS3.tween(_player, { x: targetX, z:targetY }, null, 0.1, Linear.easeNone);
				_iTween.onComplete = move;
				_iTween.onUpdate = _world.sort;
				_iTween.play();
            }
		}
    }
}

wonderflのタグをsuggestするグリモンを更新

suggest

以前wonderflでお気に入り作品にタグ付けする際、サジェストを出すグリモンを書いたのですが、
wonderflのHTML構造が変更されたので使えなくなっていました。

今回、新しいページ構造でも使えるようアップデートしました。
元のページか下記からインストールお願いします。

wonderflTagSuggest.user.js

Home > Archives > 2010-09-06

Return to page top