2016-03-30 23 views
0

私はlibgdxを使ってキャラクターがコインを集めて得点を得るシンプルなゲームを作っています。コインが再び消滅する前に1-2秒間しか現れないようにしたいと思います。私はそれをどうやって行うのか分からない。私はスケジューラーやnanoTime()のような技術を試してみましたが、うまく動作しません。特定の時間にオブジェクトが消えるようにするにはどうすればよいですか?

私はコインにスポーンするためにイテレータを使用しています。 (これは更新方法です)

if(TimeUtils.nanoTime() - coin.lastDropTime > 2000000000){ 
      coin.spawnCoin(); 
    } 

    Iterator<Rectangle> iter = coin.coins.iterator(); 
    while(iter.hasNext()) { 
     Rectangle gold_coin = iter.next(); 
     if(snail.bounds.overlaps(gold_coin)){ 
      score += 10; 
      iter.remove(); 
     } 
    } 

これはコインクラスです。

public class Coin { 

Sprite image; 

boolean isVisible = true; 

public Array<Rectangle> coins; 
public long lastDropTime; 

public Coin(){ 
    image = GameScreen.coin_sprite; 
    coins = new Array<Rectangle>(); 
} 

public void spawnCoin(){ 
    Rectangle bounds = new Rectangle(); 
    bounds.x = MathUtils.random(20, 1920 - 16); 
    bounds.y = MathUtils.random(20, 1080 - 50); 
    bounds.width = image.getWidth(); 
    bounds.height = image.getHeight(); 
    coins.add(bounds); 
    lastDropTime = TimeUtils.nanoTime(); 
} 

} 

私は唯一のコインがお互いの後に2秒を起動するために取得することができ、かつ取り外しコインを取得する唯一の方法は、それらのオーバーラップcharachterをさせることです。

+0

あなたのコインクラスは、1枚のコインまたはすべてのコインを代表するものとしますか?すべてのコインにはlastDropTimeが1つしかありません。コインごとに時間がかかるように聞こえます。lastDropTimeで個々のコインのクラスを作成すると、コインをループするときに制限時間を超えたコインを取り除くことができます。 –

+0

コインは、硬貨やコインが落ちてしまうまでコインが出るようにしたいゲームを終了する。すべてのコインのクラスを作ることは、正しいことではないようです。 –

+0

個々のコインのクラスを作成することによって、1つのコインを作成して1つのコインを作成し、このクラスのインスタンスのリストを現在のコインとして作成することを意味します。 –

答えて

1

コインにタイマーを追加するだけです。

現在、あなたはコインを表すべきであるクラス​​を持っています。しかしあなたはそこにあなたの硬貨を持っています。 OOPプログラミングの力は、コインを抽象化することです。コインが自分のオブジェクトであることを確認し、この光沢のある小さなオブジェクトのクラスだけを作成します。

public class Coin { 

    //Fields specific for the coin 
    private Vector2 position; 
    private int worth; 
    private Sprite sprite; 

    //Fields for the timer, since this coin dissapears it should hold it's own self destruct timer 
    public float timeAlive = 0; 
    public float despawnTime = 2; 

    public Coin(Vector2 position, int worth, Sprite sprite, float despawnTime) { 
     this.position = position; 
     this.worth = worth; 
     this.sprite = sprite; 
     this.despawnTime = despawnTime; 
    } 

    //Since we hold a list somewhere else of the objects represented by this class we should be able to delete them from the list when the time is up. 
    public boolean isAlive() 
    { 
     return timeAlive < despawnTime; 
    } 

    //I like to abstract update and draw from render. In update we put the logic, which in this case is updating it's time alive. 
    public void update() 
    { 
     timeAlive += Gdx.graphics.getDeltaTime(); 
    } 

    public void draw(SpriteBatch batch) 
    { 


     //Draw your object 
    } 
} 

public class SomethingHoldingCoins { 

    //A list to hold our coins 
    List<Coin> coins = new ArrayList<Coin>(); 

    //A timer system to spawn coins 
    private int spawnTime = 4; 
    private int timer = 0; 

    public void update() 
    { 
     //Increment timer by the time since last frame 
     timer += Gdx.graphics.getDeltaTime(); 

     //check if timer past the spawn time 
     if (timer >= spawnTime) 
     { 
      //Add a coin to the list 
      coins.add(new Coin(somePosition, 100, coinSprite, 2)); 
      //subtract spawntime from timer 
      timer -= spawnTime; 
     } 

     //iterate over the list of coins to do stuff like drawing and removing despawned coins 

     for (Iterator<Coin> iterator = coins.iterator(); iterator.hasNext()) 
     { 
      Coin coin = iterator.next(); 
      //Update the coin 
      coin.update(); 
      //Check if it is still alive 
      if (!coin.isAlive()) 
      { 
       //remove the coin from the list since it is despawned anyway, then continue with the next iteration 
       iterator.remove(); 
       continue; 
      } 

      coin.draw(spriteBatch); 
     } 
    } 
} 

瞬間

は、我々はそれを起動 new Coin(...)を実行して、コインを作成し、タイマーがいる限り、我々はそれに update()各フレームを呼び出しておくとして実行されます。したがって、コインを保持しているオブジェクトでは、リストを作成し、スポーンしたり、更新したりします。恐らく、あなたのマップは少なくとも Marioのコインを置くのに適した場所です。マップは coinsです。

すべてをオブジェクトとして考えます。私はコインが価値を持つかもしれないので、価値ある価値をコインの中に入れています。それはあなたがやろうとしていることと、あなたのクラスがどれほど大きくて可読なのかに依存します。簡単なドライビングゲームのためのクラスCarはおそらくその中にWheelsを持っているはずです。しかし、はるかに高度なゲームはChassisを車に入れ、ChassisSuspensionになり、サスペンションは最終的にWheelsになります。だから、それぞれが独自の機能を持つことができます。これにより、人間のロジックとはるかに小さなクラスのために、コードをより読みやすくします。

+0

コインが延長/変更されていても、スポーンの時間をコインにマップすることができない場合でも、これは優れた解決策ですが、私は同意します。 – heisbrandon

+0

@heisbrandon彼はCoinクラスを持っているが、彼はコインのように使うことはないので、私は彼をかなり見せている。そのような小さなクラスであり、すでに長方形の配列を混乱させています。コインは単に抽象化されるべきです、それはそれ自身の矩形、位置、値などとタイマー機能です。読みやすさはすべてです。 – Madmenyo

-1

ScheduledThreadPoolExecutorを見ましたか?

私はあなたがする必要があることを達成すると思う方法scheduleWithFixedDelayを持っています。

別のスレッドがリストから項目を削除している間に反復処理を行っていて、その動作が定義されていない場合は、反復子の削除によってConcurrentModificationExceptionがスローされる可能性があるので注意が必要です。しかし、このようなスレッド化されたソリューションを追求しているなら、オーバーラップをチェックする別のスレッドを持つことができます。

また、私は、私はArrayインターフェイスに精通していませんが、任意のインデックスオブジェクトを削除するいくつかの方法があると思います。

ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1); 
executor.scheduleWithFixedDelay(new CoinRemover(coin, coins), 0, 2, TimeUnit.SECONDS); 

class CoinRemover implements Runnable { 
    Coin coin; 
    List<Coin> coins; 

    public CoinRemover(Coin coin, List<Coin> coins) { 
     this.coin = coin; 
     this.coins = coins; 
    } 

    @Override 
    public void run() { 
     coins.remove(coin); 
    } 
} 
+0

私は前にそれを見たとは思わない。イマはそれを見て、ありがとう! –

+0

@AntonHolm不要なスレッドは使用しないでください。彼はコインの状態を変える可能性が最も高く、別のスレッドで起こったときには、ファンに当たってしまうことがあります。 – Madmenyo

+0

@ menno-gouw別のスレッドで硬貨の値を読み書きしている場合は、少なくともオブジェクトがスレッドセーフであることを確認する必要があります。しかし、単に別のスレッドでコレクションを変更している場合は、それらのオブジェクトの状態とその変更可能性は無関係です。 – heisbrandon

関連する問題