人工知能に関する断創録

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



お城を建てる

前回、勇者はすみっこでいじけてたのでお城を建ててあげましょう。というわけで今回はマップの作り方です。ここで書くコードは拡張性をまったく考慮してません。本当はマップ専用のクラスを作って処理を分離するところですがそれはもっと後の回で取り上げます。

rpg02.jar

マップの構造

今回作るマップは床と壁の画像は、

f:id:aidiary:20100306231940g:plain f:id:aidiary:20100306231946g:plain

を使いましょう。

コード中でマップを定義しているのは、mapという15×15の二次元配列です。配列の1つの要素がマップの1マスにあたるので15マス×15マスのマップです。

    // マップ 0:床 1:壁
    private int[][] map = {
        {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
        {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
        {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
        {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
        {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
        {1,0,0,0,0,1,1,1,1,1,0,0,0,0,1},
        {1,0,0,0,0,1,0,0,0,1,0,0,0,0,1},
        {1,0,0,0,0,1,0,0,0,1,0,0,0,0,1},
        {1,0,0,0,0,1,0,0,0,1,0,0,0,0,1},
        {1,0,0,0,0,1,1,0,1,1,0,0,0,0,1},
        {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
        {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
        {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
        {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
        {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} };

目を凝らしてよーく見てください。0は床で1は壁です。なんとなくマップに見えるでしょ?今回は床と壁ですので0と1しか使いませんが、水とか木のマップチップも使いたければ2とか3とか使っても大丈夫です。ただ、配列を0とか1とか手で打ち込んで書くのはむちゃくちゃ面倒です。後でお絵かきするようにマップが作れるマップエディタも作ってみます。

このように0と1のマップをイメージで表示するための処理は下のようになります。

    private void drawMap(Graphics g) {
        for (int i = 0; i < ROW; i++) {
            for (int j = 0; j < COL; j++) {
                // mapの値に応じて画像を描く
                switch (map[i][j]) {
                    case 0 : // 床
                        g.drawImage(floorImage, j * CS, i * CS, this);
                        break;
                    case 1 : // 壁
                        g.drawImage(wallImage, j * CS, i * CS, this);
                        break;
                }
            }
        }
    }

ROWは行数15、COLは列数15、CSはマップチップのサイズ32です(下の図を見てください)。「15×15のマップ」と書いた場合は前が行数で後が列数とします。

f:id:aidiary:20100306231944g:plain

マップ配列はmap[行][列]です。マップ内の値(0か1)に応じてマップチップを画面に描いています。ここで注意しなければならないのはマップの行・列と画面座標の対応関係です。i行j列のマップチップの左上の座標は(j*CS, i*CS)となります(上図参照)。イメージを描画するときは画面上の座標を使う必要があるので

    g.drawImage(floorImage, j * CS, i * CS, this);

となります。jが先です。

どうです、なかなか立派なお城ができたでしょう?出口はありませんが(笑)