JAVAプログラミング講座 宇宙のJAVAさん

- STORY 4 -



くま先生久しぶりに、宇宙のJAVAさんをはじめます(笑)

ミャンちゃんクマ先生、久しぶりだみゃん!!

うし君もーもー!

くま先生さて、前回予告したゲストですが・・・

ミャンちゃん爆裂健にゃ???

くま先生爆裂健も昔は我々と同様 JAVAプログラミングに燃えていましたが、
今ではやる気がうせて 酒浸りの毎日です!!

うし君もー、だめもー!

くま先生と、いうわけで、特別ゲストは無しです!!

うし君ミャンちゃんはーい!

くま先生今回は「ダブルバッファリング」に手を出します。

ミャンちゃんにゃ???

くま先生要は「裏画面」です。 JAVAでゲームを作る場合、避けては通れない技術です。

 


くま先生まずは、ダブルバッファリングは忘れて、簡単なお絵かきプログラムを作ってみましょう。

うし君もー!!

くま先生マウスドラッグすると、作画されるプログラムを考えます。
例によって、JAVA Applet 雛形 を加工します。
さしあたりプログラム名は「NoDB」にしましょう。

うし君ファイル名を「NoDB.java」に変えて、Applet名も変えるモー

 // ===============================================================

public class NoDB extends Applet {

 

くま先生さて、今回はマウスをドラッグ(マウスのボタンを押しながら移動)すると、作画されるようなプログラムを作ります。

ドラッグされたマウスの座標を記憶して、その座標に paint() で、円を作画する事にします。

マウスの座標を記憶するための変数を「グローバル変数」で宣言します。
今回は、mx  my という変数名にしましょう。

    // グローバル変数
    int mx, my;

mx my には値が入っていないので、init() で初期値を入れます。
今回は、mx=0 my=0 としました。

    public void init() { // 初期処理
        mx = 0;
        my = 0;

    } // init()

さて、ドラッグしたら現在のマウス座標を mx  my   に収納します。
この処理はどこに記述しますか???

ミャンちゃん mouseDrag() にゃ???

くま先生その通りです! ミャンちゃん!!
mouseDrag() はつぎのようになります。

    public boolean mouseDrag(Event e, int x, int y) { // マウス移動
       mx = x;
        my = y;
        repaint();

        return true;
    } // mouseDrag()

現在のマウスの X 座標を mx に、Y 座標を my に代入し、その後 repaint() (作画要求) します。

くま先生次に作画ですが、ドラッグされた場所( mx, my)に、青色の円を描きましょう!!

ミャンちゃん 円はどう描くにゃ???

くま先生内側が塗りつぶされた円を描く命令は fillOval() です。
paint() の中で、g.fillOval( mx, my, 10, 10); とすれば、縦横10ドットの四角に収まる円が作画されます。

うし君じゃ!こうだモー!!

    public void paint(Graphics g) { // 作画処理
        g.setColor(Color.blue);
        g.fillOval( mx, my, 10, 10);

    } // paint()

くま先生さすがは牛君、正解です!! 作画色をちゃんと青にしてますね!!

くま先生 sample.html を書きかえるのを、忘れないでね!!

<APPLET CODE="NoDB.class" WIDTH=640 HEIGHT=480>
</APPLET>

くま先生コンパイルして、これで完成です!!!! NoDB.javaNoDB.class 
2人とも、マウスでお絵かきしてみてください!!

ミャンちゃん 円で絵が描けるみゃ!!!! みゃみゃみゃあ!!

うし君モモモモモモモモモモモモモ・・・

ミャンちゃん あ!! 牛君、絵がうまいねー

うし君芸術が出来たも!!



くま先生さて、お絵かきアプレットが動いているブラウザを一度「最小化」させて、またもとに戻してください。
もしくは、他の Window でブラウザを隠してください・・・

うし君も! 俺の芸術が消えたも!!

ミャンちゃん 本当だ!! せっかく描いた絵が、消えちゃった・・・・

くま先生そうなんです。 - STORY 1 - で述べた通り、再び画面が出てくるときは paint() が呼び出されますが、直接アプレット画面に書いた絵は消えてしまいます。

直描き

くま先生こんな感じで(表の)画面に直接描いているので、画面が隠れたとたん絵は消えてしまいます。

そこでメモリー上に仮の(裏の)画面を作り、そこに作画をした後、(表の)画面に移せば、(表の)画面が消えても、絵自体は仮の(裏の)画面に残ります。

この手法をダブルバッファリングといいます。

ダブルバッファリング

これなら、ブラウザが隠れて(表の)画面が消えても、裏画面から再び画像を転送すれば、画面は消えません!!!!

 

うし君早く言って欲しいも! 芸術が瞬殺されたも!

くま先生では、さっきのお絵かきプログラムを ダブルバッファリング対応 に変えましょう!!!

くま先生やり方は難しくありません。 裏画面を用意すれば良いだけです。
裏画面の用意の仕方は、詳しく考えないようにしましょう(笑)
このプログラムを写せば、OKですので・・・

ミャンちゃん みゃん!

くま先生ます、グローバル宣言に「ダブルバッファリング」用の宣言を2行加えます。

    // グローバル変数
    int mx, my;
   
    Graphics bg;
    Image backimage;

Graphics クラス Image クラスです。変数名はそれぞれ、bg、backimage にしました。

くま先生次に、init() にて、メモリー上に「裏画面」を生成します!!

    public void init() { // 初期処理
       
        mx = 0;
        my = 0;
       
        backimage = createImage( 640, 480 );
        bg = backimage.getGraphics();

   
    } // init()

裏画面のサイズは、アプレットサイズと同様の( 640 , 480 )にしました。
(復習:アプレットサイズは .html ファイル内で指定ですよ・・・)

これで、bg という裏画面のキャンバスが出来ました!!

くま先生そこで、paint() で、表画面のキャンバス g に作画するのを止めて、 bg に作画する事にします。
そして、paint() の最後で裏画面を表画面にコピーします。

    public void paint(Graphics g) { // 作画処理
       
        bg.setColor(Color.blue);
        bg.fillOval( mx, my, 10, 10);
       
       g.drawImage( backimage, 0, 0, null );
       
    } // paint()

くま先生これでおしまいです。 コンパイルしてください!!

ミャンちゃん javac NoDB.java 「りたーん」!

くま先生 これで完成です!! NoDB.javaNoDB.class 
Appletviewer か WWWブラウザで sample.html を動かしてください!

ミャンちゃん みゃ! 画面を「最小化」させたり、隠したりしても、描いた絵が消えないみゃ!!

うし君これで安心だもー! 

くま先生 バブルバッファリングは、ゲームを製作する場合に非常によく使います。
「作画画面のメモリー保存」のほかに「画面のちらつき防止」に利用します。

くま先生 アクションゲームでは、キャラや背景を直接「表画面」に作画すると、キャラが動くたびに画面がちらつきます。
そこで、最初「裏画面」にキャラを作画し、作画終了後 一括して「表画面」に表示させるとちらつきません!!

くま先生 私の友人 爆裂健の「JAVA 着せ替え アプレット」では、服を動かした時にちらつくのを防止するため、ダブルバッファリングを使用しています。

興味がある人は「爆裂健ホームページV」で JAVA着せ替えアプレット プログラム が公開されているので、見てください。

KissApplet.java の グローバル宣言の場所に

    Graphics bg;
    Image backimage;

と、今回の講座同様、ダブルバッファリング用の宣言があると思います。

ミャンちゃん あ! 本当だみゃ!! あったみゃ!!

くま先生 今回の講座はこれでおしまいです!! また、次の講座でお会いしましょう!!

うし君ミャンちゃんもーーーー!!!(みゃーーーん)!

くま先生 任務完了。

- 続く -

 


戻る