Actionscript 3 AS3中collison检测码的优化
我在舞台上有两个mc,第一个叫做导弹,第二个叫做盒子 因此,我把盒子放在盒子里,导弹放在盒子里。我的问题是如何检测是否有任何导弹与箱子相撞并损坏箱子 我使用的是简单有效的算法,但当舞台上有很多导弹和箱子时,算法速度非常慢。我使用了两个嵌套的“for”循环,这是一个糟糕的做法,但我目前没有其他想法 这是密码Actionscript 3 AS3中collison检测码的优化,actionscript-3,collision-detection,Actionscript 3,Collision Detection,我在舞台上有两个mc,第一个叫做导弹,第二个叫做盒子 因此,我把盒子放在盒子里,导弹放在盒子里。我的问题是如何检测是否有任何导弹与箱子相撞并损坏箱子 我使用的是简单有效的算法,但当舞台上有很多导弹和箱子时,算法速度非常慢。我使用了两个嵌套的“for”循环,这是一个糟糕的做法,但我目前没有其他想法 这是密码 public function onEnterFrame(e:Event) { for(var i:int=0;i<ground_mc.boxesLayer_mc.num
public function onEnterFrame(e:Event) {
for(var i:int=0;i<ground_mc.boxesLayer_mc.numChildren;i++){
mc1=ground_mc.boxesLayer_mc.getChildAt(i);
for(var j:int=0;j<ground_mc.bmLayer_mc.numChildren;j++){
mc2=ground_mc.bmLayer_mc.getChildAt(j);
if(mc1.hitTestObject(mc2)){
se=new SmallExplosion();
se.x=mc1.x+randNumber(-20,20);
se.y=mc1.y+randNumber(-20,20);
ground_mc.addChild(se);
mc1.decreaseHealth(mc2.getDamage());
}
}
}
}
公共函数一个帧间(e:事件){
对于(var i:int=0;i最好的解决方案是使用一些物理引擎(比如)。而使用游戏引擎(比如)进行游戏开发更好:)
尽管如此,如果你想自己完成所有的工作,你可以选择like structures:)对每一个都使用一个,这样代码会稍微整洁一些,任务也会更少
还可以将OneInterFrame更改为计时器事件。如果需要,可以减慢计时器事件的速度
public function onEnterFrame(e:Event) {
for each( var box:MovieClip in ground_mc.boxesLayer_mc ){
for each(var missle:MovieClip in <ground_mc.bmLayer_mc ){
if( box.hitTestObject(missle)){
se=new SmallExplosion();
se.x=box.x+randNumber(-20,20);
se.y=box.y+randNumber(-20,20);
ground_mc.addChild(se);
box.decreaseHealth(missle.getDamage());
}
}
}
}
公共函数一个帧间(e:事件){
每个(变量框:地上的MovieClip\u mc.boxesLayer\u mc){
对于类似的任务(2D),我所做的是创建一个简单的四叉树结构,其中每个节点可以包含其他子节点,也可以包含用于冲突检测的显示对象列表。请注意,如果对象(在您的示例中为框)为移动很多这将不是有效的,因为每次移动时都需要将它们移动到正确的节点中
一个简单的示例类是:
public class WorldPartitionNode {
private var minX : Number;
private var minY : Number;
private var maxX : Number;
private var maxY : Number;
private var width : Number;
private var height : Number;
private var _children : Vector.<WorldPartitionNode>;
private var _objects : Vector.<GameObject>;
public function WorldPartitionNode(x : Number, y : Number,
w : Number, h : Number, childLevels : int)
{
minX = x;
minY = y;
maxX = x + w;
maxY = y + h;
width = h;
height = h;
if (childLevels == 0) {
// This node should have no children, so instead it should
// contain display objects
_objects = new Vector.<GameObject>;
}
else {
_children = new Vector.<WorldPartitionNode>(4,true);
_children[0] = new WorldPartitionTreeNode(minX, minY, width/2, height/2, childLevels-1);
_children[1] = new WorldPartitionTreeNode(minX+width/2, minY, width/2, height/2, childLevels-1);
_children[2] = new WorldPartitionTreeNode(minX, minY+height/2, width/2, height/2, childLevels-1);
_children[3] = new WorldPartitionTreeNode(minX+width/2, minY+height/2, width/2, height/2, childLevels-1);
}
}
public function addObject(obj : GameObject) : void
{
if (_children) {
// This is not a leaf node, so add it to that of the child
// nodes in which it belongs.
var i : uint;
for (i=0; i<4; i++) {
var c : WorldPartitionNode = _children[i];
if (obj.x > c.minX && obj.y > c.minY && obj.x < c.maxX && obj.y < c.maxY) {
c.addObject(obj);
return; // Found node, so bail
}
}
}
else {
// This is a leaf node, so just add to the internal objects vector
_objects.push(obj);
}
}
public function checkCollisions(x : Number, y : Number) : GameObject
{
if (_children) {
// This node has children, so delegate to the right child
var i : uint;
for (i=0; i<4; i++) {
var c : WorldPartitionNode = _children[i];
if (x > c.minX && y > c.minY && x < c.maxX && y < c.maxY) {
return c.checkCollisions(x, y);
}
}
}
else {
// This is a leaf node (with objects directly in it) so loop through
// them all and check collision
var obj : GameObject;
for each (obj in _objects) {
if (obj.collidesWith(x, y))
return obj;
}
return null; //None if reached
}
}
}
要检查导弹与树中对象之间的碰撞:
var missile : GameObject;
for each (missile in _missiles) {
var obj : GameObject = treeRoot.checkCollisions(missile.x, missile.y);
if (obj != null)
obj.kill(); // Was hit by missile
}
这可能会显著加快冲突检测,但依赖于框是静态的(或很少移动),因为如果它们移动,它们将不再位于正确的分区节点中,如果它们不是,树将无法找到它们之间的冲突
毫无疑问,这里有更智能的分区系统,但在我需要分散拾取的项目中,这对我来说非常有效(coins et c)在一个很大的空间里,玩家会飞过来收集它们。每一帧我都会让树检查静态拾音器和玩家之间的碰撞。我有几种类型的盒子,所以有些盒子是站着的,有些盒子移动得很慢或很快:)如果我一次至少有六个盒子在舞台上,这个代码会有效吗?一些盒子在移动,一些盒子在站立。哇,我不知道AS3中有foreach语句。一定要试试这个,谢谢
var missile : GameObject;
for each (missile in _missiles) {
var obj : GameObject = treeRoot.checkCollisions(missile.x, missile.y);
if (obj != null)
obj.kill(); // Was hit by missile
}