2011-06-28 18 views
1

Sup guys。このように、ゾンビは私が作ったクラスであり、私はArrayListの上でそれらを処理しています:Javaゲーム:ArrayListとIteratorとThread

私は、Javaクラス用の簡単なゾンビゲームを書いていると私は小さな問題で打ってる

horda.add(new Zumbi((int)(Math.random()* 750), 0)); 

ここで、引数は画面上のゾンビのスポーンの位置を表します。あなたがそれらをクリックする必要があり、それらを殺すために、非常に単純な、イテレータとの衝突をチェックし、ここに:

java.util.Iterator<Zumbi> itr = horda.iterator(); 
     while (itr.hasNext()){ 
      Zumbi z = itr.next(); 
      if (tiroPos.x > z.zumbiPos.x && 
       tiroPos.x < z.sprite.getWidth() + z.zumbiPos.x && 
       tiroPos.y > z.zumbiPos.y && 
       tiroPos.y < z.sprite.getHeight() + z.zumbiPos.y){ 

       //things to do when it hits  
      } 

tiroPosは、プレイヤーの撮影座標を保持しているポインタです。事は:時にはゾンビを打つときに起こるはずのことは起こっていない。 Iteratorが十分速く動作していないか、または他の何かが実行されていないことが原因であるかどうかはわかりません。

ゾンビごとに異なるスレッドを作っているかもしれませんが、それはコードを変更する基本的な方法であり、役に立たないとその時間をすべて失うことはありません。

だから、どんな考えですか?

//編集:忘れてしまったこと:他のメソッドでオブジェクトを描画する方法がわからず、ArrayListにアクセスしようとしたときにオーバーライドされたpaintメソッドの衝突をチェックしていますSync'd ArrayList)を別のスレッドで使用すると、共修飾の例外が発生しました。

// EDIT2: 問題は解決されました。

MouseListenerによって渡されたMouseEventオブジェクトは、マウスポインタの下端の座標を渡します。だから実際は衝突問題ではなく、より多くの数学問題でした。私はclickPoint.y- 25を正しいものにするためにそれを比較しなければなりませんでした。

お手数をおかけしていただきありがとうございます。

+0

クリックするたびにイテレータを最初にリセットしますか? –

+0

実際に別のスレッドでユーザー入力を収集していますか? – Caspar

+0

編集セクションをお読みください。これを忘れてしまった。 – Naro

答えて

0

マルチスレッド化は非常に手助けとなるだけで、処理能力の大きさに依存しています。

一般的に、衝突検出には四分木が使用されているため、代替として検討する価値があります。心に留めておくべき

+0

私は[クワッドツリー](http://en.wikipedia.org/wiki/Quadtree)を実装することが初心者のJavaプログラマが心配すべきものだとは確信していません;) – Caspar

+0

もちろん、そうではありません。しかし、それは衝突のために厳密に良いです。 :D –

2

2つのこと:

  1. あなたはそれを反復しながら、ArrayListのから項目を削除する必要がある場合は、イテレータのremove()メソッドを介してそれを行う必要があります。リスト自体を変更すると失敗します。

  2. 2つのスレッドがリストにアクセスしている場合は、Collections.synchronizedListでラップするか、別のデータ構造を選択する必要があります。

編集:あるスレッドでリストを変更している間に別のスレッドで繰り返しているようです。これにより、ConcurrentModificationExceptionが発生します。これを避ける最も簡単な方法は、リストの使用方法を両方のスレッドの同期ブロックで囲むことです。例:

synchronized(horda) { 
    iterator = horda.iterator(); 
    while (iterator.hasNext()) { 
     z = iterator.next(); 
     ... 
    } 
} 

別の方法としては、反復する前にリストのクローンを作成したり、そのようなCopyOnWriteArrayListなどjava.util.concurrentのから特別なリストの実装の1つを使用することです。

+0

これらの両方を行った。奇妙なことに私は例外を投げつけ続けている。 – Naro

+0

両方のアクセスを 'synchronized(horda)'でラップしましたが、それでも私は異常な動作をします。 – Naro

+0

どのような異常な動作ですか? – ataylor

0

私の意見ではゾンビを繰り返し処理するためにfor-eachループを使用することをお勧めします。このようなタスクを実行するために導入されたので、使用することもできます。

+0

for-eachループは素晴らしく、すべてですが、イテレータの 'remove()'にアクセスする必要があるなら、あなたは運が悪いです。@ Naroはヒットしたゾンビを "殺す"ことを望んでいるので、 for-each'ループは彼にとっては適切ではない。 – Caspar

0

私は、プレーヤーがウィンドウをクリックすることによって「撃つ」と仮定しているので、tiroPosはクリックのx、y座標です。

この場合、ユーザーがたくさんクリックしたときにクリックしたときにゾンビが表示されない場合があります。最後の「ショット」のみが保存されている可能性がありますtiroPos

適切なSystem.out.println()呼び出しをforループで追加し、別の呼び出しでtiroPosを追加することでこれをテストできます。 forループの途中でtiroPosが変更されると、ゾンビが撮影されない理由があります。

この場合、最新のクリックではなく、クリックのリストの保存を開始する必要があります。

編集:これで、同時変更の例外は修正されません。

+0

@ataylorのヒントを投稿して以来、私は例外をスローしていませんが、私はまだこの奇妙な動作をしています。私はそれらの 'System.out.println()'をさらにデバッグのために試してみます。 – Naro