Actionscript 3 关于AS3中的碰撞检测算法

Actionscript 3 关于AS3中的碰撞检测算法,actionscript-3,algorithm,performance,collision-detection,Actionscript 3,Algorithm,Performance,Collision Detection,嗯。因此,有几种方法可以实现碰撞检测,如R树、四叉树、BSP树递归维度聚类(RDC)。或者更多 我的问题是舞台上大约有6-8个敌人,其中一些移动,一些静止,还有一个英雄同时用三种类型的导弹射击。所以我一次能在舞台上看到70-100个物体 我的问题是,这类问题使用哪种算法,哪种是常见的做法?还有哪一种效率最高 我想实现四叉树,但我读到你的速度可能很慢,或者我错了 ps:我可以使用八进制树吗?或者它们是严格用于3D的?我想我可能没有受过足够的教育来理解空间索引数据结构如何解决两个多边形相交的问题。也

嗯。因此,有几种方法可以实现碰撞检测,如R树、四叉树、BSP树递归维度聚类(RDC)。或者更多

我的问题是舞台上大约有6-8个敌人,其中一些移动,一些静止,还有一个英雄同时用三种类型的导弹射击。所以我一次能在舞台上看到70-100个物体

我的问题是,这类问题使用哪种算法,哪种是常见的做法?还有哪一种效率最高

我想实现四叉树,但我读到你的速度可能很慢,或者我错了


ps:我可以使用八进制树吗?或者它们是严格用于3D的?

我想我可能没有受过足够的教育来理解空间索引数据结构如何解决两个多边形相交的问题。也许你要检查其他多边形周围区域中的每个多边形是否相交

但我提出的一个解决方案是使用Minkowski求和。特别是如果你所有的点击框都是凸的。你可以将你的导弹的命中盒和敌人的命中盒相加,并将问题归结为导弹对每个敌人的点隶属度测试,尽管如果你的导弹/敌人轮换,这将成为一个更困难的问题


希望这些信息足够有用。

我想我可能没有受过足够的教育,无法理解空间索引数据结构如何解决两个多边形相交的问题。也许你要检查其他多边形周围区域中的每个多边形是否相交

但我提出的一个解决方案是使用Minkowski求和。特别是如果你所有的点击框都是凸的。你可以将你的导弹的命中盒和敌人的命中盒相加,并将问题归结为导弹对每个敌人的点隶属度测试,尽管如果你的导弹/敌人轮换,这将成为一个更困难的问题


希望这些信息足够有用。

如果你只有10个敌人和100颗子弹左右,我怀疑任何复杂的空间结构都会让你受益匪浅。对每一个敌人检查每一颗子弹相当于一千次检查,在我看来,与维护更复杂的结构相比,性能上的提高太小了

根据游戏速度的不同,你可以每隔一帧(甚至更少)而不是每一帧检查一次碰撞。这将为您的碰撞检测提供100%的性能提升

我建议简单地这样做:

for each(var enemy:Enemy in _enemies){
    for each(var bullet:Bullet in _bullets){
         if(bullet.x > enemy.x - enemy.width / 2 && 
            bullet.x < enemy.x + enemy.width / 2 &&
            bullet.y > enemy.y - enemy.height / 2 && 
            bullet.y < enemy.y + enemy.height / 2){
                trace("collision!");
         }
     }
}
针对每个(变量敌人:敌人中的敌人){
每个(变量项目符号:项目符号中的项目符号){
如果(bullet.x>敌方.x-敌方.width/2&&
子弹.x<敌人.x+敌人.width/2&&
bullet.y>敌方.y-敌方.height/2&&
子弹y<敌人y+敌人高度/2){
跟踪(“碰撞!”);
}
}
}

如果你只有10个敌人和100颗子弹左右,我怀疑任何复杂的空间结构都会让你受益匪浅。对每一个敌人检查每一颗子弹相当于一千次检查,在我看来,与维护更复杂的结构相比,性能上的提高太小了

根据游戏速度的不同,你可以每隔一帧(甚至更少)而不是每一帧检查一次碰撞。这将为您的碰撞检测提供100%的性能提升

我建议简单地这样做:

for each(var enemy:Enemy in _enemies){
    for each(var bullet:Bullet in _bullets){
         if(bullet.x > enemy.x - enemy.width / 2 && 
            bullet.x < enemy.x + enemy.width / 2 &&
            bullet.y > enemy.y - enemy.height / 2 && 
            bullet.y < enemy.y + enemy.height / 2){
                trace("collision!");
         }
     }
}
针对每个(变量敌人:敌人中的敌人){
每个(变量项目符号:项目符号中的项目符号){
如果(bullet.x>敌方.x-敌方.width/2&&
子弹.x<敌人.x+敌人.width/2&&
bullet.y>敌方.y-敌方.height/2&&
子弹y<敌人y+敌人高度/2){
跟踪(“碰撞!”);
}
}
}

首先,你正在制作一个flash游戏。第二,你的弹药爆炸了。你不需要精确的碰撞检测。如果你的方法简洁,100多个对象不会妨碍你

绕过你的敌人,检查距离。如果距离小于X,爆炸,再次绕过敌人,使用距离造成相对伤害

// class variables
var baseDamage:Number = 50;
var splashMinDistance:Number = 72;
var splashMaxDistance:Number = 144;

var enemies:Array = // array of enemies
var ammunition:Array = // array of live ammo

function checkForContact() {
    var enemy:Enemy;
    var ammo:Ammo;

    var i:int, ic:int = enemies.length;
    var j:int, jc:int = ammo.length;

    for (i=0; i<ic; i++) {
        enemy = enemies[i];
            if (enemy == NULL) continue;
        for (j=0; j<jc; j++) {
            ammo = ammunition[j];
                    if (ammo == NULL) continue;
            if (contact(ammo, enemy)) {
                explode(ammo);
                ammo = NULL;
            }
        }
    }

    // sort ammo to remove nulls now that we're past
    // the time-sensitive part
}

function contact(ammo:Ammo, enemy:Enemy):Boolean {
    return (distance(ammo, enemy) < splashMinDistance);
}

function explode(ammo:Ammo) {
    var enemy:Enemy;
    var distance:Number;

    var i:int, ic:int = enemies.length;

    for (i=0; i<ic; i++) {
        enemy = enemies[i];
        distance = clamp(distance(ammo, enemy), splashMinDistance, Math.INT_MAX);
        if (distance > splashMaxDistance) continue;
        damageRatio = ((distance-splashMinDistance) / (splashMaxDistance-splashMinDistance));
        enemy.health -= baseDamage * damageRatio;
        if (enemy.health < 0) kill(enemy);
    }
}


function distance (o:Object, o2:Object) {
    var dx=o.x-o2.x;
    var dy=o.y-o2.y;
    return Math.sqrt(dx*dx+dy*dy);
}
//类变量
var baseDamage:数量=50;
var距离:数值=72;
var最大距离:数字=144;
var敌人:数组=//敌人数组
变量弹药:数组=//实弹数组
函数checkForContact(){
敌人:敌人;
var弹药:弹药;
变量i:int,ic:int=1.length;
变量j:int,jc:int=ammo.length;

对于(i=0;i1,你在做一个flash游戏。2,你的弹药爆炸。你不需要精确的碰撞检测。如果你的方法简洁,100多个物体不会阻碍你

绕过你的敌人并检查距离。如果距离小于X,爆炸,再次绕过敌人,使用距离作为相对伤害

// class variables
var baseDamage:Number = 50;
var splashMinDistance:Number = 72;
var splashMaxDistance:Number = 144;

var enemies:Array = // array of enemies
var ammunition:Array = // array of live ammo

function checkForContact() {
    var enemy:Enemy;
    var ammo:Ammo;

    var i:int, ic:int = enemies.length;
    var j:int, jc:int = ammo.length;

    for (i=0; i<ic; i++) {
        enemy = enemies[i];
            if (enemy == NULL) continue;
        for (j=0; j<jc; j++) {
            ammo = ammunition[j];
                    if (ammo == NULL) continue;
            if (contact(ammo, enemy)) {
                explode(ammo);
                ammo = NULL;
            }
        }
    }

    // sort ammo to remove nulls now that we're past
    // the time-sensitive part
}

function contact(ammo:Ammo, enemy:Enemy):Boolean {
    return (distance(ammo, enemy) < splashMinDistance);
}

function explode(ammo:Ammo) {
    var enemy:Enemy;
    var distance:Number;

    var i:int, ic:int = enemies.length;

    for (i=0; i<ic; i++) {
        enemy = enemies[i];
        distance = clamp(distance(ammo, enemy), splashMinDistance, Math.INT_MAX);
        if (distance > splashMaxDistance) continue;
        damageRatio = ((distance-splashMinDistance) / (splashMaxDistance-splashMinDistance));
        enemy.health -= baseDamage * damageRatio;
        if (enemy.health < 0) kill(enemy);
    }
}


function distance (o:Object, o2:Object) {
    var dx=o.x-o2.x;
    var dy=o.y-o2.y;
    return Math.sqrt(dx*dx+dy*dy);
}
//类变量
var baseDamage:数量=50;
var距离:数值=72;
var最大距离:数字=144;
var敌人:数组=//敌人数组
变量弹药:数组=//实弹数组
函数checkForContact(){
敌人:敌人;
var弹药:弹药;
变量i:int,ic:int=1.length;
变量j:int,jc:int=ammo.length;
对于(i=0;i