マイペースなプログラミング日記

DTMやプログラミングにお熱なd-kamiがマイペースに書くブログ

シューティング作成を目指して(1) 〜とりあえず画像表示編〜

最近、Javaを趣味で使ってることがなかったので、そろそろ何か作りたいと思うようになった。研究でJava使ってるけど、文字列を分割したり結合したり挿入したりばかりでつまらん。使ってるライブラリもコレクション、正規表現、DOM…。そろそろSwingも忘れかけてきてたので思い出すためにGUIな何かを作りたかった。しかし、『これが作りたい!』というものがなかったので考えた所、目に入ったのがGlendaというPlan9のマスコット。この画像を使ったゲームを作ろうと思うようになったわけだが、横向きの画像しか見つからなかったので、横スクロールなアクションorシューティングにしぼられた。それで気分でシューティングにした。攻撃法方が現時点で全く思いつかないのだが、そのうち思いつくだろう、多分。ゲーム作成経験なんてないんで、途中でやめる可能性が高いけどそんなこと気にしないで作成へ


最初にやることはウインドウ表示して画像表示するまで。画像は32x32にした。ちょっと小さいかな?

以下ソース。その後、申し訳ない程度の説明

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;

import java.io.File;
import java.io.IOException;

public class Glenda extends JComponent{
   private BufferedImage glendaImage;

    public static void main(String[] args){
        SwingUtilities.invokeLater(new Runnable(){
            public void run(){
                Glenda.start();
            }
        });
    }

    private static void start(){
        try{
            JFrame frame = new JFrame("Glenda");

            Glenda glenda = new Glenda();
            glenda.loadGlendaImage("./glenda_32.png");

            glenda.setPreferredSize(new Dimension(600, 500));
            frame.add(glenda);

            frame.pack();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        }catch(IOException e){
            String message = "Glendaを読み込めませんでした";
            String title = "エラー";
            JLabel label = new JLabel(message);
            label.setForeground(Color.RED);

            JOptionPane.showMessageDialog(null, label, title, JOptionPane.ERROR_MESSAGE);
        }
    }

    public void loadGlendaImage(String fileName) throws IOException{
        glendaImage = ImageIO.read(new File(fileName));
    }

    @Override
    protected void paintComponent(Graphics g){
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, getWidth(), getHeight());

        g.drawImage(glendaImage, 0, 0, null);
    }
}

まず、mainではSwingUtilities.invokeLaterを呼び出す。これで引数で指定したRunnableを実装したクラスのrunがEventDispatchThreadから呼び出される。Swingのコンポーネントを更新するのはEventDispatchThreadでやれってことなのだが、最初のウインドウが表示されるまでは大丈夫だとか、実はバグがあってEventDispatchThreadじゃないとまずいとかあったような記憶があるが覚えてない。そしてそれが書かれたページを見つけられない。探せばどっかに書いてあるはず…。まぁ、とりあえずEventDispatchThreadで更新しておけば大丈夫だろう。問題なのはEventDispatchThreadでファイルを読み込んでるところだったり。このThreadで時間のかかる処理をしてると、その間ボタン押せなくなったりキーボードやマウスに反応しなくなったり、再描画されずにウインドウが真っ白になるので、そういう処理はSwingWorkerに任せましょうってことで次回やる。今回はファイルが1つなので時間がかからずにすむけど。あとは画像読み込んでたり表示したりするだけなので、説明なし!次回はキーボードで画像動かすところまでやる。一片にいろいろ進めるとそれだけブログのネタがすぐなくなるんで