私が取り組んでいる Cocos2D ゲームの 1 つに、円形の爆発効果があります。これらの爆発効果は、爆発半径内のすべてのゲーム キャラクター (問題のオブジェクトがタンクであるため、長方形の境界ボックスで表されます) に、設定された最大ダメージの割合を与える必要があります。したがって、これは、円と長方形の衝突と、円の半径が最も近い長方形のエッジからどれだけ離れているかに要約されます。私は昨夜これを理解することに挑戦しましたが、もっと良い方法があるかもしれないと信じています. 特に、計算された距離に基づいて適用するダメージのパーセンテージを決定する最良の方法がわかりません。
注 : すべてのタンク オブジェクトには (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 ステートメントでは、距離 < 爆発半径かどうかを尋ねます。制御が通過するとき、距離/半径は < 1 でなければなりませんよね? したがって、1 - その中間計算は負であってはなりません。
ヘルプ/アドバイスに感謝します
編集
私の時折の否定的な結果は、括弧の配置が間違っていたことが原因でした。
damageToApply = (1 - (distanceFromExplosionCenter/explosionRadius)) * explosionMaxDamage;
爆発範囲のダメージを計算する方法についての情報をまだ探しています。