代码之家  ›  专栏  ›  技术社区  ›  darkf

当接近目标时,朝向某个方向的运动会发生振荡

  •  0
  • darkf  · 技术社区  · 12 年前

    我有一个非常简单的动画: http://jsfiddle.net/k5uf9bm5/

    我有一个矩形(玩家),当我点击文档某处时,玩家会向目标位置移动。

    问题是它不能完全到达它——它无休止地来回振荡。

    这对我来说很奇怪,因为它总是在其他语言中工作,事实上类似于其他游戏使用的实现。什么可以 可能地 这个问题是不是在逃避我?

    为了完成问题,下面是代码:

    <html>
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    <script>
    var pos = {x: 0, y: 0}
    var target = null
    var $player = $("#player")
    
    $(document).click(function(e) { target = {x: e.pageX, y: e.pageY} })
    
    function update() {
        $player.css({left: pos.x + 'px', top: pos.y + 'px'})
    
        if(target) {
            var dx = target.x - pos.x
            var dy = target.y - pos.y
            var len = Math.sqrt(dx*dx + dy*dy)
            dx /= len
            dy /= len
    
            /*var theta = Math.atan2(target.y - pos.y, target.x - pos.x)
            var dx = Math.cos(theta)
            var dy = Math.sin(theta)*/
    
            pos.x += dx
            pos.y += dy
        }
    
        setTimeout(update, 25)
    }
    
    update()
    </script>
    <style>
    #player {
      position: absolute;
      width: 15; height: 15;
      background-color: black;
    }
    </style>
    <body>
    <body>
      <div id="player">x</div>
    </body>
    </html>
    
    2 回复  |  直到 12 年前
        1
  •  2
  •   odedsh    12 年前

    你似乎缺少休息条件。 len 包含到目标的距离。

     var len = Math.sqrt(dx*dx + dy*dy) 
    

    在你的代码中,你总是以单位向量向目标移动。。现在假设到目标的距离是3.5个单位。。然后你将永远围绕目标振荡。 在第4步,您将超出0.5。然后在第5步,永远低于0.5,依此类推。。

    你应该确保如果 len <1 然后不要除以它,只是让pos等于目标位置,然后停止调用update。

    如果len==0,这也将解决可能被零除的问题

        2
  •  1
  •   Community Mohan Dere    9 年前

    这让我想起了前段时间我给出的一个答案。
    看看我的 answer :).

    问题是关于角度,但如果你看他的小提琴,你会发现他的跟踪也在振荡。
    在我的Fiddle中,它不会(嗯,它也会加速和减速,我认为它的转弯更好……)。

    更具体地说,我有这样的想法:

    // time to decelerate
    if (distance <nextDecleration ){
       nextDecleration = decelerate(distance);
     }
    // within 10 px, do nothing
    else if (distance -10 < nextDecleration)       { 
      // do nothing
    }
    // bigger than 10, accelerate
    else {
      nextDecleration = accelerate(distance);
    }
    

    这就意味着:如果你在这一点的向量中,那就足够了。停在那里。