确定爆炸半径损坏 - 圆到矩形2D

时间:2013-07-02 15:50:54

标签: objective-c math cocos2d-iphone

我正在制作的一个Cocos2D游戏具有圆形爆炸效果。这些爆炸效果需要在爆炸半径范围内对所有游戏角色(由所讨论的物体为坦克的矩形边界框表示)设置最大伤害的百分比。因此,这归结为圆形到矩形的碰撞以及圆形半径离最近的矩形边缘有多远。昨晚我搞砸了这个,但我相信可能有更好的方法。特别是,我不知道根据计算的距离确定应用的伤害百分比的最佳方法。

注意:所有坦克对象的锚点都为(0,0),因此位置取决于边界框的左下角。爆炸点是圆形爆炸的中心点。

        TankObject * tank = (TankObject*) gameSprite;

        float distanceFromExplosionCenter;
        // IMPORTANT :: All GameCharacter have an assumed (0,0) anchor
        if (explosionPoint.x < tank.position.x) {
            // Explosion to WEST of tank
            if (explosionPoint.y <= tank.position.y) {
                //Explosion SOUTHWEST
                distanceFromExplosionCenter = ccpDistance(explosionPoint, tank.position);

            } else if (explosionPoint.y >= (tank.position.y + tank.contentSize.height)) {
                // Explosion NORTHWEST
                distanceFromExplosionCenter = ccpDistance(explosionPoint,
                                                          ccp(tank.position.x, tank.position.y + tank.contentSize.height));

            } else {
                // Exp center's y is between bottom and top corner of rect
                distanceFromExplosionCenter = tank.position.x - explosionPoint.x;

            } // end if
        } else if (explosionPoint.x > (tank.position.x + tank.contentSize.width)) {
            // Explosion to EAST of tank
            if (explosionPoint.y <= tank.position.y) {
                //Explosion SOUTHEAST
                distanceFromExplosionCenter = ccpDistance(explosionPoint,
                                                          ccp(tank.position.x + tank.contentSize.width,
                                                                              tank.position.y));

            } else if (explosionPoint.y >= (tank.position.y + tank.contentSize.height)) {
                // Explosion NORTHEAST
                distanceFromExplosionCenter = ccpDistance(explosionPoint,
                                                          ccp(tank.position.x + tank.contentSize.width,
                                                              tank.position.y + tank.contentSize.height));

            } else {
                // Exp center's y is between bottom and top corner of rect
                distanceFromExplosionCenter = explosionPoint.x - (tank.position.x + tank.contentSize.width);

            } // end if
        } else  {
            // Tank is either north or south and is inbetween left and right corner of rect
            if (explosionPoint.y < tank.position.y) {
                // Explosion is South
                distanceFromExplosionCenter = tank.position.y - explosionPoint.y;

            } else {
                // Explosion is North
                distanceFromExplosionCenter = explosionPoint.y - (tank.position.y + tank.contentSize.height);

            } // end if
        } // end outer if
        if (distanceFromExplosionCenter < explosionRadius) {
            /* 
             Collision :: Smaller distance larger the damage
             */
            int damageToApply;
            if (self.directHit) {
                damageToApply = self.explosionMaxDamage + self.directHitBonusDamage;
                [tank takeDamageAndAdjustHealthBar:damageToApply];
                CCLOG(@"Explsoion-> DIRECT HIT with total damage %d", damageToApply);
            } else {
                // TODO adjust this... turning out negative for some reason...
                damageToApply = (1 - (distanceFromExplosionCenter/explosionRadius) * explosionMaxDamage);
                [tank takeDamageAndAdjustHealthBar:damageToApply];
                CCLOG(@"Explosion-> Non direct hit collision with tank");
                CCLOG(@"Damage to apply is %d", damageToApply);
            } // end if

        } else {
            CCLOG(@"Explosion-> Explosion distance is larger than explosion radius");
        } // end if
    } // end if

问题:

1)这个圆圈到矩形碰撞算法可以做得更好吗?我有太多支票吗?

2)如何计算基于百分比的损害?我目前的方法偶尔产生负数,我不明白为什么(也许我需要更多的睡眠!)。但是,在我的if语句中,我问距离是否为&lt;爆炸半径。当控制通过时,距离/半径必须< 1对吗?所以1 - 中间计算不应该是负面的。

感谢任何帮助/建议

修改

我偶尔的负面结果是由于错误的括号。

 damageToApply = (1 - (distanceFromExplosionCenter/explosionRadius)) * explosionMaxDamage;

仍在寻找有关如何计算爆炸半径伤害的输入。

1 个答案:

答案 0 :(得分:0)

您可以使用ccpDistance检查对象的距离:

float distance = ccpDistance(sprite1.position, sprite2.position);

我认为ccpDistance将始终返回正值。但如果是,那么得到绝对值:fabsf(distance)