人工知能に関する断創録

このブログでは人工知能のさまざまな分野について調査したことをまとめています(更新停止: 2019年12月31日)

プレイヤーの移動

キー入力でプレイヤーが移動するところまで作ります。インベーダーゲームではプレイヤーは左右にしか移動できないので←キーと→キーを使います。

invader01.jar

プレーヤークラス

まずはプレイヤーの属性と機能をまとめた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を実現する方法はあとで取り上げます。