1

私は現在、Slick2Dを使用してJavaで一種のプラットフォーマーに取り組んでおり、現在セットアップしている方法では、敵はArrayListの敵オブジェクトです。プレイヤーは小さな円 (これも ArrayList に保持されています) をそれらに向けて撃つことができ、それらが接続すると、敵は「死ぬ」ことになります。これは私が困っているところです。そのようなオブジェクトを取り除くにはどうすればよいですか? for eachループで配列からそれらを削除しようとしましたが、その配列をまだ検索しているという事実のために例外がスローされます(私は思います)。

for (Bullet bullet : bullets) {
  for (Enemy enemy : enemies) {
    if (bullet.intersects(enemy) {
      bullets.remove(bullet);
      enemies.remove(enemies);
    }
  }
}

それはうまくいかなかったので、次のように、相互作用する弾丸と敵のインデックスの配列を作成し、ループ後にそれらを削除しようとしています:

for (int i = 0; i < bullets.size(); i++) {
  for (int z = 0; z < enemies.size(); z++) {
    if (bullets.get(i).intersects(enemies.get(z).getPoly())) {
      bRemove.add(i);
      eRemove.add(z);
    }
  }
}

for (Integer i : bRemove) {
  bullets.remove(i);
}

for (Integer i : eRemove) {
  enemies.remove(i);
}

今は何も起こっていないようです。私が何をすべきか知っている人はいますか?これは、メイン クラス全体です。

package ca.wmc.BasicPlatform;

import java.lang.Math;
import java.util.ArrayList;

import org.newdawn.slick.Animation;
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.geom.Circle;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.SpriteSheet;
import org.newdawn.slick.geom.Polygon;

public class Game extends BasicGame  {

Player quote;
public BlockMap map;
private boolean start;
private int startCount;
private boolean lost;
private int lostCount;
private int hpTime = 0;
private ArrayList<Enemy> enemies;
private ArrayList<Bullet> bullets;
private int reload = 0;
private final double a = 2;
private int t = 0;

public Game() {
    super("Super Simple Platform");
}

public void init(GameContainer container) throws SlickException {
    container.setVSync(true);
    container.setTargetFrameRate(60);
    map = new BlockMap("tiled/newmap.tmx");
    quote = new Player("tiled/Quote.gif", 320, 320, 3, -8);
    enemies = new ArrayList<Enemy>();
    enemies.add(new Enemy("tiled/King.gif", 50, 0, -8, 26, 32));
    enemies.add(new Enemy("tiled/Quote.gif", 200, 150, -8, 28, 32));
    start = false;
    lost = false;
    bullets = new ArrayList<Bullet>();
}

public void update(GameContainer container, int delta) throws SlickException {
    if (!start) {
        if (container.getInput().isKeyDown(Input.KEY_Z)) {
            start = true;
        }
    } else {
        if (!lost) {

            ArrayList<Integer> eRemove = new ArrayList<Integer>();
            ArrayList<Integer> bRemove = new ArrayList<Integer>();

            quote.update(container, a, t, delta);
            for (Enemy enemy : enemies) {
                enemy.update(quote, a, t);
            }

            if (t == 5) {
                t = 0;
            } else {
                t++;
            }

            if (container.getInput().isKeyDown(Input.KEY_X) && reload == 0) {
                if (quote.getCurAnimation() == quote.right()) {
                    bullets.add(new Bullet(quote.getXPos() + 28, quote.getYPos() + (int)(20 * Math.random() - 22) + 25, "r"));
                } else {
                    bullets.add(new Bullet(quote.getXPos() + 28, quote.getYPos() + (int)(20 * Math.random() - 22) + 25, "l"));
                }
                reload = 10;
            }

            if (reload > 0) {
                reload--;
            }

            for (Bullet bullet : bullets) {
                if (bullet.getDirection()) {
                    bullet.setCenterX(bullet.getCenterX() + 10);
                } else { 
                    bullet.setCenterX(bullet.getCenterX() - 10);
                }
            }

            for (Enemy enemy : enemies) {
                if (quote.getPoly().intersects(enemy.getPoly()) && hpTime > 50 && quote.getHP() != 0) {
                    quote.setHP(quote.getHP() - 1);
                    hpTime = 0;
                    if (quote.getHP() <= 0) {
                        lost = true;
                    }
                }
            }

            hpTime++;

            if (startCount <= 100) {
                startCount++;
            }

            for (int i = 0; i < bullets.size(); i++) {
                for (int z = 0; z < enemies.size(); z++) {
                    if (bullets.get(i).intersects(enemies.get(z).getPoly())) {
                        bRemove.add(i);
                        eRemove.add(z);
                    }
                }
            }

            for (Integer i : bRemove) {
                bullets.remove(i);
            }

            for (Integer i : eRemove) {
                enemies.remove(i);
            }
        }

        if (quote.getYPos() > 640) {
            lost = true;
        }

    }
}

public void render(GameContainer container, Graphics g) throws SlickException{
    g.drawImage(new Image("apsci.jpg"), 0, 0);
    BlockMap.tmap.render(0, 0);
    g.drawAnimation(quote.getCurAnimation(), quote.getXPos(), quote.getYPos());
    for (Enemy enemy : enemies) {
        g.drawAnimation(enemy.getCurAnimation(), enemy.getXPos(), enemy.getYPos());
    }

    for (Circle bullet : bullets) {
        g.draw(bullet);
    }

    g.drawString("HP: " + quote.getHP(), 10, 450);

    if (!start) {
        g.drawString(getTitle(), 150, 0);
        g.drawString("Controls: arrow keys to move, Z to jump, X to fire.", 150, 50);
        g.drawString("Defeat the evil.          Press Z to start.", 150, 100);
    }

    if (startCount < 100) {
        for (Enemy enemy : enemies) {
            g.drawString("The Evil -->", enemy.getXPos() - 125, enemy.getYPos() + 10 + (int)(2 * Math.random()));
        }
        g.drawString("<-- You", quote.getXPos() + 50, quote.getYPos() + 10 + (int)(2 * Math.random()));
    }

    if (lost) {
        g.drawString("You have lost.", 200, 210);
    }
    if (lostCount > 150) {
        g.drawString("Game over.", 200, 260);
    }
    if (lostCount > 200) {
        g.drawString("If that wasn't already obvious.", 200, 310);
    }
}

public static void main(String[] args) throws SlickException{
    // TODO Auto-generated method stub
    try {
        AppGameContainer app = new AppGameContainer(new Game(), 640, 480, false);
        app.start();
    } catch (SlickException e) {
        e.printStackTrace();
    }

}

}

4

3 に答える 3

1

お気づきのように、for-eachループを利用して何かを変更し、繰り返しを続けることはできません。Iterator代わりに、 :を利用する必要があります。ここを参照してください

での削除では、ArrayList削除されたオブジェクトの後のすべてのオブジェクトを1つのインデックスだけ左にシフトする必要があるため(したがって、O(n)操作です)、代わりに使用することも検討することをお勧めしますLinkedList

スタイルに関してはCollection、実装ではなく、常にインターフェイスを介してオブジェクトを参照する必要があります。あれは、

ArrayList<Integer> eRemove = new ArrayList<Integer>();

する必要があります

List<Integer> eRemove = new ArrayList<Integer>();

このように、LinkedListに変更することにした場合は、コードを次のように変更するだけで済みます。

List<Integer> eRemove = new LinkedList<Integer();
于 2012-10-23T03:34:47.250 に答える
0

はい、現在反復処理しているArrayListから要素を削除しようとすると、問題が発生する可能性があります。

'intersect'コードが機能していることを確認しますか?簡単に見ると、交換方法は必要なもののように見えます。何もしていない場合は、必要なときに交差点が見つからない可能性があります。

于 2012-10-23T03:33:49.250 に答える
0

現在のコードは、少なくとも最初の弾丸と最初の敵を正しく削除する必要があります。そうでない場合は、intersects方法に問題があります。

最初の箇条書きが削除されると、それ以降のすべての要素が移動するため、間違った箇条書きを削除します。

これを試して:

for (int i = 0; i < bullets.size(); i++) {
        boolean hit = false;
        for (int z = 0; z < enemies.size(); z++) {

            if (bullets.get(i).intersects(enemies.get(z).getPoly())) {
                hit = true;
                enemies.remove(z);
                z--;
            }
        }

        if (hit) {
            bullets.remove(i);
            i--;
        }
}

そして、何千もの弾丸と敵ができるまで、ArrayList と LinkedList のパフォーマンスについて心配する必要があります。

于 2012-10-23T03:43:04.397 に答える