【问题标题】:Circle bounce bug圆圈弹跳错误
【发布时间】:2014-03-13 15:46:48
【问题描述】:

我正在使用没有画布(!)的 HTML5 和 jQuery 创建一个小游戏,并且在开发弹跳部分(当圆圈与阶段限制发生碰撞时)时,我发现了一个错误:

当圆圈与底部或右侧界限发生碰撞并且您按住向下/向右箭头键时,圆圈会继续在阶段界限处弹跳,但是当您对相反阶段界限(顶部和左侧)执行相同操作时,圆圈反弹一两次,然后停止(我想得到第二个反应,当它反弹然后停止)。 我还发现这个错误只发生在 Safari 中。有人可以帮我解决它吗?

JSFiddle

Demo on site

<!DOCTYPE html>
<html>

<head>
    <title>VelJS 3 Pre-Alpha</title>

    <!-- This app was coded by Tiago Marinho -->
    <!-- Special thanks to Drizr, from the interwebs -->
    <!-- Do not leech it! -->

    <link rel="shortcut icon" href="http://i.imgur.com/Jja8mvg.png">
    <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
    <script>
    var yvel = 0, xvel = 0;
    var up = false, // W or arrow up
            left = false, // A or arrow left
            right = false, // D or arrow right
            down = false; // S or arrow down

            // Keydown:
            document.addEventListener("keydown", function (evt) {
                if (evt.keyCode == 87 || evt.keyCode == 38) { // up
                    up = true;
                }
                if (evt.keyCode == 65 || evt.keyCode == 37) { // left
                    left = true;
                }
                if (evt.keyCode == 68 || evt.keyCode == 39) { // right
                    right = true;
                }
                if (evt.keyCode == 83 || evt.keyCode == 40) { // down
                    down = true;
                }
                if (evt.keyCode == 8 || evt.keyCode == 80) { // del/p
                }
            });
            // Keyup:
            document.addEventListener("keyup", function (evt) {
                if (evt.keyCode == 87 || evt.keyCode == 38) { // up
                    up = false;
                }
                if (evt.keyCode == 65 || evt.keyCode == 37) { // left
                    left = false;
                }
                if (evt.keyCode == 68 || evt.keyCode == 39) { // right
                    right = false;
                }
                if (evt.keyCode == 83 || evt.keyCode == 40) { // down
                    down = false;
                }
            });

            function y(obj){
                return $(obj).offset().top;
            }
            function x(obj){
                return $(obj).offset().left;
            }

            setInterval(function(){

                // Keydown/keyup handler:
                if (up == true) {
                    yvel -= 2;
                } else {
                    if (yvel < 0) {
                        yvel++;
                    }
                }
                if (left == true) {
                    xvel -= 2;
                } else {
                    if (xvel < 0) {
                        xvel++;
                    }
                }
                if (right == true) {
                    xvel += 2;
                } else {
                    if (xvel > 0) {
                        xvel--;
                    }
                }
                if (down == true) {
                    yvel += 2;
                } else {
                    if (yvel > 0) {
                        yvel--;
                    }
                }

                var nextposx = $("circle").offset().left+xvel/16;
                var nextposy = $("circle").offset().top+yvel/16;

                if(nextposy < 0 || nextposy+20 > window.innerHeight){
                    yvel = Math.round(yvel*-0.5);
                }
                if(nextposx < 0 || nextposx+20 > window.innerWidth){
                    console.log(xvel);
                    xvel = Math.round(xvel*-0.5);
                    console.log(xvel);
                }
                $("circle").css({
                    top:$("circle").offset().top+yvel/16,
                    left:$("circle").offset().left+xvel/16
                });
            },8);
    </script>
    <style>
        <link href='http://fonts.googleapis.com/css?family=Open+Sans:400,700,600' rel='stylesheet' type='text/css'> * {
            margin: 0;
        }
        html,
        body {
            -webkit-text-smoothing: antialiased;
            height:100%;
            overflow:hidden;
            color: #fff;
            background-color: #181818;
        }
        circle{
            position:absolute;

            top:0;
            left:0;

            width:20px;
            height:20px;

            border-radius:10px;
            background:#fff;
        }
        </style>
</head>

<body>
    <circle></circle>
</body>

</html>

我没有使用画布,因为我已经尝试使用 EaselJS 创建这个小游戏,但是我发现了很多问题,没有理由在我的案例中使用它,因为这个游戏没有任何图像(然后不需要硬件加速)。

【问题讨论】:

  • 这真是个笨蛋。你打算采取哪种行为?无限弹跳?
  • 不,我正在寻找它在弹跳后停止的时间。 (问题是当它无限弹跳时)。

标签: javascript jquery css html safari


【解决方案1】:

此答案是对先前无效答案的完整更新。 答案的完整代码在底部。

我必须检查所有浏览器以查看问题所在:

-在 Chrome 上一切正常,所以我没有什么可改变的。

-在 Safari 上,球在底部和右侧弹跳。我发现问题是由设置在 float 而不是 int 中的位置引起的,所以我只需要对位移进行四舍五入。

$("circle").css({
top:Math.round($("circle").offset().top+yvel/16),
left:Math.round($("circle").offset().left+xvel/16)
});

我的第一个答案是通过在位移中作弊来解决问题,这次的答案是解决它。这种改进应该不会影响 Chrome(但我现在无法对其进行测试)。

-在 Firefox 上,球在页面底部之前停止。我只需要更改身体碰撞的比较器并添加margin0px 到它。 在旧版本的 Firefox 中,当您按下 UP 时,球在向上前会稍微向下,我他的这个错误是由于 xvel--xvel++yvel--yvel++ 比 @987654329 快@、xvel-=2yvel+=2yvel-=2 所以我用两次++xvel、两次--xvel、两次++yvel 和两次--yvel 替换它们,这应该更快(再次我可以'现在测试它,所以我希望这有效)。这些改进不会影响 Chrome 和 Safari。

然后我优化您的代码以使其更高效。

您的 HTML 没有改变。

你的 CSS 现在是:

<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,700,600' rel='stylesheet' type='text/css'> * {
            margin: 0;
        }

        html, body {
            -webkit-text-smoothing: antialiased;
        height:100%;
        overflow:hidden;
            color: #fff;
            background-color: #181818;
            margin: 0px;
        }

    circle {
        position:absolute;  
        top:0;
        left:0;
        width:20px;
        height:20px;
        border-radius:10px;
        background:#fff;
    }

你的 JavaScript 现在是:

var yvel = 0, xvel = 0;
    var up = false, // W or arrow up
            left = false, // A or arrow left
            right = false, // D or arrow right
            down = false; // S or arrow down

            // Keydown:
            document.addEventListener("keydown", function (evt) {
                if (evt.keyCode == 87 || evt.keyCode == 38) { // up
                    up = true;
                }
                if (evt.keyCode == 65 || evt.keyCode == 37) { // left
                    left = true;
                }
                if (evt.keyCode == 68 || evt.keyCode == 39) { // right
                    right = true;
                }
                if (evt.keyCode == 83 || evt.keyCode == 40) { // down
                    down = true;
                }
                if (evt.keyCode == 8 || evt.keyCode == 80) { // del/p
                }
            });
            // Keyup:
            document.addEventListener("keyup", function (evt) {
                if (evt.keyCode == 87 || evt.keyCode == 38) { // up
                    up = false;
                }
                if (evt.keyCode == 65 || evt.keyCode == 37) { // left
                    left = false;
                }
                if (evt.keyCode == 68 || evt.keyCode == 39) { // right
                    right = false;
                }
                if (evt.keyCode == 83 || evt.keyCode == 40) { // down
                    down = false;
                }
            });

            function y(obj){
                return $(obj).offset().top;
            }
            function x(obj){
                return $(obj).offset().left;
            }

            setInterval(function(){

                // Keydown/keyup handler:
                if (up) {
                    --yvel;
                    --yvel;
                } else if (yvel < 0) {
                        yvel++;
                }
                if (left) {
                    --xvel;
                    --xvel;
                } else if (xvel < 0) {
                        xvel++;
                }
                if (right) {
                    ++xvel;
                    ++xvel;
                } else if (xvel > 0) {
                        xvel--;
                }
                if (down) {
                    ++yvel;
                    ++yvel;
                } else if (yvel > 0) {
                    yvel--;
                }

                var nextposx = $("circle").offset().left+xvel/16;
                var nextposy = $("circle").offset().top+yvel/16;

                if(nextposy < 0 || nextposy+20 > $('body').height()){
                    yvel = Math.round(yvel*-0.5);
                }
                if(nextposx < 0 || nextposx+20 > $('body').width()){
                    xvel = Math.round(xvel*-0.5);
                }
                $('circle').css({
                    top:Math.round($('circle').offset().top+yvel/16),
                    left:Math.round($('circle').offset().left+xvel/16)
                });
            },8);

你有一个结果的 JSFiddle here

剩下的唯一错误是,在 Firefox 中,圆圈在右侧超出了几个像素,但非常小。

对不起,如果我的英语不好,我希望你能得到我所写的一切。 我想我在这里的工作已经完成了...... 玩得开心 =D。

【讨论】:

  • 非常感谢!在 Safari 7 中工作得像一个魅力,但现在 Chrome 中有一个错误。如果圆圈在右或底部阶段限制处跳动,并且您继续按右/下,则圆圈会慢慢通过它。
  • 对不起,我错了,我只是在 Firefox 上尝试了这段代码,但它完全坏了...所以你可以保留你的第一个版本,我稍后会检查解决方案,但我不能这样做暂时。
  • 没问题。我正在制作这个小游戏的画布版本,而这个问题还没有解决,但如果你以后能帮助我,我将非常感激。
  • 对不起,我忙于一个大项目......我更新了我的整个答案,希望这会对你有所帮助。祝你有美好的一天!
猜你喜欢
  • 1970-01-01
  • 2022-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多