こんばんは。年越しそばを食べました、kijimaです。

前回の記事、「Google Maps API for Flash ルート検索を使って経路を地図上に表示させる(サンプルコード付)」から調子に乗って、ルートに沿ってコンチを歩かせてみました。

地図が表示されたら、コンチにタッチしてみてください。カヤック自由が丘支社から鎌倉本社に向けて歩き出します。

 

最新版のAdobe FlashPlayerをインストールしてください。

 

ルート経路を表すPolyLineから点となる座標(緯度・経度)を取得して、配列に保持しておきます。そして、その配列のlength分だけTimerEventを設定し、Timer処理が実行されるたびに、配列に保持しておいた座標にコンチを移動させる、という仕組み。

ちなみに、移動中に地図上のズームレベルをあげて拡大表示すると、高速移動するコンチが見られます(笑)

実際のサンプルコードは以下のようになりました。

 

package {	
	import flash.display.*;
	import flash.events.*;
	import flash.geom.Point;
	import flash.utils.Timer;

	import com.google.maps.*;
    import com.google.maps.controls.*;
	import com.google.maps.overlays.*;
	import com.google.maps.services.*;
	import com.google.maps.interfaces.*;	
	
	public class SetRoute extends Sprite {
		
		private var _map:Map;
		private var _positionControl:PositionControl;
		private var _typeControl:MapTypeControl;
		private var _zoomControl:ZoomControl;
				
		private var zoomParam:int = 5;
		private var moveSpeed:int = 50;
		private var startName:String = "東京都目黒区自由が丘2-8-6";
		private var goalName:String = "神奈川県鎌倉市小町2-14-7";
		
		private var route:Route;
		private var routeArray:Array;
		private var polyLine:IPolyline;
		private var startMarker:Marker;
		private var goalMarker:Marker;
		
		private var chara_mc:MovieClip;

		private var directions:Directions;
		private var timer:Timer;
		private var currentPositionNumber:int = 0;//ルート内の現在位置(ステップのナンバー)
		private var maxNumber:int;//
		private function get remainNumber():int { return maxNumber - currentPositionNumber; }; 

		public static const SET_ROUTE_SUCCESS:String = "SET_ROUTE_SUCCESS";
		public static const SET_ROUTE_FAILED:String = "SET_ROUTE_FAILED";
		
		public function SetRoute(){
			createMap();
		}
		
		private function createMap():void {
			_map = new Map();
			_map.key = "hoge";
			_map.language = "ja";
			_map.setSize(new Point(stage.stageWidth, stage.stageHeight));

			var positionControl:PositionControl = new PositionControl();
			var typeControl:MapTypeControl = new MapTypeControl();
			var zoomControl:ZoomControl = new ZoomControl();
			
			_map.addControl(positionControl);
			_map.addControl(typeControl);
			_map.addControl(zoomControl);
			
			addChild(_map);
			
			_map.addEventListener(MapEvent.MAP_READY, onMapReady);
		}
		
		private function onMapReady(e:MapEvent):void {
			_map.removeEventListener(MapEvent.MAP_READY, onMapReady);
			_map.overlayRaising = false;
			
			setRoute( new DirectionsOptions( { avoidHighways:false, travelMode:"TRAVEL_MODE_DRIVING"} ) );
		}
		
		private function setRoute(opt:DirectionsOptions) {
			directions = new Directions(opt);
			directions.addEventListener(DirectionsEvent.DIRECTIONS_SUCCESS, directionSuccess);
			directions.addEventListener(DirectionsEvent.DIRECTIONS_FAILURE, directionFail);
			directions.load( "from: " + startName + " to: " + goalName );
		}
		
		private function directionFail(event:DirectionsEvent) : void {
			trace( "ルート設定失敗 " + event.status);
		}
		
		private function directionSuccess(event:DirectionsEvent) : void {
			trace("ルート設定成功 " + event.status );
			
			route = directions.getRoute(0);
			var polylineOption:PolylineOptions = new PolylineOptions({
				strokeStyle: {
					thickness: 5,
					color: 0xFF00FF,
					alpha: 0.5
				}
			});
			
			polyLine = directions.createPolyline(polylineOption);
			_map.addOverlay(polyLine);
			
			//ルートにあわせて地図の表示拡大率を変更
			var bounds:LatLngBounds = directions.bounds;
			var zoom:Number = _map.getBoundsZoomLevel(bounds);
			_map.setCenter(bounds.getCenter(), zoom);
			
			setMarker();
			setPoint(polyLine);
			
		}
		
		//出発地と目的地にマーカーを表示させる
		private function setMarker():void {
			var startLatLng:LatLng = route.getStep(0).latLng;
			var goalLatLng:LatLng = route.endLatLng;
			
			//出発地に表示させるマーカーアイコン
			var startOption:MarkerOptions = new MarkerOptions( {
				icon:new Konchi(),	//カスタムアイコンを設定
				hasShadow:false,		//マーカーに影をつけるかどうか
				clickable:false,	//クリック可能かどうか。初期値はtrue
				draggable:true		//ドラッグ可能かどうか。初期値はfalse
			} );
			
			//目的地に表示させるマーカーアイコン
			var goalOption:MarkerOptions = new MarkerOptions( {
				hasShadow:false,
				clickable:false,	//クリック可能かどうか。初期値はtrue
				draggable:true		//ドラッグ可能かどうか。初期値はfalse
			} );
			
			startMarker = new Marker(route.getStep(0).latLng, startOption );
			goalMarker = new Marker(route.endLatLng, goalOption );
			
			//出発地のカスタムアイコンに対してマウスイベントを設定
			chara_mc = MovieClip( startMarker.getOptions().icon );
			chara_mc.addEventListener(MouseEvent.CLICK, startMove);
			
			_map.addOverlay(goalMarker);
			_map.addOverlay(startMarker);
		}
		
		//ルート経路のPolyLineから座標を取得して、配列に保持しておく
		private function setPoint(p:IPolyline):void {
			var ar:Array = [];
			var len = p.getVertexCount();
			for (var i:int = 0; i < len; i++) {
				ar.push(p.getVertex(i));				
				if (i == len -1) routeArray = ar;
			}
			maxNumber = len;
		}
		
		//キャラクターの移動
		public function startMove():void {
			chara_mc.removeEventListener(MouseEvent.CLICK, startMove);
			
			if (remainNumber <= 0 ) return;
			if (timer != null) {
				timer.stop();
				timer.removeEventListener(TimerEvent.TIMER, arguments.callee);
				timer.removeEventListener(TimerEvent.TIMER_COMPLETE, arguments.callee);
			}
			timer = new Timer(moveSpeed, remainNumber);
			
			timer.addEventListener(TimerEvent.TIMER, function():void {
				startMarker.setLatLng(routeArray[currentPositionNumber]);				
				_map.panTo(routeArray[currentPositionNumber]);
				currentPositionNumber ++;
			});
			
			
			timer.addEventListener(TimerEvent.TIMER_COMPLETE, function() {
				//到着
				timer.stop();
				timer.removeEventListener(TimerEvent.TIMER, arguments.callee);
			} );
			
			
			timer.start();
		}
	}
}

 

これで、移動中に地図上に登場するワンコと当たり判定を設定して、コンチがワンコと衝突するとゲームオーバー!なんていうひどいゲームも作れます。いや、作らないですけど。。

HTML5飯