【问题标题】:collision testing with multiple objects on stage舞台上多个物体的碰撞测试
【发布时间】:2011-11-27 19:07:35
【问题描述】:

我正在尝试创建一种树状图,这样,如果您单击其中一个圆圈,它的子圆圈会以一定程度的随机性从原始圆圈向外扩展,并由线条连接。我有这个工作,但现在我想做的是确保没有一个圆圈相互碰撞,也没有一条线纵横交错。您可以看到当前正在发生的事情的屏幕截图。我的代码如下。如何更改此代码以检查冲突并避免它们?我已经阅读了 flash 的 hitTestObject 命令,但这只适用于一个对象到另一个对象的上下文。我想测试一个接触任何显示对象的对象。

import com.greensock.TweenMax;

var sw = stage.stageWidth;
var sh = stage.stageHeight;
var cr = 3; //circle radius
var moveRange = 25;
var circleColor = 0xcccccc;
var numCircles = 4;
var lineCanvas:Sprite = new Sprite();
addChild(lineCanvas);
var lineColor = 0xe9e9e9;
var lineWeight = 1;

function init(){
    firstCircle();
}

function firstCircle(){
    var xPos = randomRange(cr, sw-cr);
    var yPos = randomRange(cr, sh-cr);
    var newCircle:Shape = new Shape();
    newCircle.graphics.beginFill(circleColor);
    newCircle.graphics.drawCircle(0,0,cr);
    newCircle.graphics.endFill();

    var circleClip:MovieClip = new MovieClip();
    circleClip.childCircles = 2;
    circleClip.x = xPos;
    circleClip.y = yPos;
    circleClip.addChild(newCircle);

    addChild(circleClip);
    circleClip.addEventListener(MouseEvent.CLICK,clickCircle);
}

function clickCircle(e:MouseEvent):void {
    var thisCircle = e.target;
    for (var i=0; i<thisCircle.childCircles;i++){
        drawCircle(thisCircle);
    }
}

function drawCircle(parentCircle){
    var xPos = parentCircle.x;
    var yPos = parentCircle.y
    //var xPos = randomRange(cr, sw-cr);
    //var yPos = randomRange(cr, sh-cr);
    var newCircle:Shape = new Shape();
    newCircle.graphics.beginFill(circleColor);
    newCircle.graphics.drawCircle(0,0,cr);
    newCircle.graphics.endFill();

    var circleClip:MovieClip = new MovieClip();
    circleClip.childCircles = 2;
    circleClip.x = xPos;
    circleClip.y = yPos;
    circleClip.addChild(newCircle);
    addChild(circleClip);
    circleClip.addEventListener(MouseEvent.CLICK,clickCircle);
    moveCircle(circleClip,xPos,yPos);
}

function drawLine(childCircle,parentX,parentY){
        lineCanvas.graphics.lineStyle(lineWeight,lineColor);
        lineCanvas.graphics.moveTo(parentX,parentY);
        lineCanvas.graphics.lineTo(childCircle.x,childCircle.y);

//想检查线或圆圈是否在这里接触到任何东西。如果是,我想杀死圆的补间(因此也停止画线)。

}

function moveCircle(childCircle,parentX,parentY){
    var curX = childCircle.x;
    var curY = childCircle.y;
    var moveX = randomRange(curX-moveRange,curX+moveRange);
    var moveY = randomRange(curY-moveRange-cr,curY+moveRange+cr);
    TweenMax.to(childCircle,.5, { x: moveX, y: moveY, onUpdate:drawLine, onUpdateParams:[childCircle,parentX,parentY]});
}

function randomRange(minNum:Number, maxNum:Number):Number {  
    return (Math.floor(Math.random() * (maxNum - minNum + 1)) + minNum);  
}

init();

【问题讨论】:

    标签: flash actionscript-3 collision-detection collision hittest


    【解决方案1】:

    有两种方法可以做到这一点:

    1. 重构您的代码以使用 Actionscript 物理库(即 Box2D 或您喜欢的任何一个)。然后,将您的“圆”和“线”视为将相互碰撞的物理对象,可能与您在这里尝试做的效果相同。对此的 PRO 是该库带有各种扩展类来处理物理交互。 CON 是实施中的开销。
    2. 执行此操作的手动/自定义方法是在舞台或初始圆圈上为 ENTER_FRAME 添加一个事件侦听器,它将循环遍历其子级,并在每个“子级”圆圈上调用 hitTestObject 方法,并与其他圆圈进行比较“孩子”圈子。线条在子圈内,所以应该没问题。

    我注意到您实际上并没有将 childCircles 添加到初始圆圈,而是将它们添加到舞台。您可能希望将这些圆圈推入一个数组中,以便稍后为这个“collisionDetection”方法引用。

    【讨论】:

      【解决方案2】:

      从根本上说,您需要维护屏幕上所有圆圈的列表,然后每次移动(或每一帧)时,您都需要检查移动的圆圈与所有其他圆圈是否一致碰撞。

      Array 应该可以很好地跟踪所有圈子。

      然后,每次有东西移动时,只要它在移动,你就应该遍历数组并检查它是否碰到了任何其他圆圈。使用类似的东西:

      function drawLine (...) 
      {
      
          // Your code here
      
          for (var i:int = 0; i < Array.length; i++)
          {  
              childCircle.hitTestObject(Array[i]);  
          }
      }
      

      或者,您可以指定一个 onEnterFrame 函数,该函数在每帧检查每个圆圈与其他圆圈,尽管这会使用更多资源。我猜此时资源对您来说不是问题,因此请使用更简单的路线并在以后需要时进行优化。

      【讨论】:

        猜你喜欢
        • 2015-02-10
        • 2014-04-19
        • 1970-01-01
        • 2022-01-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-07
        • 2013-01-28
        相关资源
        最近更新 更多