- ベストアンサー
数字を動くプログラムについて
番組の最後に流れるスタッフロールのように 数字が左から右に動くプログラムを以下のようなかんじで作りました。 class MyDrawPanel extends JPanel{ public void paintComponent(Graphics g){ g.setColor(Color.WHITE); g.fillRect(0,0,this.getWidth(),this.getHeight()); g.setColor(Color.BLACK); g.setFont(font); g.drawString("12345",x,y); } } というコンポーネントを x=-200; for(int i=0;i<500;i++){ x++; drawPanel.repaint(); try{ Thread.sleep(1); }catch(Exception ex){ } }というふうに動かしました。 ふたつ質問があります。 1.異なるスペックのパソコンで実行してみたところ表示(動く)スピードに大きな差が出ました。 これはしょうがないことなのでしょうか?(解決する方法があるのでしょうか?) 2.インクリメントをする際にThread.sleepで1msec休止させていますが これをもっと短くすることはできないのでしょうか? 動くスピードが遅いのでもう少し速くしたいです。 (xのインクリメントをx+=2でやってみましたがこれくらいしか方法はないのでしょうか?)
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
こんばんは。 1msごとのrepaintは、少しやりすぎのような気がします。 せいぜい10msごとくらいで十分なんじゃないでしょうか? 人間の目はそれほど優秀ではないですから。 で、ハードウェアの性能に左右されずに一定の速度を守りたい場合は、sleepメソッドよりjavax.swing.Timerクラスを使ったほうがよいと思います。 大げさに考えてみて、reapaintにかかる時間が、仮に高性能ハードウェアが2ms、低性能ハードウェアが6msかかったと仮定して、sleep(10)を使うと、 高 repaint() 2ms ↓ sleep(10) 10ms ↓ repaint() 2ms ↓ sleep(10) 10ms フレームの間は12msになります。 低 repaint() 6ms ↓ sleep(10) 10ms ↓ repaint() 6ms ↓ sleep(10) 10ms フレームの間は16msかかります。 速度が変わってしまいます。 タイマーを使えば、 高 タイマー ↓10ms イベント→repaint() 2ms ↓10ms イベント→repaint() 2ms フレームの間は10msになります。 低 タイマー ↓10ms イベント→repaint() 6ms ↓10ms イベント→repaint() 6ms やはりフレームの間は10msです。 この場合、性能が低すぎてrepaint()に10ms以上かかってしまうとイベントキューにイベントがたまってしまい、結局、遅れてしまいますが、少なくとも速すぎて困ってしまうってことはないかと思います。
その他の回答 (1)
- Bonjin
- ベストアンサー率43% (418/971)
>これはしょうがないことなのでしょうか?(解決する方法があるのでしょうか?) しょうがないと言えばしょうがないですね。1msecはやりすぎです。コンピュータをフル稼働させていることと同じですのでスペックの違うコンピュータでは差が出るのでしょう。 そんなに速く更新したところで人間の目には追い切れません。通常のビデオで15フレーム/secですし、PC画面のリフレッシュレートも60Hz程度です。また人間の目は30Hzを超えると目で追いきれなくなるらしいです。それらを踏まえて、移動距離と更新間隔を調整してみてはいかがでしょうか? 処理負荷が軽くなれば画像の動きもちゃんと見えるようになるでしょう。 >これをもっと短くすることはできないのでしょうか? 利用しているのはThread#sleep(long)ですが、Thread#sleep(long,int)というメソッドもあります。