読者です 読者をやめる 読者になる 読者になる

人工知能に関する断創録

人工知能、認知科学、心理学、ロボティクス、生物学などに興味を持っています。このブログでは人工知能のさまざまな分野について調査したことをまとめています。最近は、機械学習、Deep Learning、Kerasに関する記事が多いです。



イメージを使う

ここでイメージを使ってもっとゲームっぽくしてみます。イメージを使う詳しい解説はイメージを表示するやImageIconを使ったイメージのロードにあるのでそっちを見てください。

mariolike05.jar

マップにイメージを使う

まず使うイメージを用意します。今回はブロックブロックのイメージだけ使います。背景を真っ黒に塗りつぶしてブロックがあるところだけブロックを描画することにします。マップクラスのloadImage()でイメージをロードしています。

    /**
     * イメージをロードする
     */
    private void loadImage() {
        ImageIcon icon = new ImageIcon(
                             getClass().getResource("image/block.gif"));
        blockImage = icon.getImage();
    }

ImageIconを使うとMediaTrackerを使う必要がないので楽です。実際にイメージを描画しているのはdraw()です。

    for (int i = firstTileY; i < lastTileY; i++) {
        for (int j = firstTileX; j < lastTileX; j++) {
            // mapの値に応じて画像を描く
            switch (map[i][j]) {
                case 1 : // ブロック
                    g.drawImage(blockImage, tilesToPixels(j) + offsetX,
                                tilesToPixels(i) + offsetY, null);
                    break;
            }
        }
    }

fillRectangle()の代わりにdrawImage()を使うだけですね。

プレイヤーにイメージを使う

プレイヤーのイメージはこれを使いましょう。

f:id:aidiary:20091017223618g:plain

4つありますね。上は右へ移動しているとき、下は左へ移動しているときに使うイメージです。それぞれ2枚ずつあるのはアニメーションのためです。よく見ると微妙に形が違います。この2枚を順に切り替えると動いているように見えます。

PlayerクラスのloadImage()でイメージをロードしています。マップとほとんど同じです。

    /**
     * イメージをロードする
     */
    private void loadImage() {
        ImageIcon icon = new ImageIcon(getClass().getResource(
                "image/player.gif"));
        image = icon.getImage();
    }

プレイヤーの描画はマップより複雑です。RPGの勇者はがにまたが直ったと基本的に同じなので詳しくはそっちを見てください。RPGでは4方向あったのですがアクションでは2方向でよいので少し簡単です。

プレイヤーはどっちの方向を向いているかを表すdirとアニメーションを切り替えるcountという2つの変数を持っています。

    // 向いている方向
    private int dir;
    // アニメーション用カウンタ
    private int count;

dirはRIGHTかLEFTの値を取れます。

    // 方向
    private static final int RIGHT = 0;
    private static final int LEFT = 1;

プレイヤーが右へ移動中はdirがRIGHTになり、プレイヤーが左へ移動中はdirがLEFTになります。

    /**
     * 左に加速する
     */
    public void accelerateLeft() {
        vx = -SPEED;
        dir = LEFT;
    }

    /**
     * 右に加速する
     */
    public void accelerateRight() {
        vx = SPEED;
        dir = RIGHT;
    }

プレイヤーを描画するときはdirの値を元に左向き、右向きのイメージのどっちを描画するわけです。もう1つのcountは別スレッドを使って0と 1の値が300ミリ秒ごとに切り替わります。countの値を元に描画するイメージを切り替えるわけです。実際にイメージを描画してるのはdraw()です。

    /**
     * プレイヤーを描画
     * 
     * @param g 描画オブジェクト
     * @param offsetX X方向オフセット
     * @param offsetY Y方向オフセット
     */
    public void draw(Graphics g, int offsetX, int offsetY) {
        g.drawImage(image,
                (int) x + offsetX, (int) y + offsetY, 
                (int) x + offsetX + WIDTH, (int) y + offsetY + HEIGHT,
                count * WIDTH, dir * HEIGHT,
                count * WIDTH + WIDTH, dir * HEIGHT + HEIGHT,
                null);
    }

イメージは4つつながっているためdirとcountの値によって表示する範囲を指定しています。