プレイヤーの移動
キー入力でプレイヤーが移動するところまで作ります。インベーダーゲームではプレイヤーは左右にしか移動できないので←キーと→キーを使います。
プレーヤークラス
まずはプレイヤーの属性と機能をまとめたPlayerクラスを作ります。プレイヤーの属性として
private static final int SPEED = 5; // 移動スピード private int x; // プレイヤーの位置(x座標) private int y; // プレイヤーの位置(y座標) private int width; // プレイヤーの幅 private int height; // プレイヤーの高さ private Image image; // プレイヤーの画像
などが考えられます。スピードは1回のmove()メソッドで移動する距離です。大きいほどプレイヤーは速く移動します。
プレイヤーを移動させたいのでmove()メソッドを実装します。
/** * プレイヤーを移動する * * @param dir 移動方向 */ public void move(int dir) { if (dir == LEFT) { x -= SPEED; } else if (dir == RIGHT) { x += SPEED; } // 画面の外に出ていたら中に戻す if (x < 0) { x = 0; } if (x > MainPanel.WIDTH - width) { x = MainPanel.WIDTH - width; } }
まあ簡単です。引数のdirの方向によってプレイヤーのX座標を変えてます。プレイヤーが画面外に出ないようにする処理も書いています。
ImageIconを使ったイメージのロード
イメージをロードするloadImage()を見てください。
/** * イメージをロードする * */ private void loadImage() { // プレイヤーのイメージを読み込む // ImageIconを使うとMediaTrackerを使わなくてすむ ImageIcon icon = new ImageIcon(getClass().getResource( "image/player.gif")); image = icon.getImage(); // 幅と高さをセット width = image.getWidth(panel); height = image.getHeight(panel); }
イメージを表示する(2004/10/9)と比較してみてください。今回はImageIconクラスを使ってイメージをロードし、ImageIconのgetImage()を使ってImageオブジェクトを取り出しています。このように書くとMediaTrackerを使う必要がなくなります。ImageIconは自動的に MediaTrackerを使ってくれるからです。こっちの方が簡潔な書き方なので以後使っていきます。
ゲームループ
最後にゲームループを見てみます。ゲームループはスレッドとして実装しています。
/** * ゲームループ */ public void run() { while (true) { // 押されているキーに応じてプレイヤーを移動する // 何も押されていないときは移動しない if (leftPressed) { player.move(LEFT); } else if (rightPressed) { player.move(RIGHT); } // 再描画 repaint(); // 休止 try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } } }
押されたキーに応じてplayerを移動させています。leftPressedとrightPressedはboolean型の変数です。キーが押されていたらtrue、押されていなかったらfalseになります。
sleep()を使って20ミリ秒間休止しています。つまり、1000÷20で50FPSとなります。もっと厳密なFPSを実現する方法はあとで取り上げます。