0

我正在使用java创建一个小型坦克游戏。在该游戏中,生命包和硬币堆不时在游戏网格上的随机位置生成。他们都有有限的生命周期在生命周期结束后,他们就会从场上消失。当它们在网格上可见时,任何坦克都可以在消失之前获得它们。我想将 lifepack 对象和 coinpile 对象的列表保存在ArrayList中,以便通过游戏 AI 算法访问它们。我希望使用简单的java知识实现上述概念如下。

以下是我的 LifePack 类。CoinPile 类的行为方式类似:

public class LifePack extends Thread{
    public int healthBonus;
    public int lifetime;
    public String type;
    public Point location;
    public boolean visible;

    public LifePack(int x,int y,int lifetime){
        location=new Point(x, y);
        this.lifetime=lifetime;
        this.type="health_pack";
        this.visible=true;
        this.start();

    }

    public void run(){
        while(true){

            if(this.lifetime>0){
                try{
                    Thread.sleep(1);
                    if(lifetime%1000==0){
                        System.out.println("Life pack "+this.getId()+" will be disappeared in "+this.lifetime/1000+" s");
                    }
                    this.lifetime--;
                }
                catch(Exception ex){
                    ex.printStackTrace();
                }
            }
            else{
                this.visible=false;
                this.interrupt();
                break;
            }
        }
        System.out.println("Life pack visibility = "+this.visible);
    }


}

我想将新创建的 LifePack 对象添加到数组列表中,如下所示:

public ArrayList<LifePack> lifePacks;
lifePacks = new ArrayList<LifePack>();

lifePacks.add(new LifePack(x, y, lifeTime));

每次创建新的生命包时,我都会将该生命包对象添加到上面的数组列表中。一旦生命包的生命周期到期,我想将上述类中的“可见”布尔变量设置为“ false ”,以便我可以检查该变量以用于其他目的。

但我没有得到我想要的输出。我可以将正在运行的线程对象添加到上面的数组列表中并保持线程状态运行,还是我必须移动到不同的实现?如果有解决方案,请有人帮我解决这个问题。

谢谢你。

4

3 回答 3

0

正如已经指出的那样,创建线程是一个坏主意。特别是,一旦您的应用程序达到存在大量生命包的地步。另请注意,在构造函数中启动线程是非常糟糕的做法。如果你想使用普通线程,建议实现一个可运行的(java.lang.Runnable)。

但是,总的来说,我强烈建议您使用 java.util.concurrent 包中提供的 Java 并发抽象:http: //docs.oracle.com/javase/6/docs/api/java/util/concurrent/ package-summary.html使用 ExecutorService 来运行 callables (java.util.concurrent.Callable) 允许您很容易地改变线程数。

我还会质疑您将所有生命包存储在同一个集合中并为每个生命包分配状态(可见性)的想法。我不由自主地想到了以下场景:一旦游戏运行了一段时间,你最终会得到大量的救生包,其中大部分都不再使用了。因此,您可能需要考虑为 lifepack 所处的不同状态设置不同的集合。这也将使丢弃对象变得非常容易(无需遍历集合)。假设这些集合将被多个线程访问,您希望它们是线程安全的。为此,您还可以在 java.util.concurrent 包中找到各种类型的集合。

于 2013-04-24T13:45:42.280 回答
0

我同意 dirkk 的观点,即你会启动太多线程。但要回答你的问题,也许你应该考虑使用 AtomicBoolean 来显示。

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/atomic/AtomicBoolean.html

于 2013-04-24T13:11:56.077 回答
0

从我所见,一个线程检查列表中的某些条目是否为假,其他线程将其设置为假,这需要是线程安全的。

您可以通过在更新操作期间同步列表本身来做到这一点

  synchronized(list){
       //update the needed entry to false
  }
于 2013-04-24T13:40:31.667 回答