Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
511 views
in Technique[技术] by (71.8m points)

移动web端做重力感应小游戏,实现效果差,有卡顿,应该怎么解决?有相关插件可以用么?

做移动web端重力感应小游戏,要求页面中对象boss根据手机的倾斜改变位置。使用了h5里的重力监听器写了一段js代码,设备物理方向信息可以被监听到,对象也可以根据倾斜方向移动位置。问题是移动不流畅,反应不灵敏,对象无法随着设备倾斜方向立刻做出移动方向上的改变。
以下是我的js代码:
监听设备物理方向的计时器(我需要每隔几秒更新一下设备倾斜角度信息的变化,同时后面有关闭重力监听的需求,所以用了计时器)

t = setInterval(function() {
                window.addEventListener("deviceorientation",gravity, true);
            },30);

对象根据倾斜方向移动位置的代码:

 function gravity(event) {
        var beta = Math.ceil(event.beta);
        var gamma = Math.ceil(event.gamma);
        var beta_a = Math.abs(beta);
        var gamma_a = Math.abs(gamma);
        var speed;

        //if(((0 <= beta_a)&&(beta_a <= 15))||((0 <= gamma_a)&&(gamma_a <= 15))){
        //    speed = 350;
        //}else if(((15 < beta_a)&&(beta_a <= 30))||((15 < gamma_a)&&(gamma_a <= 30))){
        //    speed = 300;
        //}else if(((30 < beta_a)&&(beta_a <= 90))||((30 < gamma_a)&&(gamma_a <= 90))){
        //    speed = 250;
        //}

        if ((-90 <= beta) && ( beta < 0)) {
            hide_hint();
            //脸上移
            if (boss.offsetTop > -(w_width * 0.75 * 0.5)) {
                if ((0 <= gamma) && (gamma <= 90)) {
                    // 脸右移
                    if (boss.offsetLeft < w_width - w_width * 0.75 * 0.5) {
                        $("#boss").stop(true);
                       $("#boss").animate({bottom:"124vw",right:"-37vw"},300);
                        
                    } else {
                        $("#boss").stop(true);
                        $("#boss").animate({bottom:"124vw"},250);
                        $("#boss").css("rignt","-37vw");
                    
                    }
                } else if ((-90 <= gamma) && (gamma < 0)) {
                    //脸左移
                    if (-(w_width * 0.75 * 0.5) < boss.offsetLeft) {
                        $("#boss").stop(true);
                        $("#boss").animate({right:"62vw"},250);
                        $("#boss").css("bottom","124");
                      
                    } else {
                        $("#boss").stop(true);
                        $("#boss").animate({bottom:"124vw"},250);
                        $("#boss").css("right","62vw");
                        
                    }
                }
            } else {
                if ((0 <= gamma) && (gamma <= 90)) {
                    // 脸右移
                    if (boss.offsetLeft < w_width - w_width * 0.75 * 0.5) {
                        $("#boss").stop(true);
                        $("#boss").animate({right:"-37vw"},250);
                        $("#boss").css("bottom","124vw");
                      
                    } else {
                        $("#boss").stop(true);
                        $("#boss").css("bottom","124vw");
                        $("#boss").css("rignt","-37vw");
                        
                    }
                } else if ((-90 <= gamma) && (gamma < 0)) {
                    //脸左移
                    if (-(w_width * 0.75 * 0.5) < boss.offsetLeft) {
                        $("#boss").stop(true);
                        $("#boss").animate({right:"62vw"},250);
                        $("#boss").css("bottom","124vw");
                      
                    } else {
                        $("#boss").stop(true);
                        $("#boss").css("bottom","124vw");
                        $("#boss").css("right","62vw");
                        
                    }
                }
            }
        } else if ((0 <= beta) && (beta <= 90)) {
            hide_hint();
            //脸下移
            if (boss.offsetTop < (w_height - w_width * 0.75 * 0.5)) {
                if ((0 <= gamma) && (gamma <= 90)) {
                    // 脸右移
                    if (boss.offsetLeft < w_width - w_width * 0.75 * 0.5) {
                        $("#boss").stop(true);
                       $("#boss").animate({bottom:"-37vw",right:"-37vw"},300);
                        
                    } else {
                        $("#boss").stop(true);
                        $("#boss").animate({bottom:"-37vw"},250);
                        $("#boss").css("rignt","-37vw");
                        
                    }
                } else if ((-90 <= gamma) && (gamma < 0)) {
                    //脸左移
                    if (-(w_width * 0.75 * 0.5) < boss.offsetLeft) {
                        $("#boss").stop(true);
                        //$("#boss").animate({bottom:"-37vw"},200);
                        //$("#boss").animate({right:"62vw"},200);
                        $("#boss").animate({bottom:"-37vw",right:"62vw"},300);
                        
                    } else {
                        $("#boss").stop(true);
                        $("#boss").animate({bottom:"-37vw"},250);
                        $("#boss").css("right","62vw");
                        
                    }
                }
            } else {
                if ((0 <= gamma) && (gamma <= 90)) {
                    // 脸右移
                    if (boss.offsetLeft < w_width - w_width * 0.75 * 0.5) {
                        $("#boss").stop(true);
                        $("#boss").animate({right:"-37vw"},250);
                        $("#boss").css("bottom","-37");
                        
                    } else {
                        $("#boss").stop(true);
                        $("#boss").css("bottom","-37");
                        $("#boss").css("rignt","-37vw");
                        
                    }
                } else if ((-90 <= gamma) && (gamma < 0)) {
                    //脸左移
                    if (-(w_width * 0.75 * 0.5) < boss.offsetLeft) {
                        $("#boss").stop(true);
                        $("#boss").animate({right:"62vw"},250);
                        $("#boss").css("bottom","-37");
                       
                    } else {
                        $("#boss").stop(true);
                        $("#boss").css("right","62vw");
                        $("#boss").css("bottom","-37");
                       
                    }
                }
            }
        }
    }

开头注释的部分本来是想做根据倾斜角度的不同对象移动速度也不同的,但是效果不好而且本身在无速度变化的时候就有反应不灵敏的问题,所以希望可以先解决精准移动反应无延迟的问题。
最后,自己手写的原生js还是粗糙的,如果有不好的编码习惯,麻烦大家指教,代码逻辑方面如果有问题,也请大家指出。要是有有知道有好用的相关的重力感应插件可以用的话,也拜托请提供一下相关信息。谢谢~!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

问题已解决,回来整理一下。之前的代码实现对象移动的方法是animate方法,经过物理设备倾斜方向的判断确定需移动对象的移动方向并使其在一定时间内移动至某一点,原本代码片段如下:

 if ((0 <= gamma) && (gamma <= 90)) {
                    // 脸右移
                    if (boss.offsetLeft < w_width - w_width * 0.75 * 0.5) {
                        $("#boss").stop(true);
                        $("#boss").animate({right:"-37vw"},250);
                        $("#boss").css("bottom","124vw");
                      
                    } else {
                        $("#boss").stop(true);
                        $("#boss").css("bottom","124vw");
                        $("#boss").css("rignt","-37vw");
                        
                    }
                } else if ((-90 <= gamma) && (gamma < 0)) {
                    //脸左移
                    if (-(w_width * 0.75 * 0.5) < boss.offsetLeft) {
                        $("#boss").stop(true);
                        $("#boss").animate({right:"62vw"},250);
                        $("#boss").css("bottom","124vw");
                      
                    } else {
                        $("#boss").stop(true);
                        $("#boss").css("bottom","124vw");
                        $("#boss").css("right","62vw");
                        
                    }
                }

在animate方法中若确定了移动的目的地以及移至那点的时间后,对象移动的速度便成了变值,因为在该方法中对象在距离移动目的地的距离不同却须在相同时间结束运动。这是导致移动对象运动卡顿不好控制关键所在。
解决方案是,使速度成为定值,即使移动距离成为变值。修改后代码如下:
重力感应监听部分:

 //重力感应
            //监听设备物理方向信息
            var timeout = false;
            ttt();
            function ttt(){
                if(timeout) {
                    return;
                }else {
                    window.addEventListener("deviceorientation", gravity, true);
                }
                setTimeout(ttt,1);
            }

不同物理设备倾斜方向的移动方案:

function change_bottom(beta,gamma,speed_1){
        //alert(speed_1+"a");
        right_go = parseFloat($("#boss").css("right"));
        if ((-180 <= beta) && ( beta < 0)){
            bottom_go = parseFloat($("#boss").css("bottom")) + speed_1;
            if(bottom_go >= 121*prop){
                bottom_go = 121*prop;
            }
        }else if((0 <= beta) && (beta <= 180)){
            bottom_go = parseFloat($("#boss").css("bottom")) - speed_1;
            if(bottom_go <=(-37*prop)){
                bottom_go = -37*prop;
            }
        }
        $("#boss").animate({bottom: bottom_go+"px",right: right_go+"px"},1,function(){
            //change_bottom();
        });
    }

    function change_right(beta,gamma,speed_2){
        //alert(speed_2+"b");
        bottom_go = parseFloat($("#boss").css("bottom"));
        if ((0 <= gamma) && (gamma <= 180)){
            right_go = parseFloat($("#boss").css("right")) - speed_2;
            if(right_go <= (-37*prop)){
                right_go = -37*prop;
            }
        }else if((-180 <= gamma) && (gamma < 0)){
            right_go = parseFloat($("#boss").css("right")) + speed_2;
            if(right_go >= 62*prop){
                right_go = 62*prop;
            }
        }
        $("#boss").animate({right: right_go+"px",bottom: bottom_go+"px"},1,function(){
            //change_right();
        });
    }

    function all_change(beta,gamma,speed_1,speed_2){
        //alert(speed_1+"c");
        //alert(speed_2+"d");
        if ((-180 <= beta) && ( beta < 0)){
            bottom_go = parseFloat($("#boss").css("bottom")) + speed_1;
            if(bottom_go >= 121*prop){
                bottom_go = 121*prop;
            }
        }else if((0 <= beta) && (beta <= 180)){
            bottom_go = parseFloat($("#boss").css("bottom")) - speed_1;
            if(bottom_go <= (-37*prop)){
                bottom_go = -37*prop;
            }
        }
        if ((0 <= gamma) && (gamma <= 180)){
            right_go = parseFloat($("#boss").css("right")) - speed_2;
            if(right_go <= (-37*prop)){
                right_go = -37*prop;
            }
        }else if((-180 <= gamma) && (gamma < 0)){
            right_go = parseFloat($("#boss").css("right")) + speed_2;
            if(right_go >= 62*prop){
                right_go = 62*prop;
            }
        }
        $("#boss").animate({right: right_go+"px",bottom: bottom_go+"px"},1,function(){
            //all_change();
        });
    }

最后也实现了根据物理设备倾斜角度的不同对象移动速度改变的效果,代码如下:

 function gravity(event) {
        var beta = Math.ceil(event.beta);
        var gamma = Math.ceil(event.gamma);
        var beta_a = Math.abs(beta);
        var gamma_a = Math.abs(gamma);
        var speed_1;
        var speed_2;

        hide_hint();

        if((0 <= beta_a)&&(beta_a <= 10)){
            speed_1 = 2;
        }else if((10 < beta_a)&&(beta_a <= 20)){
            speed_1 = 5;
        }else if((20 < beta_a)&&(beta_a <= 30)){
            speed_1 = 6;
        }else if((30 < beta_a)&&(beta_a <= 40)){
            speed_1 = 8;
        }else if((40 < beta_a)&&(beta_a <= 50)){
            speed_1 = 10;
        }else if((50 < beta_a)&&(beta_a <= 60)){
            speed_1 = 15;
        }else if((60 < beta_a)&&(beta_a <= 70)){
            speed_1 = 20;
        }else if((70 < beta_a)&&(beta_a <= 80)){
            speed_1 = 45;
        }else if((80 < beta_a)&&(beta_a <= 180)){
            speed_1 = 50;
        }

        if((0 <= gamma_a)&&(gamma_a <= 10)){
            speed_2 = 2;
        }else if((10 < gamma_a)&&(gamma_a <= 20)){
            speed_2 = 5;
        }else if((20 < gamma_a)&&(gamma_a <= 30)){
            speed_2 = 6;
        }else if((30 < gamma_a)&&(gamma_a <= 40)){
            speed_2 = 8;
        }else if((40 < gamma_a)&&(gamma_a <= 50)){
            speed_2 = 10;
        }else if((50 < gamma_a)&&(gamma_a <= 60)){
            speed_2 = 15;
        }else if((60 < gamma_a)&&(gamma_a <= 70)){
            speed_2 = 20;
        }else if((70 < gamma_a)&&(gamma_a <= 80)){
            speed_2 = 45;
        }else if((80 < gamma_a)&&(gamma_a <= 180)){
            speed_2 = 50;
        }



        if((beta == 0) && (gamma != 0)){
            change_right(beta,gamma,speed_2);
        }else if((beta != 0) && (gamma == 0)){
            change_bottom(beta,gamma,speed_1);
        }else if((beta != 0) && (gamma != 0)){
            all_change(beta,gamma,speed_1,speed_2);
        }
    }

还有一点就是,为了使物理设备倾斜变化对象移动情况也立即发生变化无延迟,需要使animate方法中给定的时间值等于监听设备物理方向信息间隔时间相同。


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...