AWT Sprite Class でアニメーション


AWT Sprite Class を使って画像を切り分けてアニメーションします。

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

プログラムの作成

  1. 画像を切り分けて描画する AWT Sprite Object Class です。
    SpriteF.java の名前で保存して下さい。
    //★ Frame を継承して画像を切り分ける Sprite Class    前田 稔
    import java.awt.*;
    
    class SpriteF extends Frame
    {   private Image   img;
        private int Height,Width,Hnum,Wnum;
        int     frameNum;
    
        // Constructor
        SpriteF(String filename, int wn, int hn)
        {   Wnum= wn;
            Hnum= hn;
            Width=Height= 32;
            frameNum = Wnum*Hnum;
            img= getToolkit().getImage(filename);
            // MediaTracker で待ち合わせ
            MediaTracker tracker = new MediaTracker(new Component(){});
            tracker.addImage(img, 0);
            try
            {   tracker.waitForID(0);
            } catch(InterruptedException e){}
            Width= img.getWidth(null)/Wnum;
            Height= img.getHeight(null)/Hnum;
            if (img.getHeight(null)==-1)    System.out.println("Image File Error " + filename);
        }
    
        public void view(Graphics g, int n, int dx, int dy)
        {   int sx, sy;
            if (n >= frameNum)  return;
            sx = (n % Wnum) * Width;
            sy = (n / Wnum) * Height;
            if (img != null)
            {   g.drawImage(img,dx,dy,dx+Width,dy+Height,sx,sy,sx+Width,sy+Height,this);
            }
        }
    }
    
  2. SpriteF.java をコンパイルして SpriteF.class を作成して下さい。
    main() メソッドが定義されていないので、次のメッセージが表示されますが無視して下さい。
        Exception in thread "main" java.lang.NoSuchMethodError: main
         -- Press any key to exit (Input "c" to continue) --
        
  3. SpriteF.class を使って、アニメーションをする MainF.java です。
    SpriteF.class と同じフォルダーに格納して下さい。
    //★ SpriteF Class を使って美人のアニメーション    前田 稔
    import java.awt.*;
    import java.util.*;
    
    class MainF extends Frame
    {   SpriteF     spr;
        Timer       time;
        int         currFrame;
    
        // Main()
        public  static void main(String args[])
        {   new MainF();
        }
    
        // Constructor
        MainF()
        {   super("Animation");
            spr = new SpriteF("bijin.jpg",4,2);
            currFrame = 0;
            time = new Timer();
            time.schedule(new TestTask(),300,200);
            setSize(200, 200);
            setVisible(true);
        }
    
        // Paint
        public void paint(Graphics g)
        {   spr.view(g, currFrame, 50, 60);
        }
    
        // Timer Task
        public class TestTask extends TimerTask
        {   public void run()
            {   currFrame = (currFrame+1) % spr.frameNum;
                repaint();
            }
        }
    }
    
  4. 画像ファイル(bijin.jpg)をプログラムと同じフォルダーに格納して下さい。
    このファイルには「幅=96, 高さ=96」の Sprite が横に4枚、縦に2段でならんでいます。
    MainF.java をコンパイルして実行して下さい。
    Windows の画面に美人の画像がアニメーションされたら完成です。

プログラムの説明

Sprite Class を使って画像を切り分けてアニメーションします。
  1. AWT を使ったプログラムの基本的な説明は 色を設定して線を描く を参照して下さい。
    AWT でタイマを使うので java.util.* をインポートします。
    SpriteF spr は Sprite Class の定義です。
    time はタイマの Object です。
    currFrame はタイマ切り替えで表示する画像の番号です。
        import java.awt.*;
        import java.util.*;
        class MainF extends Frame
        {   SpriteF     spr;
            Timer       time;
            int         currFrame;
        
  2. Main では MainF() をインスタンス化するだけです。
        // Main()
        public  static void main(String args[])
        {   new MainF();
        }
        
  3. MainF の Constructor です。
    super("Animation") で継承したクラスの Constructor を呼び出します。
    new SpriteF("Bijin.jpg",4,2) で SpriteF class をインスタンス化します。
    "Bijin.jpg" は横に4枚、縦に2枚の画像が並んでいます。
    currFrame は表示する画像の番号で、最初は0番目に設定します。
    new Timer() でタイマをインスタンス化します。
    time.schedule(new TestTask(),300,200); でタイマで起動するタスクを登録します。
    new TestTask() が起動するタスクで、300o秒 が起動開始までの時間で、200 が起動する間隔です。
    setSize() で Window(Frame) のサイズを設定します。
    setVisible() で表示します。
        // Constructor
        MainF()
        {   super("Animation");
            spr = new SpriteF("Bijin.jpg",4,2);
            currFrame = 0;
            time = new Timer();
            time.schedule(new TestTask(),300,200);
            setSize(200, 200);
            setVisible(true);
        }
        
  4. 画像を描画するメソッドです。
    spr.view(g,currFrame,50,60) で Sprite Class を使ってフレームを描画します。
    50,60 は画像を表示する Windows の左上座標です。
        // Paint
        public void paint(Graphics g)
        {   spr.view(g, currFrame, 50, 60);
        }
        
  5. タイマ割り込みで起動するタスクのクラスです。
    TimerTask を継承しています。
    void run() がタスクで起動されるメソッドです。
    (currFrame+1) % spr.frameNum; で表示する画像を切り替えて repaint() で画像を描画するメソッドを呼びます。
        // Timer Task
        public class TestTask extends TimerTask
        {   public void run()
            {   currFrame = (currFrame+1) % spr.frameNum;
                repaint();
            }
        }
        
  6. Swing のタイマとは少しプログラミングの方法が違います。
    参考までに申し添えますと、javax.swing.* と java.awt.event.* をインポートすれば Swing と同様にプログラミングすることも出来ます。

Sprite Object Class

  1. Sprite Object Class(SpriteF.java) の説明です。
    画像描画の基本的な説明は Image(画像)の描画 を参照して下さい。
  2. class SpriteF は Frame を継承しています。
    Image img; は画像データ(イメージ)の領域です。
    Width, Height は Sprite(カード一枚分)の幅と高さです。
    Wnum, Hnum は切り分ける Sprite(カード)の横と縦の枚数です。
    frameNum は切り分ける Sprite(カード)の総枚数です。
        import java.awt.*;
        class SpriteF extends Frame
        {   private Image   img;
            private int Height,Width,Hnum,Wnum;
            int     frameNum;
        
  3. getImage(filename) でカレントディレクトリから filename の画像を入力します。
    コンストラクタで横と縦の枚数を受け取るのですが、Sprite の幅と高さは画像サイズから計算します。
    このとき getToolkit().getImage(filename) で画像を入力するのに多少時間がかかります。
    そこで MediaTracker を使って入力が終了するのを待ち合わせます。
        img= getToolkit().getImage(filename);
        // MediaTracker で待ち合わせ
        MediaTracker tracker = new MediaTracker(new Component(){});
        tracker.addImage(img, 0);
        try
        {   tracker.waitForID(0);
        } catch(InterruptedException e){}
        

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