2012-10-23 59 views
1

我目前正在使用Slick2D和我目前设置的方式在java中使用一种平台游戏,敌人是ArrayList中的Enemy对象。玩家可以向他们射击小圆圈(也包含在ArrayList中),如果他们连接,应该发生的是敌人“死亡”。这是我遇到麻烦的地方。我如何摆脱这样的对象?我已经尝试从每个循环中的数组中删除它们,但由于它仍然在搜索所述数组(我认为),所以会引发异常。敌人破坏slick2d

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(); 
    } 

} 

}

+0

_that does not work_;发生了什么事?请明确点。 – manas

回答

0

是,试图从您当前迭代通过,势必会造成问题一个ArrayList中删除元素。

您确定您的“相交”代码正在工作吗?快速查看替换方法即可满足您的需求。如果它没有做任何事情,也许它不应该找到交叉点。

1

正如您所指出的,您无法修改某些使用for-each循环的内容并继续迭代。相反,您需要使用Iteratorsee here

由于在ArrayList去除也需要每一个对象后要被移动的物体取出一个索引(因此是O(n)操作)离开,我建议你也可能想看看使用LinkedList来代替。

关于风格,你也应该总是通过它们的接口引用Collection对象,而不是它们的实现。也就是说,

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

应该

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

这样一来,如果你决定改变到一个LinkedList,你只需要代码更改为:

List<Integer> eRemove = new LinkedList<Integer(); 
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 VS LinkedList的性能比较,直到你有成千上万的子弹和敌人。