根据地理信息绘画的html5 小游戏 - 简单实现

很久没写文章了,以前一直有一个想法,就是作一个根据用户行走的路线,获取地理位置,而后把它们绘制出来,最后产生的效果,相似蜗牛行走留下的痕迹。html

最近思考了一下,搭了一个https,简单实现了一下,提供一下思路给你们看看,具体的细节还有不少须要完善。html5

demo:
图片描述nginx

demo页面地址: (不会泄露你的隐私,请用移动端访问,耐心等待位置获取)
https://www.yudonghan.com/snail/git

1.地理信息接口

要作这样一个东西首先要去了解html5提供了哪些地理信息接口,这些内容能够在MDN上找到:
主要是一个 Geolocation.watchPosition()Geolocation.getCurrentPosition()canvas

getCurrentPosition 是一次性的获取你的地理信息位置,watchPosition是监听地理信息位置的改变。浏览器

2.https

了解到接口之后,遇到的第一个问题是,发现普通的http协议因为隐私限制,已经取消了对上述两个接口的支持,解决方法是必须搭建https协议的服务器!
上网找到方法,我使用伪造的假证书搭建了nginx 的https服务,但问题是用户在访问的时候须要手动确认这个不安全的访问,不过这也正常,做为定位这样敏感的信息,确实是须要极高的安全性。安全

3.实现思路

我但愿能够过一段时间拿到一个定位,只有一个,因此我设置了一个时间周期的循环,并记录当前在哪一个循环内,若是这个周期内已经拿到过watch接口获得的位置,那么我就不作操做,若是没拿到过,我就给放到记录里,若是整个周期都没拿到,也不要紧,我就抛弃这个周期,去获取更精确的值。服务器

地理信息的返回,是带有一个accurancy的精度值,是以米为单位的,对地理信息的舍弃与否,主要取决于你指望的这个精确值。函数

关于绘制,这边就是用一个最基本的带有透明度的圆。在最开始,我会记录下第一次进来的位置信息(对应画布的粗略的中点),以后每次跟此次进行比对,算出差值,而后放大,映射到画布坐标,做为圆心,绘制到画布上。优化

直接看代码:

(function () {
    // 初始化画布
    var canvas
    var ctx
    var width = 500;
    var height = 500;
    function initCanvas() {
        canvas = document.getElementById("snail_canvas");
        canvas.width = width;
        canvas.height = height;
        ctx = canvas.getContext("2d");
    }
    // 绘制点方法
    function drawPoint(x, y, r) {
        ctx.fillStyle = "rgba(0, 0, 200, 0.1)";
        ctx.beginPath();
        ctx.arc(x, y, r, 0, 2 * Math.PI);
        ctx.fill();
    }

    // 地理信息位置参数
    var options = {
        enableHighAccuracy: true,
        desiredAccuracy: 20
    }
    // 一些记录用的变量
    var pathArr = {}
    var pathIndex = 0
    var watchID = navigator.geolocation.watchPosition(checkLocation, onError, options);
    var firstFlag = true
    var centerPos = {}
    var centerPoint = {}
    centerPoint.x = width / 2
    centerPoint.y = height / 2


    // 检查位置,每次地理信息变化都会通过这个函数
    function checkLocation(position) {
        // 精度小于指望值过滤
        if (position.coords.accuracy <= options.desiredAccuracy) {
            // 当前周期内只能记录一次地理坐标
            if (!pathArr[pathIndex]) {
                var offset
                pathArr[pathIndex] = position
                document.getElementById('container').innerHTML += 'render in period' + pathIndex + '<br>';
                // 获取地理坐标
                var geoX = position.coords.longitude
                var geoY = position.coords.latitude
                // 全局第一次坐标做为咱们画布的中点绘制
                if (firstFlag) {
                    offset = {
                        x: 0,
                        y: 0
                    }
                    centerPos = {
                        x: geoX,
                        y: geoY
                    }
                    firstFlag = false
                }
                else {
                    // 后来的坐标咱们算跟第一次坐标的差值记录
                    offset = {
                        x: geoX - centerPos.x,
                        y: geoY - centerPos.y
                    }
                }
                // 将差值传给点渲染方法
                renderPoint(offset)
            }            
        }
    }
    // 地理坐标放大倍数
    var mulTime = 100000
    function renderPoint(offset) {
        // 用画布中点叠加放大后的差值,并绘制该点
        var x = centerPoint.x + offset.x * mulTime 
        var y = centerPoint.y + offset.y * mulTime
        drawPoint(x, y, 5)
        document.getElementById('container').innerHTML += '**** : ' + offset.x + '+' + offset.y + '<br>';
    }



    function main() {
        initCanvas()
        // 设置一个循环来计算周期,每一个周期最多获取一次地理信息位置,最少0次
        setInterval(function () {
            pathIndex ++
        }, 2000)
    }

    // 页面加载和从新进入页面的时候都会运行main
    window.onload = main;
    window.focus = main;

    //失败时
    function onError(error){
        switch(error.code){
            case 1:
            alert("位置服务被拒绝");
            break;

            case 2:
            alert("暂时获取不到位置信息");
            break;

            case 3:
            alert("获取信息超时");
            break;

            case 4:
            alert("未知错误");
            break;
        }
    }
    
})()

4.问题

目前这套系统还存在不少问题,好比精度问题,常常产生绘制不许确的状况。

绘制上,更是不够细致,尤为是当你走出画布是没法记录的,当前的放大值过大,还很容易走出画布。该点后续能够优化。

最大问题:做为html5页面,你必须一直开启浏览器访问才能持续获取定位,不能黑屏,不能暂存浏览器,致使这个页面很是不实用!

进化:目前是透明圆点的绘制方法,能够改用折现等其余方式。圆点能够自定义颜色,大小,成为真正的步行绘制系统。能够自定义放大倍数,根据用户的速度,改变不一样的放大。

相关文章
相关标签/搜索