Google Maps API for Flash を利用してコンチを地図上で歩かせてみた(サンプルコード付)
こんばんは。年越しそばを食べました、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(); } } }
これで、移動中に地図上に登場するワンコと当たり判定を設定して、コンチがワンコと衝突するとゲームオーバー!なんていうひどいゲームも作れます。いや、作らないですけど。。