私は、ff を含む単純な AndEngine ゲームに取り組んでいます。スプライト
a.) 戦車 b.) 兵士 c.) 爆弾
ここに同様の質問があります: Android AndEngine: Simple sprite collision
ゲームの外観:
ただし、最初の問題を修正すると、別の問題が発生しました。
爆弾 (飛行機が現在いる場所にスポーンし、マウス クリックによってターゲットまたは床に到達するまで垂直に下降する) がターゲット (たとえば兵士) に命中すると、兵士のスプライトは切り離され、その後ろに血しぶきのスプライトを残す必要があります。 1秒間だけでなく、爆弾からの爆発スプライト。ただし、ゲーム フォースは indexOutOfBoundError を出して終了します。これはおそらく爆弾とそのターゲットの間のスプライト数の不一致であり、範囲外の配列エラーを引き起こしている可能性があることを理解していますが、logCat はまったく役に立ちません。
09-22 11:13:37.585: E/AndroidRuntime(735): FATAL EXCEPTION: UpdateThread
09-22 11:13:37.585: E/AndroidRuntime(735): java.lang.IndexOutOfBoundsException: Invalid index 5, size is 5
09-22 11:13:37.585: E/AndroidRuntime(735): at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
09-22 11:13:37.585: E/AndroidRuntime(735): at java.util.ArrayList.get(ArrayList.java:304)
09-22 11:13:37.585: E/AndroidRuntime(735): at org.andengine.entity.Entity.onManagedUpdate(Entity.java:1402)
09-22 11:13:37.585: E/AndroidRuntime(735): at org.andengine.entity.Entity.onUpdate(Entity.java:1167)
09-22 11:13:37.585: E/AndroidRuntime(735): at org.andengine.entity.Entity.onManagedUpdate(Entity.java:1402)
09-22 11:13:37.585: E/AndroidRuntime(735): at org.andengine.entity.scene.Scene.onManagedUpdate(Scene.java:284)
09-22 11:13:37.585: E/AndroidRuntime(735): at org.andengine.entity.Entity.onUpdate(Entity.java:1167)
09-22 11:13:37.585: E/AndroidRuntime(735): at org.andengine.engine.Engine.onUpdateScene(Engine.java:591)
09-22 11:13:37.585: E/AndroidRuntime(735): at org.andengine.engine.Engine.onUpdate(Engine.java:586)
09-22 11:13:37.585: E/AndroidRuntime(735): at org.andengine.engine.Engine.onTickUpdate(Engine.java:548)
09-22 11:13:37.585: E/AndroidRuntime(735): at org.andengine.engine.Engine$UpdateThread.run(Engine.java:820)
ここで見られるように、logCat は私のコードではなく、AndEngine 自体でエラーを出しています。おそらくそうではないでしょう。
onCreateScene Update Handler で実行される新しいコード (上記のリンクされた前の問題のヘルプに従って):
protected void checkSoldierCollision() {
// TODO Auto-generated method stub
int numBombs = bombGroup.getChildCount();
int numTroops = troopsGroup.getChildCount();
final ArrayList<Sprite> toBeDetached = new ArrayList<Sprite>();
for (int i = 0; i < numBombs; i++) {
Sprite s = (Sprite) bombGroup.getChildByIndex(i);
for (int j = 0; j < numTroops; j++) {
Sprite s2 = (Sprite) troopsGroup.getChildByIndex(j);
if (s.collidesWith(s2)) {
/*Sprite splat = createSplat();
splat.setPosition(s.getX(), s.getY());
getEngine().getScene().attachChild(splat);*/
Sprite splode = createExplosion();
splode.setPosition(s.getX(), s.getY());
getEngine().getScene().attachChild(splode);
// WARNING: cannot detach from the list
//while looping through the list
toBeDetached.add(s);
toBeDetached.add(s2);
}
}
}
runOnUpdateThread(new Runnable() {
@Override
public void run() {
for (Sprite s : toBeDetached) {
s.detachSelf();
Sprite splode = createExplosion();
splode.setPosition(s.getX(), s.getY());
getEngine().getScene().attachChild(splode);
}
toBeDetached.clear();
}
});
}
エラーが発生しないためには、スプラットまたは爆発のいずれかであることに気付きました。スプラットと爆発の両方が衝突時にシーンに取り込まれた場合、エラーが発生します。
また、爆弾が兵士に当たらない場合でも (ただし、床にぶつかると分離して爆発雲に置き換えられます)、同様のエラーが発生します。
私の createBomb 関数:
public Sprite createBomb(float x, float y) {
Sprite bombSprite = new Sprite(x, y, this.mBombTextureRegion,
getVertexBufferObjectManager());
MoveYModifier downModBomb = new MoveYModifier(1, 60, FLOOR);
downModBomb.addModifierListener(new IModifierListener<IEntity>() {
@Override
public void onModifierStarted(IModifier<IEntity> pModifier,
IEntity pItem) {
}
@Override
public void onModifierFinished(IModifier<IEntity> pModifier,
final IEntity pItem) {
pItem.detachSelf();
AnimatedSprite explodeSprite = createExplosion();
explodeSprite.setPosition(pItem.getX(), FLOOR);
getEngine().getScene().attachChild(explodeSprite);
}
});
bombSprite.registerEntityModifier(downModBomb); // register action
return bombSprite;
}
私の onCreateScene 爆弾関数と衝突 updateHandler:
scene.setOnSceneTouchListener(new IOnSceneTouchListener() {
@Override
public boolean onSceneTouchEvent(Scene pScene,
TouchEvent pSceneTouchEvent) {
if (pSceneTouchEvent.getAction() == TouchEvent.ACTION_UP) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Sprite bomb = createBomb(f16Sprite.getX(),
f16Sprite.getY());
bombGroup.attachChild(bomb);
}
});
return true;
}
return false;
}
});
// periodic checks
scene.registerUpdateHandler(new IUpdateHandler() {
@Override
public void onUpdate(float pSecondsElapsed) {
// checkTankCollision();
// checkSoldierBackCollision();
checkSoldierCollision();
}
@Override
public void reset() {
}
});
私の createExplosion メソッド:
public AnimatedSprite createExplosion() {
AnimatedSprite boomSprite = new AnimatedSprite(0, 0,
this.mExplodeTextureRegion, getVertexBufferObjectManager());
DelayModifier delay = new DelayModifier(.3f); // delay in seconds, can
// take float numbers .5
// seconds
delay.addModifierListener(new IModifierListener<IEntity>() {
@Override
public void onModifierStarted(IModifier<IEntity> pModifier,
IEntity pItem) {
((AnimatedSprite) pItem).animate(new long[] { 100, 100, 100 }, // durations/frame
new int[] { 1, 2, 3 }, // which frames
true); // loop
}
@Override
public void onModifierFinished(IModifier<IEntity> pModifier,
final IEntity pItem) {
((AnimatedSprite) pItem).detachSelf();
}
});
boomSprite.registerEntityModifier(delay); // register action
return boomSprite;
}
これを解決するにはどうすればよいですか?ループ ロジックは、完全に私の強みというわけではありません。これを別の方法で実装する方法についてもオープンです。
更新: 衝突の結果がスプラットまたは爆発のいずれであっても、プレーヤーが爆弾を連発し続ければ (たとえば 4 ~ 5 回)、ゲーム全体の力が閉じられることに気付きました。
- はんだ/タンクのインスタンスを作成するたびに許容される爆撃回数があるようです。爆弾が兵士に命中するたびに、最初に爆発の作成をオフにしました (そのため、両方ではなく、ブラッドスプラットがその場所に残ります)。問題なく動作しますが、爆弾が 4 ~ 6 個を超えるとゲームが終了します。新しい兵士インスタンスがスポーンすると (つまり、古いものが画面から消えて切り離されると)、ゲーム フォースが終了する前にプレイヤーに 4 ~ 6 個の爆弾が与えられます。