宝箱の蓋を開ける

BG に設定した宝箱を探し出して、宝物を取り出します。

下のリンクをクリックすると、このページで作成したアプレットが実行されます。
宝箱の蓋を開ける

前田稔の超初心者のプログラム入門

プログラムの作成

  1. メモ帳などでタイプして rpgtakara.java の名前で保存して下さい。
    Applet はサーバーにアップロードすることが前提なので、ファイル名やクラス名を小文字で統一しています。
    //★ 宝箱の蓋を開ける    前田 稔
    //   appletviewer rpgtakara.htm
    import java.applet.*;
    import java.awt.*;
    import java.io.*;
    import java.net.URL;
    import javax.imageio.ImageIO;
    import java.awt.event.*;
    
    public class rpgtakara extends Applet implements Runnable, KeyListener
    {   // Back Ground
        bg          obj;                        // BG Class
        Point       off= new Point();           // BG のスクロール値
        // Character
        card        cat;                        // card Class(cat の描画)
        int         key_t[] = { 0,0,0,0 };      // UP, RIGHT, DOWN, LEFT
        Point       pos= new Point(320,512);    // cat の座標(4の倍数)
        int         dir= 0, num= 0;             // cat の向きとアニメ
        long        animeTime= 0;               // アニメーションのタイミング
        // Game Window
        Rectangle   win= new Rectangle(0,0,800,576);
        // Double Buffer
        Dimension   size;
        Image       back= null;
        Graphics    buffer;
    
        // Initialize
        public void init()
        {   obj = new bg(getCodeBase().toString(),"javabg.txt");
            cat = new card(getCodeBase().toString() + "chr47.gif",32,32);
            obj.LoadAT(getCodeBase().toString(),"javabgatt.txt");
            obj.SetRect(win);
            off.y= obj.scrollMax.y;
            setBackground(Color.gray);
            size = getSize();
            back= createImage(size.width, size.height);
            if (back==null) System.out.print("createImage Error");
            addKeyListener(this);
            Thread t = new Thread(this);
            t.start();
        }
    
        // Paint Method
        public void paint(Graphics g)
        {   if (back==null)     return;
            buffer= back.getGraphics();
            if (buffer==null)   return;
            size = getSize();
            buffer.setColor(getBackground());
            buffer.fillRect(0, 0, size.width, size.height);
            obj.MapView(buffer,off.x,off.y);
            cat.View(buffer,dir*2+num,pos.x,pos.y);
            g.drawImage(back,0,0,this);
        }
    
        // Message Loop
        public void run()
        {   long    nowTime,drawTime;
            nowTime= System.currentTimeMillis();
            drawTime= nowTime+100;
            while(true)
            {   nowTime= System.currentTimeMillis();
                if (drawTime<nowTime)
                {   drawTime= nowTime+30;
                    if (action())   repaint();
                }
            }
        }
    
        // キャラクタの移動
        public boolean action()
        {   int     i;
            long  nowTime = System.currentTimeMillis();
            if (animeTime < nowTime)
            {   animeTime= nowTime+200;
                num^= 1;
            }
            eventcheck();       //イベントのチェック
            // MAP の境界まで動く
            i= 4;
            if ((pos.x+off.x)%32!=0 && (dir==1 || dir==3))  i= dir;
            if ((pos.y+off.y)%32!=0 && (dir==2 || dir==0))  i= dir;
            // キーが押されているか
            if (i>3)
            {   for(i=0; i<4; i++)
                {   if (key_t[i]==1)
                    {   dir= i;
                        if (obj.GetAtt(i,pos,off)>0) break;
                    }
                }
            }
            if (i>3)    return false;
            // 座標の更新
            switch(i)
            {   case 0:     // UP
                    if (pos.y>obj.center.y) pos.y-= 4;
                    else    if (off.y>=4)   off.y-= 4;
                    else    pos.y-= 4;
                    break;
                case 1:     // RIGHT
                    if (pos.x<obj.center.x) pos.x+= 4;
                    else    if (off.x+4<obj.scrollMax.x)  off.x+= 4;
                    else    pos.x+= 4;
                    break;
                case 2:     // DOWN
                    if (pos.y<obj.center.y) pos.y+= 4;
                    else    if (off.y+4<obj.scrollMax.y)  off.y+= 4;
                    else    pos.y+= 4;
                    break;
                case 3:     // LEFT
                    if (pos.x>obj.center.x) pos.x-= 4;
                    else    if (off.x>=4)   off.x-= 4;
                    else    pos.x-= 4;
                    break;
            }
            return true;
        }
    
        // イベントのチェック
        public void eventcheck()
        {   int     wat,wx,wy;
            wat= obj.GetAtt(pos,off);
            switch(wat)
            {   case 2:     //宝箱の蓋を開ける
                    wx= obj.GetX(pos.x,off.x);
                    wy= obj.GetY(pos.y,off.y);
                    obj.TT[wy][wx]++;
                    obj.TT[wy-1][wx]++;
                    System.out.println("宝箱を見つけた!");
                    return;
            }
        }
    
        // KeyEvent Listener
        public void keyPressed(KeyEvent e)
        {   switch(e.getKeyCode( ))
            {   case KeyEvent.VK_UP :   key_t[0]= 1;  break;
                case KeyEvent.VK_RIGHT: key_t[1]= 1;  break;
                case KeyEvent.VK_DOWN : key_t[2]= 1;  break;
                case KeyEvent.VK_LEFT : key_t[3]= 1;  break;
            }
        }
        public void keyReleased(KeyEvent e)
        {   switch(e.getKeyCode( ))
            {   case KeyEvent.VK_UP :   key_t[0]= 0;  break;
                case KeyEvent.VK_RIGHT: key_t[1]= 0;  break;
                case KeyEvent.VK_DOWN : key_t[2]= 0;  break;
                case KeyEvent.VK_LEFT : key_t[3]= 0;  break;
            }
        }
        public void keyTyped(KeyEvent e) { }
    }
    
    //★ 画像を切り分ける class card は Java Applet カードゲームと同じです。
    class card extends JApplet
    {   private Image   Img;            // CARD Image
          ・・・
    }
    
    //★ BG Object Class は、前回の「TEXT ファイルを使う」と同じです。
    class bg extends Applet
    {   String  Imgfile;        // image file
          ・・・
    }
    
  2. Java Applet を起動する HTML(rpgtakara.htm) ファイルです。
    <html>
      <body>
        <h3>宝箱の蓋を開ける</h3>
        <applet code="rpgtakara.class" width="800" height="576">
        </applet>
      </body>
    </html>
    
  3. BG(背景画像)を定義した TEXT 形式のファイル(javabg.txt)です。
    私が作成した MapEditor を使って作成したファイルです。
    //Map  Ver 3.2  前田 稔
    //JavaBG.gif
    //  25,   40,   32,   32,  Map の幅と高さ, Mapchip の幅と高さ
    103, 103, 103, 103, 103, 103, 103, 101, 11, 136, 153, 8, 55, 8, 8, 8, 56, 53, 8, 8, 8, 61, 8, 96, 8, 
    119, 119, 119, 119, 119, 119, 119, 101, 11, 109, 109, 8, 8, 54, 8, 8, 8, 8, 8, 8, 8, 61, 8, 112, 8, 
    103, 11, 11, 11, 11, 11, 11, 101, 11, 136, 153, 8, 52, 8, 56, 8, 8, 61, 61, 61, 8, 61, 169, 170, 8, 
    119, 11, 11, 11, 11, 11, 11, 101, 11, 152, 137, 8, 8, 53, 8, 8, 61, 8, 8, 8, 8, 61, 185, 186, 61, 
    103, 11, 11, 11, 11, 11, 11, 101, 11, 136, 153, 8, 54, 8, 8, 8, 61, 8, 54, 8, 54, 8, 56, 8, 8, 
    119, 11, 11, 11, 11, 11, 11, 101, 11, 152, 137, 8, 8, 8, 61, 61, 8, 8, 53, 8, 52, 8, 8, 56, 14, 
    11, 11, 165, 166, 11, 11, 11, 101, 11, 136, 153, 56, 8, 61, 8, 8, 56, 14, 8, 54, 8, 14, 8, 8, 54, 
    105, 106, 181, 182, 107, 108, 104, 101, 11, 152, 153, 8, 8, 61, 8, 8, 8, 8, 8, 8, 8, 8, 55, 8, 8, 
    121, 122, 11, 11, 123, 124, 120, 101, 11, 152, 144, 145, 189, 147, 148, 147, 148, 145, 148, 145, 146, 147, 146, 147, 148, 
    11, 11, 11, 11, 11, 11, 11, 11, 11, 152, 128, 129, 189, 131, 132, 129, 130, 129, 130, 129, 130, 131, 132, 129, 130, 
    146, 147, 146, 147, 146, 147, 148, 145, 145, 149, 153, 49, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
    129, 130, 131, 132, 129, 129, 130, 131, 130, 129, 151, 49, 3, 3, 3, 74, 160, 161, 162, 160, 161, 162, 74, 3, 3, 
    49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 90, 176, 177, 178, 176, 177, 178, 90, 3, 49, 
    29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 3, 3, 3, 3, 3, 3, 3, 3, 16, 16, 3, 3, 3, 3, 3, 
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 
    29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 3, 33, 48, 48, 48, 48, 48, 48, 3, 48, 48, 48, 48, 48, 48, 
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 33, 24, 24, 24, 24, 24, 24, 3, 24, 24, 24, 24, 24, 24, 
    28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 74, 74, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
    49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 90, 90, 24, 24, 24, 24, 24, 24, 3, 24, 24, 24, 24, 24, 24, 
    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
    139, 172, 172, 172, 172, 172, 172, 140, 3, 141, 3, 32, 24, 24, 24, 24, 24, 24, 3, 24, 24, 24, 24, 24, 24, 
    155, 3, 3, 3, 3, 3, 156, 3, 3, 157, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
    155, 3, 156, 3, 3, 3, 3, 3, 3, 157, 3, 32, 25, 25, 25, 25, 25, 25, 3, 25, 25, 25, 25, 25, 25, 
    155, 3, 3, 3, 3, 156, 3, 3, 3, 157, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
    155, 3, 3, 3, 3, 156, 3, 3, 3, 157, 3, 32, 25, 25, 25, 25, 25, 25, 3, 25, 25, 25, 25, 25, 25, 
    155, 3, 3, 156, 3, 3, 3, 3, 156, 157, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
    171, 172, 172, 172, 172, 172, 172, 172, 172, 173, 3, 32, 25, 25, 25, 25, 25, 25, 3, 25, 25, 25, 25, 25, 25, 
    3, 3, 3, 3, 3, 37, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
    134, 145, 146, 145, 146, 147, 148, 135, 32, 3, 3, 32, 26, 26, 26, 26, 26, 26, 3, 26, 26, 26, 26, 26, 26, 
    136, 64, 64, 64, 64, 64, 64, 137, 42, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
    152, 64, 64, 85, 64, 69, 64, 153, 32, 3, 3, 32, 26, 26, 26, 26, 26, 26, 3, 26, 26, 26, 26, 26, 26, 
    136, 64, 69, 70, 85, 64, 64, 137, 30, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 
    152, 64, 64, 64, 64, 64, 64, 153, 32, 3, 3, 32, 26, 26, 26, 26, 26, 26, 3, 26, 26, 26, 26, 26, 26, 
    150, 130, 131, 132, 130, 131, 132, 151, 42, 3, 3, 3, 48, 48, 48, 48, 48, 48, 3, 48, 48, 48, 48, 48, 48, 
    135, 43, 43, 43, 43, 43, 43, 43, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 134, 145, 145, 146, 147, 148, 
    144, 145, 135, 3, 3, 3, 3, 3, 3, 76, 3, 75, 3, 3, 3, 3, 3, 134, 145, 149, 80, 80, 64, 80, 80, 
    80, 80, 137, 49, 49, 49, 49, 49, 49, 92, 3, 91, 49, 49, 49, 49, 49, 136, 80, 80, 80, 80, 80, 84, 80, 
    80, 80, 153, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 152, 80, 80, 80, 81, 80, 80, 80, 
    64, 81, 144, 145, 145, 145, 146, 147, 135, 3, 3, 134, 145, 146, 147, 148, 145, 149, 80, 84, 80, 80, 80, 84, 80, 
    64, 64, 64, 80, 80, 80, 80, 80, 137, 3, 3, 136, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 
    
  4. Mapchip の属性を定義した TEXT 形式のファイル(javabgatt.txt)です。
    //JavaBG.gif の属性(0:通行不可  1:通行可  2:宝箱  3:ワープ 4:ドア)  12*16
      1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
      1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,
      1,  1,  0,  0,  0,  1,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,
      1,  0,  1,  1,  0,  1,  0,  1,  1,  0,  0,  0,  0,  0,  0,  0,
      0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  1,  0,  0,  0,  0,  0,
      0,  0,  0,  0,  0,  0,  0,  0,  0,  3,  0,  0,  0,  0,  0,  0,
      1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,
      2,  1,  2,  1,  0,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,
      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,
      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  3,  0,
      0,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  1,  0,
      0,  0,  0,  1,  1,  3,  3,  1,  1,  1,  1,  0,  0,  1,  1,  1,
    
  5. プロジェクトのフォルダーに、次のファイルを格納して下さい。
    ファイル名 説明
    rpgtakara.javaJava Applet のソースプログラムファイル
    rpgtakara.htm Java Applet を起動する HTML ファイル
    javabg.gif MapChip の画像ファイル
    javabg.txt BG(背景画像)を定義した TEXT 形式のファイル
    javabgatt.txt Mapchip の属性を定義した TEXT 形式のファイル
  6. rpgtakara.java をコンパイルして Class ファイルを作成して下さい。
    インターネットブラウザを起動して HTML ファイルから実行して下さい。
    矢印キーを操作して宝箱を探して下さい。

Main プログラムの説明

  1. このプログラムは TEXT ファイルを使う の続きです。
    BG に設定した Mapchip の属性を利用して、キャラクタを操作して宝箱を探します。
    Mapchip の属性は次のとおりです。
    1. 0:通行不可
      キャラクタが通ることが出来ないセルです。
    2. 1:通行可
      キャラクタが通ることが出来るセルです。
    3. 2:宝箱
      探し当てると蓋が開きます。
    4. 3:ワープ
      ダンジョンの入口/出口です。
  2. bg obj; は BG を描画する bg object class です。
    off は BG のスクロール値です。
    card cat; はキャラクタを描画する card object class です。
    key_t[] はキャラクタを矢印キーで操作するための領域です。
    pos はキャラクタの座標です。
    dir は進む方向(後,右,前,左)で、num は二枚の画像を切り替えながらキャラクタをアニメーションする領域です。
    animeTime はキャラクタのアニメーションのタイミングを取る領域です。
    win は Game Window の矩形領域です。
    size, back, buffer は描画の「チラツキ」を抑えるための Back Buffer です。
        public class rpgtakara extends Applet implements Runnable, KeyListener
        {   // Back Ground
            bg          obj;                        // BG Class
            Point       off= new Point();           // BG のスクロール値
            // Character
            card        cat;                        // card Class(cat の描画)
            int         key_t[] = { 0,0,0,0 };      // UP, RIGHT, DOWN, LEFT
            Point       pos= new Point(320,512);    // cat の座標(4の倍数)
            int         dir= 0, num= 0;             // cat の向きとアニメ
            long        animeTime= 0;               // アニメーションのタイミング
            // Game Window
            Rectangle   win= new Rectangle(0,0,800,576);
            // Double Buffer
            Dimension   size;
            Image       back= null;
            Graphics    buffer;
        
  3. init() はアプレットの初期化を行うメソッドです。
    obj = new bg() で bg Object Class をインスタンス化します。
    javabg.txt には、画像ファイルの名前やセルのサイズやインデックス情報など背景を描画するのに必要な情報が記録されています。
    new card() で card Object Class をインスタンス化します。
    obj.LoadAT() で Mapchip の属性を定義したファイルを入力します。
    obj.SetRect(win); で BG を描画する矩形領域を設定します。
    off.y= obj.scrollMax.y; で縦方向のスクロール値を最大に設定します。
    ダブルバッファの領域を設定します。
    KeyListener を設定して Thread を起動します。
        public void init()
        {   obj = new bg(getCodeBase().toString(),"javabg.txt");
            cat = new card(getCodeBase().toString() + "chr47.gif",32,32);
            obj.LoadAT(getCodeBase().toString(),"javabgatt.txt");
            obj.SetRect(win);
            off.y= obj.scrollMax.y;
            setBackground(Color.gray);
            size = getSize();
            back= createImage(size.width, size.height);
            if (back==null) System.out.print("createImage Error");
            addKeyListener(this);
            Thread t = new Thread(this);
            t.start();
        }
        
  4. paint() メソッドでは、obj.MapView(buffer,off.x,off.y); でスクロール値を指定して BG を描画します。
    その上から cat.View(buffer,dir*2+num,pos.x,pos.y); でキャラクタを描画します。
    描画は BackBuffer にイメージを作成してから一挙に Front Buffer に転送します。
        public void paint(Graphics g)
        {   if (back==null)     return;
            buffer= back.getGraphics();
            if (buffer==null)   return;
            size = getSize();
            buffer.setColor(getBackground());
            buffer.fillRect(0, 0, size.width, size.height);
            obj.MapView(buffer,off.x,off.y);
            cat.View(buffer,dir*2+num,pos.x,pos.y);
            g.drawImage(back,0,0,this);
        }
        
  5. 矢印キーを検出してキャラクタを操作する action() メソッドです。
    ネコは進行方向(上下左右)それぞれに、二枚の画像を切り替えながら移動します。
    animeTime でタイミングを取りながら num^= 1; でキャラクタの画像を交互に切り替えます。
    eventcheck(); でイベントが設定されているセルをチェックします。
    キーを離したあとも x%32!=0 または y%32!=0 でマップの境界になるまでキャラクタを進めます。
    上下左右のキーにより、進行方向を設定して座標を移動します。
    BG のスクロールには、二種類の方法があります。
    1. キャラクタを中央に置く方法
      キャラクタを中央に置いて、先に背景画像からスクロールします。
      背景画像がスクロール出来なくなったら、キャラクタを動かします。
      戻るときはキャラクタが中央に来るまで移動し、中央に来たら背景をスクロールします。
    2. キャラクタから動かす方法
      矢印キーの操作で先にキャラクタを動かします。
      キャラクタがウインドウの端に来ると背景をスクロールします。
    今回はキャラクタを中央に置く方法を使っています。
    ただし、横方向はスクロールの余地が無いので、直接キャラクタが動きます。
        // キャラクタの移動
        public boolean action()
        {   int     i;
            long  nowTime = System.currentTimeMillis();
            if (animeTime < nowTime)
            {   animeTime= nowTime+200;
                num^= 1;
            }
            eventcheck();       //イベントのチェック
            // MAP の境界まで動く
            i= 4;
            if ((pos.x+off.x)%32!=0 && (dir==1 || dir==3))  i= dir;
            if ((pos.y+off.y)%32!=0 && (dir==2 || dir==0))  i= dir;
            // キーが押されているか
            if (i>3)
            {   for(i=0; i<4; i++)
                {   if (key_t[i]==1)
                    {   dir= i;
                        if (obj.GetAtt(i,pos,off)>0) break;
                    }
                }
            }
            if (i>3)    return false;
            // 座標の更新
            switch(i)
            {   case 0:     // UP
                    if (pos.y>obj.center.y) pos.y-= 4;
                    else    if (off.y>=4)   off.y-= 4;
                    else    pos.y-= 4;
                    break;
                case 1:     // RIGHT
                    if (pos.x<obj.center.x) pos.x+= 4;
                    else    if (off.x+4<obj.scrollMax.x)  off.x+= 4;
                    else    pos.x+= 4;
                    break;
                case 2:     // DOWN
                    if (pos.y<obj.center.y) pos.y+= 4;
                    else    if (off.y+4<obj.scrollMax.y)  off.y+= 4;
                    else    pos.y+= 4;
                    break;
                case 3:     // LEFT
                    if (pos.x>obj.center.x) pos.x-= 4;
                    else    if (off.x>=4)   off.x-= 4;
                    else    pos.x-= 4;
                    break;
            }
            return true;
        }
        
  6. 宝箱を調べる eventcheck() メソッドです。
    bg.GetAtt() で現在のセルの属性を調べます。
    属性=2 のときは「宝箱」のセルです。
    宝箱を探し当てると、蓋が空いた画像に切り替えます。
    宝箱の画像と蓋が空いた画像が隣同士で並んでいることを確認して下さい。
        public void eventcheck()
        {   int     wat,wx,wy;
            wat= obj.GetAtt(pos,off);
            switch(wat)
            {   case 2:     //宝箱の蓋を開ける
                    wx= obj.GetX(pos.x,off.x);
                    wy= obj.GetY(pos.y,off.y);
                    obj.TT[wy][wx]++;
                    obj.TT[wy-1][wx]++;
                    System.out.println("宝箱を見つけた!");
                    return;
            }
        }
        

Java Game Program