矢印キーでキャラクタを操作

背景画像をバックに矢印キーでアニメーションしながらキャラクタを操作します。

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

プログラムの作成

  1. キャラクタの画像を描画する CARD Object Class は、カードゲームで使っていたものを別ファイルにしました。
    CARD.class の説明は CARD Class で画像を切り分ける を参照して下さい。
    CARD.java をコンパイルして CARD.class を作成して下さい。
    //★ CARD Object Class(JFrame を継承)    前田 稔
    import java.awt.*;
    import javax.swing.*;
    import java.io.*;
    import javax.imageio.ImageIO;
    
    class CARD extends JFrame
    {   private Image       Img;
        private Dimension   size;   // Sprite Size
        private Dimension   num;    // Sprite 並び数
        int     frameNum;
    
        // Constructor
        public CARD(String filename, int ws, int hs)
        {   Init(filename,ws,hs);
        }
        public CARD(String filename, Dimension siz)
        {   Init(filename,siz.width,siz.height);
        }
    
        // Initialize
        void Init(String filename, int ws, int hs)
        {   size= new Dimension(ws,hs);
            num= new Dimension(1,1);
            //画像ロード
            File infile = new File(filename);
            Img = loadImage(infile);
            num.width= Img.getWidth(null)/size.width;
            num.height= Img.getHeight(null)/size.height;
            frameNum = num.width*num.height;
            if (num.width<1 || num.height<1)
                System.out.println("Image File Error" + filename);
        }
    
        // Sprite View
        public void View(Graphics g, int n, int dx, int dy)
        {   int sx, sy;
            if (n >= frameNum)
            {   System.out.println("Sprite Number Error" + n);
                return;
            }
            sx = (n % num.width) * size.width;
            sy = (n / num.width) * size.height;
            if (Img != null)
            {   g.drawImage(Img,dx,dy,dx+size.width,dy+size.height,sx,sy,sx+size.width,sy+size.height,this);
            }
        }
        public void View(Graphics g, int n, Point pnt)
        {   View(g,n,pnt.x,pnt.y);
        }
    
        // Load Image
        public static Image loadImage(File f)
        {   try
            {   Image img = ImageIO.read(f);
                return img;
            }
            catch (IOException e)
            {   throw new RuntimeException(e);
            }
        }
    }
    
  2. 背景画像をバックにキャラクタを操作するプログラムです。
    Rpg_01.java の名前で CARD.class と同じフォルダーに格納して下さい。
    //★ 背景画像をバックに矢印キーでキャラクタを動かす    前田 稔
    //   タイムラグがあり、ちらつきます
    import java.awt.*;
    import javax.swing.*;
    import java.awt.event.*;
    
    public class Rpg_01 extends JFrame implements KeyListener
    {   CARD    card;
        Image   bg;
        Point   pos= new Point(100,80);     //キャラクタの座標
        int     dir= 0, num= 0;
    
        // Main
        public static void main(String args[])
        {   new Rpg_01();
        }
    
        // Constructor
        Rpg_01()
        {   super("Character");
            bg = getToolkit().getImage("c:\\data\\test\\MapBack.gif");
            card = new CARD("c:\\data\\test\\Chr47.gif",32,32);
            addKeyListener(this);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setBackground(Color.gray);
            setSize(800,600);
            setVisible(true);
        }
    
        // Paint
        public void paint(Graphics g)
        {   int yoff;
            g.drawImage(bg,0,40,800,600,this);
            card.View(g,dir*2+num,pos);
        }
    
        // KeyEvent Listener
        public void keyPressed(KeyEvent e)
        {   switch(e.getKeyCode( ))
            {   case KeyEvent.VK_UP :    pos.y-= 10; dir=0; break;
                case KeyEvent.VK_RIGHT : pos.x+= 10; dir=1; break;
                case KeyEvent.VK_DOWN :  pos.y+= 10; dir=2; break;
                case KeyEvent.VK_LEFT :  pos.x-= 10; dir=3; break;
            }
            num ^= 1;
            repaint();
        }
        public void keyReleased(KeyEvent e) { }
        public void keyTyped(KeyEvent e) { }
    }
    
  3. 画像ファイル(MapBack.gif と Chr47.gif)をパスで指定したフォルダーに格納して下さい。
    MapBack.gif は 400*300 の背景画像で 800*600 に引き延ばして描画しています。
    Chr47.gif は 32*32 の Sprite が「後,右,前,左」の順に2枚ずつ8枚並んだ画像です。
    上下左右の矢印キーを押すとキャラクタの画像がアニメーションしながら動きます。
    キーの操作にタイムラグがあります。また多少キャラクタの画像が「チラツキ」ます。

プログラムの説明

  1. 画像の描画は Image(画像)の描画 を参照して下さい。
    矢印キーの操作は 矢印キーでキャラクターを動かす を参照して下さい。
  2. キーのイベントを検出するので java.awt.event.* をインポートします。
    CARD card は画像を切り分ける CARD Class の領域です。
    Image bg は背景の画像です。
    pos はキャラクターの座標です。
    dir は進む方向(後,右,前,左)で、num は二枚の画像を切り替えてキャラクターをアニメーションする領域です。
        import java.awt.*;
        import javax.swing.*;
        import java.awt.event.*;
    
        public class Rpg_01 extends JFrame implements KeyListener
        {   CARD    card;
            Image   bg;
            Point   pos= new Point(100,80);     //キャラクタの座標
            int     dir= 0, num= 0;
        
  3. Constructor で背景画像を読み込みます。
    new CARD() で CARD Class をインスタンス化します。
    32,32 は Sprite 一枚分のサイズです。
    矢印キーを検出するために KeyListener を設定します。
        // Constructor
        Rpg_01()
        {   super("Character");
            bg = getToolkit().getImage("c:\\data\\test\\MapBack.gif");
            card = new CARD("c:\\data\\test\\Chr47.gif",32,32);
            addKeyListener(this);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setBackground(Color.gray);
            setSize(800,600);
            setVisible(true);
        }
        
  4. paint() メソッドでは、キャラクターの進む方向(dir)と画像の切替(num)で示す画像を描画します。
        // Paint
        public void paint(Graphics g)
        {   int yoff;
            g.drawImage(bg,0,40,800,600,this);
            card.View(g,dir*2+num,pos);
        }
        
  5. KeyEvent Listener で矢印キーを検出して、キャラクターの座標と進む方向を更新します。
    num の値は num ^= 1; で、0と1を交互に繰り返します。
    repaint(); で画像を描画します。
        // KeyEvent Listener
        public void keyPressed(KeyEvent e)
        {   switch(e.getKeyCode( ))
            {   case KeyEvent.VK_UP :    pos.y-= 10; dir=0; break;
                case KeyEvent.VK_RIGHT : pos.x+= 10; dir=1; break;
                case KeyEvent.VK_DOWN :  pos.y+= 10; dir=2; break;
                case KeyEvent.VK_LEFT :  pos.x-= 10; dir=3; break;
            }
            num ^= 1;
            repaint();
        }
        

超初心者のプログラム入門(Java2)