CARD Class で画像を切り分ける

花札の画像を入力して、切り分けて描画します。
C# でも カードを描画 を作成しています。

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

プログラムの作成

  1. カードゲームを題材にしてプログラミングの手法を説明します。
    ゲームプログラムは今まで説明したことの集大成です。欲張らずに基礎から学んで下さい。
    画像の描画は Image(画像)の描画 を参照して下さい。
  2. メモ帳などでタイプして Card_01.java の名前で保存して下さい。
    //★ CARD Class で切り分ける    前田 稔
    import java.awt.*;
    import javax.swing.*;
    import java.io.*;
    import javax.imageio.ImageIO;
    
    class Card_01 extends JFrame
    {   CARD    card;
    
        // Main
        public static void main(String args[])
        {   new Card_01();
        }
    
        // Constructor
        public Card_01()
        {   super("Image View");
            card = new CARD("c:\\data\\test\\hanafuda.gif",51,75);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setSize(600,460);
            setVisible(true);
        }
    
        // Paint Method
        public void paint(Graphics g)
        {   super.paint(g);
            for(int i=0; i<5; i++)
                for(int j=0; j<10; j++) card.view(g,i*10+j,j*56+20,i*80+46);
        }
    }
    
    //★ CARD Object Class
    class CARD extends JFrame
    {   private Image   Img;
        private int Height,Width,Hnum,Wnum;
        int     frameNum;
    
        // Constructor
        public CARD(String filename, int ws, int hs)
        {   Width= ws;
            Height= hs;
            Wnum=Hnum= 1;
            //画像ロード
            File infile = new File(filename);
            Img = loadImage(infile);
            Wnum= Img.getWidth(null)/Width;
            Hnum= Img.getHeight(null)/Height;
            frameNum = Wnum*Hnum;
            if (Wnum<1 || Hnum<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 % 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);
            }
        }
    
        // Load Image
        public static Image loadImage(File f)
        {   try
            {   Image img = ImageIO.read(f);
                return img;
            }
            catch (IOException e)
            {   throw new RuntimeException(e);
            }
        }
    }
    
  3. 画像ファイル("c:\\data\\test\\hanafuda.gif")をパスで指定したフォルダーに格納して下さい。
    hanafuda.gif は「横=51ドット,縦=75ドット」の花札が5段10列に並んだ画像です。

プログラムの説明

  1. Main では Card_01 Class をインスタンス化するだけです。
        // Main
        public static void main(String args[])
        {   new Card_01();
        }
        
  2. Constructor で CARD Class をインスタンス化して、ウインドウを表示します。
    「51,75」はカード(花札)一枚分の幅と高さです。
        // Constructor
        public Card_01()
        {   super("Image View");
            card = new CARD("c:\\data\\test\\hanafuda.gif",51,75);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setSize(600,460);
            setVisible(true);
        }
        
  3. カードを描画する paint() メソッドです。
    5段10列に並んだカードの画像を座標を指定して順番に card.view() メソッドで描画します。
    i*10+j がカードの番号で j*56+20 がX座標で i*80+46 がY座標です。
        // Paint Method
        public void paint(Graphics g)
        {   super.paint(g);
            for(int i=0; i<5; i++)
                for(int j=0; j<10; j++) card.view(g,i*10+j,j*56+20,i*80+46);
        }
        

CARD Class の説明

  1. 5段10列に並んだカードの画像を切り分けて描画します。
    CARD Class は Sprite Class と同じ要領です。
    詳細は Image(画像)の描画 を参照して下さい。
  2. CARD Class の Constructor は Sprite Class とはパラメータで受け取る値が違います。
    Sprite Class では、並んでいる枚数を受け取りましたが、CARD Class では一枚分のサイズを受け取ります。
    画像のサイズを取得して、一枚分の幅と高さから、横と縦の枚数を計算しています。
    このとき画像の入力に getToolkit().getImage() を使うと待ち合わせが必要になるので ImageIO.read() を使っています。
    詳細は Image(画像)の描画 を参照して下さい。
        // Constructor
        public CARD(String filename, int ws, int hs)
        {   Width= ws;
            Height= hs;
            Wnum=Hnum= 1;
            //画像ロード
            File infile = new File(filename);
            Img = loadImage(infile);
            Wnum= Img.getWidth(null)/Width;
            Hnum= Img.getHeight(null)/Height;
            frameNum = Wnum*Hnum;
            if (Wnum<1 || Hnum<1)
                System.out.println("Image File Error" + filename);
        }
    
        // Load Image
        public static Image loadImage(File f)
        {   try
            {   Image img = ImageIO.read(f);
                return img;
            }
            catch (IOException e)
            {   throw new RuntimeException(e);
            }
        }
        

構造体を使った CARD Class

  1. Java にはゲームプログラムで使えそうな構造体(Class)が用意されています。
    せっかくなので CARD Class を Dimension 構造体を使ってリメイクしてみましょう。
    構造体(Class)の説明は Rotation Class に Point を使うを参照して下さい。
    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. 先の CARD Class と比べてみて下さい。
    Dimension で Sprite Size と Sprite 並び数を定義してみました。
    また Sprite Size に Dimension を使えるように、二種類の Constructor を用意しています。
    View() でも座標のパラメータに Point が使えるように、二種類のメソッドを用意しました。

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