ここまでの整理
きりがよいのでここらで整理します。いくつか変更点をまとめておきます。
パネルサイズ変更
パネルのサイズを少し大きくしました。それに合わせてメッセージウィンドウの表示位置も調整しています。
// パネルサイズ public static final int WIDTH = 640; public static final int HEIGHT = 640;
マップチップの大きさは32ピクセルx32ピクセルですので1画面に20チップx20チップ入ることになります。これに合わせてマップも少し大きくしています。あまりよくない制限なのですがマップは20x20以上の大きさにしておかないとエラーになります。
アクティブレンダリング使用
今まではpaintComponent()で描画処理していたのですがアクティブレンダリングに変更しています。まあ見た目にはほとんどわかりませんが。ゲームループはすごくすっきりして気持ちがいいです。
public void run() { while (true) { // キー入力をチェック checkInput(); // ゲーム状態を更新 gameUpdate(); // レンダリング gameRender(); // 画面に描画 paintScreen(); ・・・ } }
休止時間を少し正確に
今までは50fpsを実現するために休止時間を問答無用に20ms(1000/50)とってたんですが、実際はゲーム状態の更新などが入るため1フレームが20ms以上になってました。正確に1フレーム20msで処理できるように少し改造しています。ゲーム状態の更新時間を20msから引いて残りの時間を休止しています。処理が重くなった場合でも最低5msだけ休止します。
(注)System.currentTimeMillis()の精度が低いため正確に50fpsになりません。ただRPGなんでfpsにそんなに気を使わなくてもいいでしょう。
// 1フレームの時間(50fpsなので1フレーム20ms) private static final int PERIOD = 20; public void run() { long beforeTime, timeDiff, sleepTime; beforeTime = System.currentTimeMillis(); while (true) { ・・・ timeDiff = System.currentTimeMillis() - beforeTime; sleepTime = PERIOD - timeDiff; // このフレームの残り時間 // 最低でも5msは休止を入れる if (sleepTime <= 0) { sleepTime = 5; } try { Thread.sleep(sleepTime); } catch (InterruptedException e) { e.printStackTrace(); } beforeTime = System.currentTimeMillis(); } }
BufferedImageの使用
今まではキャラクターやマップチップにImageを使ってましたがBufferedImageを使うように変更します。BufferedImage のロードはImageIOを使います。
// イメージ private static BufferedImage charaImage; private void loadImage() { // キャラクターのイメージをロード try { charaImage = ImageIO.read( getClass().getResource("image/chara.gif")); } catch (IOException e) { e.printStackTrace(); } }
サウンドエンジン改良版の使用
名前でMIDIやWAVEが再生できるサウンドエンジン改良版(2005/12/10)を使うように修正してます。それにともないMapクラスへはBGMを名前で渡してます。