【问题标题】:collision detection poor performance碰撞检测性能不佳
【发布时间】:2013-01-25 22:15:16
【问题描述】:

我正在使用 KineticJs 构建一个游戏,它使用拖放来移动屏幕上的元素,我遇到了很大的性能问题,因为我会检查 dragmove 事件,如果你拖动的元素与可能的捕捉位置发生碰撞,然后拖动元素变得迟钝。 我正在使用内置函数的 kineticJs,但我感觉它们没有得到很好的优化。它实际上在 chrome 中工作得相当不错(你可以看到滞后),但在 Firefox 中它并不好。 关于如何优化我的代码的任何想法

element.on('dragmove',function(evt){
    var position = stage.getUserPosition(evt);
    var snap = snapGroup.getIntersections(position.x,position.y);
    if(snap.length > 0) snapElement(snap[0]);
}

【问题讨论】:

  • 为什么不在gamedev.stackexchange.com上提问
  • 这个碰撞检测代码真的属于dragmove吗?为什么不dragstop
  • 它必须在 dragmove 事件上,因为我正在旋转拖动元素,因为它拖动到可能的放置位置

标签: javascript html html5-canvas kineticjs


【解决方案1】:

找到瓶颈。我猜是这条线:

var snap = snapGroup.getIntersections(position.x,position.y);

如果是这样,请设置一个计数器并仅每隔几个更新周期更新一次。确保在 dragend 上进行最终更新,以便最终获得正确的最终位置。

编辑:

也许这样的事情可能会起作用:

var dragUpdateCount = 0;
var dragUpdateRate = 5;
element.on('dragmove',function(evt){
    dragUpdateCount++;
    if (dragUpdateCount >= dragUpdateRate) {
        var position = stage.getUserPosition(evt);
        var snap = snapGroup.getIntersections(position.x,position.y);
        if (snap.length > 0) {
            snapElement(snap[0]);
        }
        dragUpdateCount = 0;
    }
}

【讨论】:

  • 这很有帮助,但我尝试每隔几个滴答才更新一次,但它没有用,我不知道是什么问题,你能写下你将如何实现它的代码吗?
【解决方案2】:

正如@Aram 指出的那样,瓶颈在于 .getIntersections() 函数。

.getIntersections() 函数占用大量内存/处理,因此您需要进行初步检查,将处理限制在某些位置。我制作的一个小游戏也遇到了类似的问题,.getIntersections() 的碰撞检测正在扼杀我的速度,我也尝试了 .intersects() 但它有类似的结果。我所做的是这样的:(不知道这是否适用于旋转)

 element.on('dragmove',function(){ //dont think you need the 'evt' passed here
     var position = stage.getUserPosition();
     var snapChildren = snapGroup.getChildren();  //get each snapGroup child
     for(var i=0; i<snapChildren.length; i++){
          if(position.x > snapChild[i].getX() && position.x < snapChild[i].getX()+snapChild[i].getWidth()){ // check horizontal bounding rectangle
                if(position.y > snapChild[i].getY() && position.y < snapChild[i].getY()+snapChild[i].getHeight(){ // check vertical bounding rectangle
                    var snap = snapGroup.getIntersections(position.x,position.y);
                    if(snap.length > 0) snapElement(snap[0]);
                }
           }
     }
 }

所以这是一种“边界矩形”碰撞检测方法,应该最大限度地减少您必须做的处理。

即使您正在获取所有子项并在 for 循环中处理它们,它仍然比 .getIntersections() 快

【讨论】:

  • 如果这不起作用,那么您只需按照相同的想法构建自己的函数,您需要先进行一些简单的检查,然后您可以执行 .getIntersections()
  • getIntersections() 性能将很快得到改善。敬请期待。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-05
  • 2019-04-30
相关资源
最近更新 更多