2016-09-09 11 views
1

私は基本的なJavaゲームをプログラミングしていますが、問題があります。 私が試してみるたびに、10秒待ってもプログラムが正しく動作しなくなります。私はDrawableというクラスを作りました。これはpaintの機能を持っています。このpaint関数は、コンストラクタで指定された特定の領域に矩形を描画します。 そして私はarraylist(ランダムに、別のスレッドで追加された)のすべてのdrawables上で反復するスレッドを持って、ちょうど彼らのxに1を引く。正しく動作しなくなると、キャラクターはジャンプしてすべてのアニメーションを実行できますが、ドロワーブルは動かなくなります。最初に私はこれがConcurrentModificationExceptionエラーを与えたかもしれないと思ったが、それはコンソールにそれを印刷しなかった。 今私は本当に何をすべきか分かりません。 ここで私はDrawablesを追加します。私のJavaプログラムが予期せず正しく動作しなくなる

ここ
Thread t2 = new Thread(new Runnable() { 
    @Override 
    public void run() { 
     while (Game.isPlayingGame) { 
      try { 
       Thread.sleep((long) (Math.random()*2000)); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      obstacles.add(new Drawable(
       Constants.WIDTH, 
       (int) (Constants.HEIGHT/2), 
       Constants.WIDTH - 100, 
       (int) (Constants.HEIGHT/2) - 100, 
       Color.BLUE)); 
     } 
    } 
}); 
t2.start(); 

私はDrawablesを移動:

Thread t = new Thread(new Runnable() { 
    @Override 
    public void run() { 
     while (Game.isPlayingGame) { 
      try { 
       Thread.sleep(1); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      for (Drawable d : obstacles) { 
       d.x -= 1; 
       d.x2 -= 1; 
       if (d.x2 < 0) { 
        obstacles.remove(d); 
       } 
      } 
     } 
    } 
}); 
t.start(); 

塗装方法:事前に

@Override 
public void paint(Graphics g) { 
    super.paint(g); 
    floor.paint(g); 
    Graphics2D g2d = (Graphics2D) g; 
    AffineTransform ant = g2d.getTransform(); 
    g2d.rotate(Math.toRadians(rotation), 
       character.x - Constants.characterSize/2, 
       character.y - Constants.characterSize/2); 
    character.paint(g); 
    g2d.setTransform(ant); 
    for (Drawable d : obstacles) { 
     d.paint(g); 
     System.out.println(rotation_down); 
     if (!rotation_down) { 
      if (!character.onCollision(floor)) { 
       character.y += (int) gravityAccel; // gravity 
       character.y2 += (int) gravityAccel; // gravity 
       gravityAccel += 0.1; 
      } else { 
       Screen.canJump = true; 
       gravityAccel = 0; 
      } 
     } 

    } 
    repaint(); 
} 

感謝。

+0

また、基本的に画面の大きさ( 'WIDTH'と' HEIGHT')を格納する 'Constants'クラスもあります。 – JHacking

+2

ヒント:ここにたくさんのコードを投稿しています。これはマルチスレッドに関するものです。あまりにも多くの人があなたのコードの潜在的なバグを見つけるためにそれを実際にすべて読んでいないならば、驚かないでください。本質的には、これを** minimal **の例に減らすことができるかどうか試してみてください。最初のスターターとして。 **イベントディスパッチャスレッド**について読んでみたい。間違ったことをすると(例えば、UIが簡単にフリーズして反応しなくなるなど) – GhostCat

+0

OK、最小化しようとします – JHacking

答えて

1

適切な同期は、Drawableの正確な内部構造によって異なります。 CopyOnWriteArrayListも使用します。描画領域クラスは、X 1およびX 2の減少は、アトミックであるべきであり、少なくとも塗料()メソッドと同期:

synchronized moveToLeft() { 
    x-=1; 
    x2-=1; 
} 

しかし、X2 < 0のオブジェクトを持っている意味がないが、これは別個です討論。

また、このような何かを

synchronized getX2() { 
    return x2; 
} 

と2番目のスレッドで持ちたいでしょう:

if (d.getX2 == 0) { 
    obstacles.remove(d); 
} 
else { 
    d.moveToLeft(); 
} 

最初であるあなたがそれを行う場合は、他の方法で回避のチェックを行う理由x2が既に-1である場合には、obstacles.remove(d)はまだ呼び出されておらず、d.paint()が呼び出されます。これは、paint()メソッドが負の座標を処理できない限り、問題を引き起こす可能性があります。

関連する問題