1

我一直在玩 JavaScript/JQuery,并决定创建一个小程序,让球在矩形边界区域周围弹跳。我相信我的代码逻辑应该是有意义的,但由于某种原因,我无法让它改变方向。更奇怪的是,我将球的 x 和 y 位置作为文本放在上面,但它似乎是静态卡住的(它不会改变),但是当我检查它留下的元素时,我看到顶部的 css 参数正在改变时间。

这是代码:

    <!DOCTYPE html>
<html>
    <head>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js">
        </script>
        <style>
            .ball {
                width: 50px;
                height: 50px;
                background: red;
                -moz-border-radius: 50px;
                -webkit-border-radius: 50px;
                border-radius: 50px;
                position: absolute;
            }
            .boundary {
                width: 700px;
                height: 500px;
                background: #AAAAAA;
                border-style:solid;
                border-width:5px;
                position: absolute;
            }
        </style>
        <script>
            $(document).ready(function(){
                var b = new ball(1, 1, 10, 10);
                for(i = 0; i < 1000; i++)
                    b.moveBall();
            });

            function ball(xPos, yPos, xVel, yVel)
            {
                this.xPos = xPos;
                this.yPos = yPos;
                this.xVel = xVel;
                this.yVel = yVel;
                this.rightBound = false
                this.leftBound = false;
                this.upBound = false;
                this.downBound = false;
                this.width = 50;
                this.height = 50;


                this.moveBall = moveBall;
                function moveBall()
                {
                    var h = 500;
                    var w = 700;

                    //detect if it is at x bounds
                    if(this.xPos + this.width + this.xVel > w)
                        {this.rightBound = true;}
                    else if(this.xPos + this.xVel < -1)
                        this.leftBound = true;
                    else
                    {
                        this.rightBound = false;
                        this.leftBound = false;
                    }

                    //detect if it is at y bounds
                    if(this.yPos + this.height + this.yVel > h)
                        {this.downBound = true;}
                    else if(this.yPos + this.yVel < -1)
                        this.upBound = true;
                    else
                    {
                        this.upBound = false;
                        this.downBound = false;
                    }

                    //handle velocity changes for bounds
                    //so you switch the x direction if x bound is met, same for y
                    if(this.rightBound || this.leftBound)
                        this.xVel *= -1;
                    if(this.upBound || this.downBound)
                        this.yVel *= -1;

                    //now give motion               
                    this.xPos += xVel;
                    this.yPos += yVel;

                    //now draw  
                    $(".ball").animate({
                        left:this.xPos + 'px',
                        top:this.yPos + 'px'
                        }, 150).text(this.xPos + "," + this.yPos);  
                }
            }
        </script>
    </head>

    <body>
        <div class="boundary">
            <div class="ball"></div>
        </div>
    </body>
</html>

奇怪的是,它似乎从一开始就自动将最终值 10,001、10,001(假设它从不改变方向)作为 (x,y) 坐标。任何可以为我指明正确方向的东西都将不胜感激!对不起,如果这是一些基本错误,我试图确保它不是但有时他们会漏掉!

4

2 回答 2

2

你是ball.moveBall在循环中做你的,而不是在计时器上。所以它会尽可能快地进行计算。是的,可计算不是一个词。继续。

通过调用$.animate您是说您希望 jQuery 处理将对象从一个位置移动到另一个位置。jQuery 的运行方式比计算机慢。等等,这变得越来越混乱。让我简单地说。

你循环了ball.moveBall1000 次。这需要多长时间?几乎没有时间。这就是为什么坐标一直停留在 1000 的原因。它实际上超级超级超级快。如此之快,它基本上在 jQuery 有时间开始移动球之前就到达了那里。然后......然后球开始移动。为什么?为什么它实际上没有立即移动到位置 1000,1000?好吧,坐标确实达到了 1000,1000。但是 jQuery 就像,“哦,好吧,将球移动到位置 1000,1000。我可以做到!真的很慢......”。您可能已经厌倦了听到解释,所以这里是修复:

更改$(".ball").animate$(".ball").css。并将您的循环更改为window.setInterval(function(){b.moveBall()},1000)或类似的东西。我在这里为你设置了一个小提琴:http: //jsfiddle.net/uXbwR/

你会注意到它移动得很慢。那是因为我将间隔设置为 1000 毫秒,这意味着它每秒只移动一次。对于一场比赛,你会想要 1000/60(每 60 秒一次),但我试过了,它让球移动得非常快。你的球的速度真的很高。你可能想试着把它调低一点。

这就是我所拥有的。

编辑

计算上。这就是我要找的词。

于 2013-07-01T19:28:13.497 回答
1

只有在前面完成后,您才应该调用动画的下一步。您告诉 animate 需要 150 毫秒,但 while 循环几乎立即完成,无需等待每一步。

[编辑]

@Samuel 的回答很完整,并且已经为您建议了一个很好的解决方法。我想这将超出您的应用程序的目的,但如果您有兴趣设置一个适当的 Javascript 游戏主循环,这些是一些有用的资源,然后是我的实现:

Fabien Sanglard,游戏计时器:问题和解决方案

Paul Irish,requestAnimationFrame 用于智能动画

var RENDERING_FRAME_TIME = 1000/60; // ms
var PHYSICS_FRAME_TIME = 5;         // ms

var currentTime = new Date().getTime();
var accumulator = 0;

(function mainloop(){
    newTime = new Date().getTime();
    accumulator = newTime - currentTime;
    currentTime = newTime;
    while (accumulator > PHYSICS_FRAME_TIME) {
        integrate(PHYSICS_FRAME_TIME);
        accumulator -= PHYSICS_FRAME_TIME;
    }
    requestAnimationFrame(mainloop);
    render();
})();
于 2013-07-01T19:27:36.833 回答