zeerd's blog     Article     Search     About     Tags     Pebble     Feed

闲来生雅趣,无事乐逍遥。对窗相望雪,一盏茶香飘。

基于地理位置的寻宝类游戏实现(核心部分)

#Game


《重出江湖》中有一件道具,叫做“七色七音盒”。使用这个道具,可以指引玩家找到一些用来增加经验值的道具。

具体的用法就是使用一下七色七音盒,盒子会告诉玩家在某个方向可以找到增加经验值的道具。总共可以使用七次,如果还没有找到,盒子就会爆掉。

我原本的目的就是要在微信的公众账号平台上实现这个七色七音盒的现实版。不过,由于后来发现微信的位置信息并非绝对的使用者所在位置,而是可以在发送之前进行调节。这就导致了玩家上传的位置信息可以随意作假,导致游戏可玩度和公平性下降。同时,原本打算借助的百度地图API,在进行基于经纬度的周边检索时位置偏移非常严重,也严重影响了游戏判定算法的实现。综合上面两个原因,这个游戏的开发工作中止了。所以,在这里,把之前研究出来的一些结果发布一下。

其实,主体的思路很简单。玩家上传自己所在位置的经纬度信息,也就是微信中的“位置”信息。通过微信公众平台的API,可以从位置信息中解析出经纬度值。然后,通过js脚本传送给百度地图API。

百度地图API根据传入的经纬度信息,在其周边指定范围内随机抽选一个商户或其他有名称的建筑信息,并将名称及相对玩家所在位置的方位信息和可能需要的步行距离发送给玩家。玩家根据给定的名称和方位找到任务目标,并再次上传位置信息。如果位置信息在目标的一定范围内,则游戏完成。

百度地图利用部分的简单脚本实现已经完成,内容如下: (其中的TypeMap借用了如下网址的map实现,我只是为了避免和百度地图API冲突而改了个名字) http://www.oschina.net/code/snippet_87799_566 (这是我找到的地方,如果不是首发地址,请通知我进行修改,抱歉)

var map_poi_title = new TypeMap();
var poi_result = new result_st();
var arrayKeywords = ["餐厅","银行","商店"]; // 可以添加其他类型,最多支持10种

function result_st(){
    this.title = "";
    this.distance = "";
    this.duration = "";
}

function seven_box(){
    this.loc_x = 0;
    this.loc_y = 0;
    this.range = 500;

    this.set = function(_x, _y, _r){
        this.loc_x = _x;
        this.loc_y = _y;
        this.range = _r;
    }

    this.calc = function(OnCalcFinish){
        var point = new BMap.Point(this.loc_x, this.loc_y);
        var output = "";
        var callback_fun = function() { OnCalcFinish()};

        var searchComplete = function (results){
            if (walking.getStatus() != BMAP_STATUS_SUCCESS){
                return ;
            }

            var plan = results.getPlan(0);
            var map_key = results.getEnd().point.lng+":"+results.getEnd().point.lat;

            poi_result.title = map_poi_title.get(map_key);
            poi_result.distance = plan.getDistance(true);
            poi_result.duration = plan.getDuration(true);
            OnCalcFinish();
        };
        var walking = new BMap.WalkingRoute(point, {
            onSearchComplete: searchComplete
        });

        var searchCompleteNearby = function (results){
            var i=0;
            var j=0;
            var result_set = new Array();
            if (local.getStatus() != BMAP_STATUS_SUCCESS){
                return ;
            }
            for(j=0;j<arrayKeywords.length;j++){
                for(i=0;i < results[j].getCurrentNumPois();i++){ //getNumPois
                    resu = results[j].getPoi(i);
                    var map_key = resu.point.lng+":"+resu.point.lat;
                    map_poi_title.put(map_key, resu.title);
                    result_set.push(resu.point);
                }
            }
            var rnd_idx = Math.floor(Math.random()*result_set.length);
            walking.search(point, result_set[rnd_idx]);
        };
        var local = new BMap.LocalSearch(point, {
            onSearchComplete: searchCompleteNearby
        });
        local.searchNearby(arrayKeywords, point, this.range);
    }
    this.get = function(){
        return poi_result;
    }
}

使用的时候,大概是如下的样子:

<script type="text/javascript">
	var seven = new seven_box();
	var OnCalcFinish = function(){
	var output = seven.get().title + "(需要";
	    output += seven.get().duration + "";                //获取时间
	    output += "总路程为:" ;
	    output += seven.get().distance + "";             //获取距离
	    alert(output);
	}
	seven.set(116.404, 39.915, 500);// 经纬度、直径范围
	seven.calc(OnCalcFinish);
</script>

其实,整个设计来看的话,目前仅仅实现了任务目标的确立。 另外还有几件事情没有实现。 1、有七次机会。那么就需要一个数据库来进行存储和判断; 2、基于经纬度计算出方位的算法还没有去调查; 3、以及其他一些为了增加游戏难度而加入的模糊概念。比如实际地点名称的隐藏。

但是,由于前面提到的原因,这些不打算继续弄了。原因嘛,我懒得做界面……也没那个实力做的很好看。