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

