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

- STORY 6 -



くま先生 こんにちは、クマです。

ミャンちゃん みゃんちゃんみゃん!!

うし君 うしだもー

くま先生 さて、さっそく現在製作中のパズルゲームの続きを作りましょう!!

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


くま先生 前回は、裏画面にCGを読みこみ、それを表示するところまで作りました。
今回は読みこんだCGのパネルを、ごじゃごじゃに入れ替えて表示させましょう。

くま先生 前回のプログラムは、

    ・CGを読みこむ

    ・裏画面に作画

    ・表画面に表示

の順番で処理をしていました。 今回はプログラムを追加して、

    ・CGを読みこむ

    ・裏画面に作画

   ・CGのパネルを入替える

    ・表画面に表示

のように処理(プログラム)を追加します。

うし君 CGの入替えってどうやるんだもー????

くま先生 copyArea() 命令を使います。 この命令はCGの一部を違う場所にコピーできます。

うし君 さっそくCGを入替えるもーー!!!

ミャンちゃん プログラムするみゃん!!

くま先生 ちょっと、待ってください・・・ 実は、1つ問題があります・・・・

うし君 問題が多いプログラムだもーーー

ミャンちゃん 問題はなんだみゃん????

くま先生 copyArea() 命令でCGの一部をコピーできるのですが、今回のプログラムはパネルをごじゃごじゃに入替える事ですよね???

くま先生 たとえば下図で「1のパネル」「2のパネル」を交換するとします。

パネルの交換1

くま先生 「1のパネル」の場所に「2のパネル」copyArea() 命令でコピーすると、「1のパネル」の画像が消えてしまいます。
これでは次に「1のパネル」「2のパネル」の位置にコピーする事は出来ません!!

 うし君 ほんとだもー!! それなら「1のパネル」の画像を一時退避させるも!!!!!

くま先生 「1のパネル」の画像を普通に退避させるためには、もう1つ裏画面を用意するか、MemoryImageSource などの凝った命令を使って、メモリーに退避させねばならないので、かなりプログラムが複雑になってしまいます。

ミャンちゃん 面倒なプログラムはいやだみゃん!!!

くま先生 私もです。 そこで、次のように解決します。

画像移動

くま先生 上図を見てください。
まず裏画面のサイズを ( 480 x 480 )から、( 480 x 560 )に変更します。
そして、「パネル1」裏画面の使われていない部分(増やした下部分)にコピーします。
次に、「パネル2」「パネル1」の場所にコピーします。
次に、裏画面の使われていない部分にコピーした「パネル1」「パネル2」の場所にコピーします。
これで、「パネル1」「パネル2」を入替える事が出来ます!!

ミャンちゃん なるほどみゃん!

 うし君 でも、ふざけた解決法方だもー

くま先生 くまですから・・・

 

くま先生 ではさっそく裏画面のサイズを変更します。

    public void init() { // 初期処理
       
        backimage = createImage( 480, 560 );
        bg = backimage.getGraphics();
       
        img = getImage(getDocumentBase(), "image.jpg");

 

うし君 次はパネルの入替えプログラムかもーー??

くま先生 そうですが、入替えるパネルを ランダム で決定します。

ミャンちゃん それはなんだみゃ??? それ、機動戦士みゃん???

うし君 ランダム「いいかげん」って事だもー

くま先生 たとえばサイコロです。 サイコロとは1から6までの数字が ランダム で出てくるアイテムです。

ミャンちゃん なるほどみゃん!! 入替えるパネルを適当に選ぶのみゃん!!

くま先生 そうです。 JAVAでは

int rd = (int) (6 * Math.random());

という命令で、からまでのランダムな数字が rd という変数に入ります。

int rd = (int) (100 * Math.random());

とすると、から99までのランダムな数字が rd という変数に入ります。

ミャンちゃん なるほどみゃん!!

くま先生 init() bg.drawImage( img, 0, 0, this); の下に次のようにプログラムします。

       

        bg.drawImage( img, 0, 0, this);
       
        int x1, y1, x2, y2;
       
        x1 = (int) (6 * Math.random());
        y1 = (int) (6 * Math.random());
        x2 = (int) (6 * Math.random());
        y2 = (int) (6 * Math.random());

 

くま先生 ここでは、x1 はパネル1のX座標、y1 はパネル1のY座標、x2 はパネル2のX座標、y2 はパネル2のY座標です。
次にパネル入替えです。

copyArea() は、 copyArea( 移動元X, 移動元Y, サイズX, サイズY, 移動先X, 移動先Y ) という風に使います。

うし君 さっそくパネルを入替えるもー!!! 1つのパネルの大きさは ( 80 x 80 )なので、

    bg.copyArea( x1*80, y2*80, 80, 80, x2*80, y2*80 );

だもーーーー!!!

くま先生 ところが再び問題があります。 問題は copyArea() です。
実は恐ろしい事に、 copyArea() の移動先の指定は「相対座標」なんです!

うし君 もーーーーーーー!!!!!!!!!!!

ミャンちゃん ??? 相対座標だと困るみゃん???

うし君 めんどくさいもー!!! ひどいもー!!

くま先生 たとえば、( 122, 57 )の画像を ( 33, 29 ) にコピーするとしますね(下図参照)。
コピーする画像のサイズは ( 80, 50 )とします。

 

相対座標と絶対座標

くま先生 移動先の指定が「絶対座標」の場合は、

    copyArea( 122, 57, 80, 50, 33, 29);

となります。
ところが「相対座標」の場合は、移動元の座標からの移動量で表すので、

    copyArea( 122, 57, 80, 50, -89, -28);

となります。

うし君 わかりずらい、もぉ〜!!!

くま先生 未確認情報ですが、爆裂健氏は copyArea() のあまりの使いづらさに怒り狂って、
「スーパーサイヤ人」に変身したらしいです。

うし君 きっと、純粋な怒りだったんだもー

くま先生 「相対座標」はあまりに使いづらいので、新たに関数を用意して、絶対座標で指定できるようにします。

うし君 それがいいもー!!

くま先生 では、一番下に関数を追加します。 関数名は kcpoy です。

   

    } // mouseDrag()
   
   // -----------------------------------------------------------
    void kcopy( int x, int y, int dx, int dy) {
        bg.copyArea( x*80, y*80, 80, 80,(dx-x)*80, (dy-y)*80 );
    }


// ===============================================================
} // End of Class

くま先生 この関数は、

  kcpoy(  移動元パネルのX位置 ,   移動元パネルのY位置 ,  移動先パネルのX位置 ,   移動先パネルのY位置    );

という風にして、画像のコピーを指定します。

うし君 これで、楽になるもー

くま先生 ではパネルをコピーしましょう。 もちろん kcpoy() を使います!
先ほどの init() でのランダムのプログラムの下にコピー命令を足します。

           
            x1 = (int) (6 * Math.random());
            y1 = (int) (6 * Math.random());
            x2 = (int) (6 * Math.random());
            y2 = (int) (6 * Math.random());
           
            kcopy( x1, y1, 0, 6);
            kcopy( x2, y2, x1, y1);
            kcopy( 0, 6, x2, y2);

くま先生 先ほど説明しましたが、もう一度手順を説明します。

  kcopy( x1, y1, 0, 6);

「パネル1」をパネル座標( 0, 6 ) (裏画面下)にコピー

  kcopy( x2, y2, x1, y1);

「パネル2」を「パネル1」の場所にコピー

  kcopy( 0, 6, x2, y2);

パネル座標( 0, 6 )の「パネル1」を「パネル2」の場所にコピー

という具合にパネルを入替えています。

 

くま先生 では、さっそくコンパイルしてみてください!!

ミャンちゃん javac KumaPuzzle.java(リターン)
appletviewer sample.html(リターン)

ミャンちゃん あ! パネルが1枚、入れ替わってるみゃ!!!

動作画面

うし君 ほんとだもー!! でもこれだとパズルゲームにならないも・・

くま先生 わかっています。
そこで、プログラムを追加して、ほんの 300回ほどパネルを入替えましょう!!

くま先生 init() のランダムの部分とパネル移動の部分を、for 文で囲みます。
for 文で300回ほどループさせましょう!!


        bg.drawImage( img, 0, 0, this);
       
        int r, x1, y1, x2, y2;
       
        for ( r=0; r<300 ; r++) {

            x1 = (int) (6 * Math.random());
            y1 = (int) (6 * Math.random());
            x2 = (int) (6 * Math.random());
            y2 = (int) (6 * Math.random());
           
            kcopy( x1, y1, 0, 6);
            kcopy( x2, y2, x1, y1);
            kcopy( 0, 6, x2, y2);
       }
       

 

くま先生 これで、パネル入替えのプログラムは終了です。
コンパイルしてみてください!!!

ミャンちゃん やった! パネルがばらばらに入れ替わってるみゃ!!KumaPuzzle.javaKumaPuzzle.classフォルダ

うし君 なんか、パズルゲームみたいになってきたもー。

 

くま先生 今回の講座はこれで終了。 次回もまたゲームの続きを作っていきます。

うし君ミャンちゃん はーい、くま先生。

 

- 続く -

 


戻る