HTML5赋予Web开发人员更加强大的能力。其中的GeoLocation属性,可以让开发人员非常方便地获取用户的地理位置。结合Google Maps提供的API,就可以直观地在地图上将用户的位置标注出来。
今天带来的是我和Aj同学(博客)几个月前完成的一个小游戏。手机用户直接访问网址,即可参与该游戏。该游戏取材于经典的吃豆人游戏(Pac Man),所不同的是,玩家需要移动自己的真实的地理位置才能移动游戏中角色的位置。该游戏也支持多人对战,不同的玩家分别扮演吃豆人和鬼。
游戏的后端使用的是GAE。
先看模拟器上的截图:
1. 房间列表(index)
2. 创建游戏
3. 游戏进行中
现将开发中的一些心得,尤其是关于前端实现的心得,总结一下,以作抛砖引玉之用。
1. 如何自定义地图样式。
为了尽可能地和原作贴合,我们需要将地图绘制成黑底蓝条的模样,黑色代表可以通行的部分,蓝条代表“墙”或边界。所幸的是google maps已经提供给我们这个方法:
// 自定义地图样式,注意先后顺序不能调换
var stylez = [
{
featureType: "all",
stylers: [
{ hue: "#0000ff" },
{ saturation: 100 },
{ lightness: -40}
]
},
{
featureType: "road",
stylers: [
{ hue: "#000000" },
{ saturation: 75 },
{ lightness: -100}
]
}
];
var styledMapOptions = {
name: "Pac Man"
};
// 设置地图类型
var PacManMapType = new google.maps.StyledMapType(stylez, styledMapOptions);
map.mapTypes.set(MY_MAPTYPE_ID, PacManMapType);
2. 如何获取玩家位置并显示在地图上
// 获取用户位置
navigator.geolocation.getCurrentPosition(function(position) {
lastPos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
map.setCenter(lastPos);
// 初始化地标
origin = new google.maps.Marker({
position: lastPos,
map: map,
draggable: true
});
addMarkerClickListener(origin, messages.prefix_ori);
google.maps.event.trigger(origin, 'click');
}, function() {
alert(messages.geoservice_failed);
});
那么如何做到实时更新用户的位置呢,也非常简单:
// 监听用户位置
navigator.geolocation.watchPosition(function(position) {
// 上传最新位置,不做任何事
var curPos=new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var data='roomName='+roomInfo.roomName+'&location='+curPos.toUrlValue()+'&userName='+roomInfo.me;
Ajax.post('updatelocation', data, function(){});
}, function() {
alert(messages.geoservice_failed);
}, positionOptions);
每当用户位置发生改变时,watchPosition将会被自动回调。
3. 如何在用户选定的出发点和目的地间均匀的绘制豆子。
// 绘制豆子
function drawBeans(){
// 自定义地标图形
var image = new google.maps.MarkerImage('./bean.png', null, null, new google.maps.Point(5, 5));
var overview_path=directionsDisplay.getDirections().routes[0].overview_path;
// 绘制豆子地标
for(var i=1; i!=overview_path.length; ++i){
var prev=overview_path[i-1];
var next=overview_path[i];
// 该路段的豆子数目,约数
var count=Math.round(calcDistance(prev, next)/beanSpacing);
for(var j=0; j!=count; ++j){
var lat=prev.lat()+(next.lat()-prev.lat())*j/count;
var lng=prev.lng()+(next.lng()-prev.lng())*j/count;
var position = new google.maps.LatLng(lat, lng);
var isExisted=false;
for(var k=0; k!=beans.length; ++k){
if(position.equals(beans[k].getPosition())){
isExisted=true;
break;
}
}
if(!isExisted){
var bean=new google.maps.Marker({
position: position,
map: map,
icon: image
});
beans.push(bean);
}
}
}
overview_path是路线的一个属性。之所以使用routes[0],是因为同一个起点和终点间往往可能有不同的路径,通过下标指定为首选的那条路径。overview_path是一个数组,每个元素代表着该路径中的一个拐点,绘制路线其实就是将这些拐点连接起来。
然后,我们通过calcDistance函数计算前后拐点的距离,用这个值除以放置豆子的固定距离值,就可以得到该路段该绘制多少颗豆子,然后依次将这些豆子排布在拐点之间的连线上即可。
那么如何计算拐点间的距离呢?calcDistance的代码如下:
// 计算给定的两个latLng对象之间的距离, 返回单位为米
function calcDistance(pos1, pos2) {
lat1=pos1.lat();
lon1=pos1.lng();
lat2=pos2.lat();
lon2=pos2.lng();
// m (change this constant to get km/miles etc.)
var R = 6371 *1000;
var dLat = (lat2-lat1) * Math.PI / 180;
var dLon = (lon2-lon1) * Math.PI / 180;
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(lat1 * Math.PI / 180 ) * Math.cos(lat2 * Math.PI / 180 ) *
Math.sin(dLon/2) * Math.sin(dLon/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
return Math.round(d);
}
这里涉及到了一些地理和立体几何知识。当然,得到的只是一个近似值。
4. 玩家状态的实时交互
很遗憾的是,这里使用的是Ajax轮询机制。Ajax工具代码如下,很简单:
Ajax={
callback: null,
url: null,
ajaxErrorHandler: function(status, msg){
alert('ajax failed due to '+status+' when fetch '+this.url);
},
get: function(url, func){
this.url=url;
this.callback=func;
xmlhttp.open("GET", ajaxBaseUrl+url, true);
xmlhttp.send();
},
post: function(url, data, func){
this.url=url;
this.callback=func;
xmlhttp.open("POST", ajaxBaseUrl+url, true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send(data);
}
}
Aj同学做的关于websocket的毕设可以很好地解决实时性的问题。当然,还有诸如pushlet等替代技术,我们自己也没有实现,这里就不铺开讲述了。
最后,附上真机调试图和源代码,欢迎探讨。
测试设备是Hegar同学(博客)的moto defy。
- 大小: 49.4 KB
- 大小: 61 KB
- 大小: 8.4 KB
- 大小: 33.5 KB
- 大小: 20.2 KB
分享到:
相关推荐
谷歌地图GoogleMaps3.310 谷歌地图GoogleMaps3.310 谷歌地图GoogleMaps3.310 谷歌地图GoogleMaps3.310
Google Maps in HTML google maps的开源代码
谷歌地图手机版。...不过要花费很少的GPRS流量(5元包月/30兆流量足矣),不想使用积分下载的朋友可以在360软件管家里直接搜索"GoogleMaps"来下载使用也可在我牛里下载(以下链接)【推荐:Google地球_pc端最新版链接...
Google Maps API编程资源大全
googlemaps googlemaps使用 maps 地图
GoogleMaps API V3离线下载工具及使用.zip 主要对其地图的下载,及自我编制。 离线下完全可以使用,只需先进行地图的下载。 添加了控件,离线下可进行操作。。。
China Google Maps 适用于非智能机
包含了google my maps的使用方法,一步一步教你使用google map
本书从易到难、由浅入深、循序渐进地介绍了Google Maps API和Google Earth API的开发技术。本书知识讲解通俗易懂,并有大量的实例供读者更加深刻地巩固所学习的知识,帮助读者更好地进行开发实践。 本书共分为18...
先前上传的资料有编译错误,今天改进了一次好了。这个是目前新Google Maps API使用的最全的DEMO。
flex做的googlemaps 分享一下
dot NET中使用Google Maps 系统要求: 1.Visual Studio 2005或更高版本 2.Microsoft ASP.NET AJAX Extensions支持 3.Internet Explorer 7.0或Mozilla Firefox 2.x
Google Maps API android demo Eciplse project source code and javacript version Google Maps API and Place Search example html.
Google Maps JavaScript API V3应用
详细介绍Google Maps API的应用,光盘配有源代码示例和辅助工具
GoogleMaps PPC版 可用于WM5 WM6 WM6.1
google maps中文版原版,可以运行于os4.3
<br>Written by Schuyler Erle and Rich Gibson, authors of the popular Mapping Hacks, Google Maps Hacks shares dozens of tricks for combining the capabilities of Google Maps with your own datasets....
Google Maps 谷歌地图FLASH Google Maps 谷歌地图 演示地址: http://blog.jyrxw.com/index.php?q=node/34 http://map.jyrxw.com/ Flash版,带定位搜索功能