キーでシップを操作

矢印キーでシップを操作します。

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

プログラムの作成

  1. メモ帳などでタイプして Shoot_01.java の名前で保存して下さい。
    //★ Double Buffer でシップを表示    前田 稔
    import java.awt.*;
    import javax.swing.*;
    import java.awt.event.*;
    
    class Shoot_01 extends JFrame implements KeyListener
    {   Image       img;
        int         key_t[] = { 0,0,0,0 };      //UP, RIGHT, DOWN, LEFT
        Point       pos= new Point(100,80);
        Dimension   size;
        Image       back;
        Graphics    buffer;
    
        // Main
        public static void main(String args[])
        {   new Shoot_01();
        }
    
        // Constructor
        public Shoot_01()
        {   super("Image View");
            img = getToolkit().getImage("c:\\data\\test\\ship.png");
            addKeyListener(this);
            ThreadClass threadcls = new ThreadClass();
            Thread thread = new Thread(threadcls);
            thread.start();
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setSize(640, 480);
            setBackground(Color.gray);
            setVisible(true);
            size = getSize();
            back= createImage(size.width, size.height);
            if (back==null) System.out.print("createImage Error");
        }
    
        //  Runnable Class
        class ThreadClass implements Runnable
        {
            public void run()
            {   long    nowTime,drawTime;
    
                nowTime= System.currentTimeMillis();
                drawTime= nowTime+500;
                while(true)
                {   nowTime= System.currentTimeMillis();
                    if (drawTime<nowTime)
                    {   drawTime= nowTime+30;
                        if (action())   repaint();
                    }
                }
            }
        }
    
        // 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);
            buffer.drawImage(img,pos.x,pos.y,this);
            g.drawImage(back,0,0,this);
        }
    
        // シップの移動
        public boolean action()
        {   if (key_t[0]==1)     // UP
            {    pos.y-= 4; return true;  }
            if (key_t[1]==1)     // RIGHT
            {    pos.x+= 4; return true;  }
            if (key_t[2]==1)     // DOWN
            {    pos.y+= 4; return true;  }
            if (key_t[3]==1)     // LEFT
            {    pos.x-= 4; return true;  }
            return false;
        }
    
        // 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) { }
    }
    
  2. 画像ファイル("c:\\data\\test\\ship.png")をパスで指定したフォルダーに格納して下さい。
    適当なサイズの画像であれば、何でもかまいません。

プログラムの説明

  1. シューティングゲームでは FPS(frames per second) を一定にして描画します。
    FPS の説明は Thread で FPS を制御 または Runnable で FPS を制御 を参照して下さい。
    KeyListener で直接キーを検出したのでは、タイムラグが生じます。
    詳しい説明は Timer でキーの状態を調べる を参照して下さい。
    普通に描画したのでは画面の「チラツキ」が大きくてゲームになりません。
    チラツキを少なくする方法は Double Buffer を使う を参照して下さい。
  2. キーのイベントを検出するので java.awt.event.* をインポートします。
    Image img はシップ(自機)の画像です。
    key_t[] はシップを矢印キーで操作するための領域です。
    Point pos はシップの座標です。
    Point の説明は Rotation Class に Point を使う を参照して下さい。
    size がフレーム領域のサイズで、back が Back Buffer のイメージ領域で、buffer がその Graphics です。
        import java.awt.*;
        import javax.swing.*;
        import java.awt.event.*;
    
        class Shoot_01 extends JFrame implements KeyListener
        {   Image       img;
            int         key_t[] = { 0,0,0,0 };      //UP, RIGHT, DOWN, LEFT
            Point       pos= new Point(100,80);
            Dimension   size;
            Image       back;
            Graphics    buffer;
        
  3. Constructor でシップの画像を読み込みます。
    矢印キーを検出するために KeyListener を設定します。
    Runnable でスレッドを起動します。
    スレッドの説明は Runnable を使う を参照して下さい。
    ウインドウの背景を gray に設定します。
    Back Buffer を作成します。
        // Constructor
        public Shoot_01()
        {   super("Image View");
            img = getToolkit().getImage("c:\\data\\test\\ship.png");
            addKeyListener(this);
            ThreadClass threadcls = new ThreadClass();
            Thread thread = new Thread(threadcls);
            thread.start();
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setSize(640, 480);
            setBackground(Color.gray);
            setVisible(true);
            size = getSize();
            back= createImage(size.width, size.height);
            if (back==null) System.out.print("createImage Error");
        }
        
  4. ThreadClass から action() メソッドを呼んで、repaint() でシップを描画します。
        //  Runnable Class
        class ThreadClass implements Runnable
        {
            public void run()
            {   long    nowTime,drawTime;
    
                nowTime= System.currentTimeMillis();
                drawTime= nowTime+500;
                while(true)
                {   nowTime= System.currentTimeMillis();
                    if (drawTime<nowTime)
                    {   drawTime= nowTime+30;
                        if (action())   repaint();
                    }
                }
            }
        }
        
  5. paint() メソッドでは BackBuffer にイメージを作成してから一挙に Front Buffer に転送します。
        // 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);
            buffer.drawImage(img,pos.x,pos.y,this);
            g.drawImage(back,0,0,this);
        }
        
  6. シップの移動を調べる action() メソッドです。
    上下左右のキーの操作でシップを動かします。
        // シップの移動
        public boolean action()
        {   if (key_t[0]==1)     // UP
            {    pos.y-= 4; return true;  }
            if (key_t[1]==1)     // RIGHT
            {    pos.x+= 4; return true;  }
            if (key_t[2]==1)     // DOWN
            {    pos.y+= 4; return true;  }
            if (key_t[3]==1)     // LEFT
            {    pos.x-= 4; return true;  }
            return false;
        }
        
  7. KeyEvent Listener の説明は Runnable を使う を参照して下さい。

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