舞台上多个物体的碰撞测试
我正在尝试创建一种树形图,这样,如果您单击其中一个圆圈,它的子圆圈就会以某种程度的随机性从原始圆圈向外扩展,并通过线条连接。我已经完成了这项工作,但现在我想做的是确保没有任何圆圈相互碰撞,也没有任何线条交叉。您可以查看当前正在发生的情况的屏幕截图。我的代码如下。如何更改此代码以便检查冲突并避免冲突?我已经阅读了 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();
I'm trying to create a sort of tree diagram such that, if you click on one of the circles, its child circles spread outward with some degree of randomness from the original circle, connected by lines. I have this working, but now what I want to do is make sure that none of the circles collide with each other and none of the lines criss cross. You can see the screenshot for what is currently happening. My code is below. How do I change this code so that it checks for collisions and avoids them? I've read up on flash's hitTestObject command, but that only works in the context one object to another. I want to test for one object contacting any display object.
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);
//Want to check if either the line or the circle is contacting anything here. If it is, I want to kill the tween to the circle (thus also stopping the drawing of the line).
}
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();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
有两种方法可以做到这一点:
我注意到您实际上并未将 childCircles 添加到初始圆圈中,而是将它们添加到舞台中。您可能希望将这些圆圈推入数组中,以便稍后引用此“collisionDetection”方法。
There's 2 ways you could do this:
I notice you're not actually adding the childCircles to the initial circle, and instead adding them to the stage. You might want to push these circles into an Array to reference later for this "collisionDetection" method.
从根本上讲,您需要维护屏幕上所有圆圈的列表,然后每次有物体移动(或每一帧)时,您都需要检查移动的圆圈与所有其他圆圈,看看它们是否发生碰撞。
数组 应该可以很好地跟踪所有圆圈。
然后,每次有东西移动时,只要它在移动,你就应该遍历数组并检查它是否击中了任何其他圆圈。使用类似以下内容:
或者,您可以指定一个 onEnterFrame 函数,该函数每帧检查每个圆与其他每个圆的关系,尽管这会使用更多资源。我猜此时资源对您来说不是问题,因此请采用更简单的路线并在以后需要时进行优化。
Fundamentally you'll need to maintain a list of all the circles on the screen, and then every time something moves (or every frame) you'll need to check the moving circle against all the other circles to see if they are colliding.
An Array should work nicely for keeping track of all the circles.
Then, every time something moves, as long as it's moving, you should iterate through the array and check if it has hit any of the other circles. Use something like:
Alternatively, you can specify an onEnterFrame function that checks every circle against every other circle every frame, although this uses more resources. I'm guessing resources aren't an issue for you at this point, so go with the simpler route and optimize if you need it later.