2013-04-24 94 views
0

我正在使用java創建一個小坦克遊戲。在那場比賽中,隨時會在遊戲網格上的隨機位置生成救生包和錢幣堆。他們都有一個有限的生命週期終身到期後,他們從字段消失。當他們在網格上可見時,任何坦克都可以在消失之前獲得它們。我想保留生命值對象列表和coinpile對象在一個ArrayList爲了訪問他們的遊戲AI算法。我希望使用簡單的Java知識來實現​​上述概念。將運行的線程對象添加到arraylist中

以下是我LifePack class.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到一個ArrayList如下:

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

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

每次創建新的生活包,我將這個生活包對象添加到上面的數組列表中。一旦lifepack的生命週期到期,我想在上面的類中將'可見'布爾變量設置爲'false',以便我可以檢查該變量是否存在其他用途​​。

但我沒有得到我想要的輸出。我可以像上面那樣將運行的線程對象添加到arraylist中並保持線程狀態正在運行,還是必須移動到不同的實現?如果有解決方案,請有人幫我解決這個問題。

謝謝。

+5

你的建築總體來說不是很好。你爲每個Lifepack創建一個新的線程,所以如果你有說1000個Lifepacks的話,你將有1000線程運行。線程是有代價的(上下文切換等),並且爲什麼你應該在這裏做這件事實在沒有意義。相反,使用一個遊戲邏輯線程(或者可能爲所有救生包指定一個線程),並檢查每個x毫秒是否你的生活包仍然活着並執行一些遊戲邏輯。這是通常的遊戲架構方法。 – dirkk 2013-04-24 13:06:05

+0

謝謝@dirkk。其實我的java知識並不是那麼好。我會嘗試你的想法。再次感謝。 – Deepal 2013-04-24 13:31:10

回答

0

從我所看到的,一個線程檢查列表中的一些入門是假的,其他線程它設置爲false,這需要是線程安全的

你可以做到這一點的更新操作過程中同步列表本身

synchronized(list){ 
     //update the needed entry to false 
    } 
+0

在列表上同步以更新條目看起來像是一個巨大的瓶頸。 – rethab 2013-04-24 13:52:14

+0

@rethab我知道。關於如何更新列表中的條目的任何其他想法? – Eugene 2013-04-24 13:55:04

+0

如果它真的只是一個標誌,那麼一個原子變量就可以做到這一點。但正如我在文章中所建議的那樣,我會改變維持對象狀態的總體思路。 – rethab 2013-04-24 14:01:47

0

前面已經指出的那樣,創建線程是一個壞主意。特別是,一旦你的應用程序到達了存在很多救生包的點。另外請注意,在構造函數中啓動線程是非常糟糕的做法。如果你想使用純線程,建議實現一個可運行的(java.lang.Runnable)。但是,一般來說,我強烈建議您使用java.util.concurrent包中提供的Java併發抽象:http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html使用ExecutorService來運行可調用對象(java.util.concurrent.Callable)允許您改變線程的數量很容易。

我也會質疑你的想法,將所有救生包放在同一個集合中,併爲它們分配一個狀態(可見性)。自發地,我可以想到以下情況:一旦遊戲運行了相當長的一段時間,最終你會得到大量的救生包,其中大部分不再使用。因此,你可能想要考慮爲不同的狀態生命包可以有不同的集合。這也會使扔掉對象非常容易(無需遍歷集合)。Aussuming這些集合將被多個線程訪問,你希望它們是線程安全的。爲此,您還可以在java.util.concurrent包中找到各種類型的集合。