ゲームプログラミング 第6回実習 乱数とマウスを使ったゲームを作ろう!!

注意点

テキストをちゃんと読んでから質問してください。
テキストをしっかり読まずに、図やテキストを流し読みをして分かった気になって、テキストを読めば分かることを質問してくる方が非常に多いです。

エディタ(導入必須)

繰り返しになりますが、xyzzy、Emacsなどのエディタの導入をお願いします。
特にWindows の方は xyzzy を必ず使って下さい。

エディタの導入方法はこちらです。

プログラミングが苦手で、上手くいかず質問してくる人ほど xyzzy を使っていないケースが多く、非常に困ります
自力でできず、TA・SAに質問しようという人は、必ず xyzzy を使うようにして下さい。

マウスを活用したゲームを作る

まず、今回の講義資料をダウンロードしてください。
第6回資料(Windows用)
第6回資料(Mac用)

マウスの情報を取得する

GameCanvas では、キーボードの情報以外に、マウスの情報を取得することができます。
マウスの情報を取得するためには、以下の命令を利用します。

マウスを使ったサンプル

ここからは、マウスを利用したサンプルプログラムについて説明していきます。
Sample01フォルダ直下にあるGame.javaを開いて下さい。

このサンプルプログラムは、これまでのサンプルのように画面上を移動するボールをマウスでクリックするとボールが消えるというサンプルです。

まずは変数定義からみていきます。
これまでと同様のボールに関する変数に加え、ボールの表示・非表示を表すフラグとして変数 ball_alive_flag が追加されています。

/********* 変数定義はこちらに *********/
// ボールのX座標
int ball_x;
// ボールのY座標
int ball_y;
// ボールのX方向の速度
int ball_speed_x;
// ボールのY方向の速度
int ball_speed_y;
// ボールの大きさ
int ball_size;

// ボールが表示されているかどうか
boolean ball_alive_flag;

	

続いては初期化処理です。
それぞれ、適切な値で初期化しています。開始時のボールは表示されている状態なので、ball_alive_flag には true をセットしています。

/********* 初期化の手順はこちらに *********/
public void initGame()
{
    // ボールの座標を初期化する
    ball_x = 0;
    ball_y = 0;

    // ボールの速度を初期化する
    ball_speed_x = 3;
    ball_speed_y = 3;

    // ボールのサイズを初期化する
    ball_size = 24;

    // ボールが表示されているかどうか
    ball_alive_flag = true;

}
	

続いて、更新処理を見ていきましょう。
ボールの動きについてはいままでの授業でやった内容なので、ここではマウスクリック処理についてのみ詳しく説明します。

/********* 物体の移動等の更新処理はこちらに *********/
public void updateGame()
{
    // ボールが表示されていれば移動処理を行う
    if(ball_alive_flag)
    {
        // Y方向に ball_speed_y ずつ進める
        ball_y = ball_y + ball_speed_y;
    
        // X方向に ball_speed_x ずつ進める
        ball_x = ball_x + ball_speed_x;
    
        // ボールが画面の上か下を越えた場合
        if(ball_y > 480 - ball_size || ball_y < 0)
        {
            // ボールのY方向の速度を反転させる
            ball_speed_y = -ball_speed_y;
        }
    
        // ボールが画面の右を越えるか、画面の左を越えた場合
        if(ball_x > 640 - ball_size || ball_x < 0)
        {
            // ボールのX方向の速度を反転させる
            ball_speed_x = -ball_speed_x;
        }

        // マウスがクリックされた瞬間なら、
        if(gc.isMousePushed())
        {
            // ボールと、マウスクリック座標との当たり判定を行う
            if( gc.checkHitRect(ball_x, ball_y, ball_size, ball_size, gc.getMouseX(), gc.getMouseY(), 1, 1) )
            {
                // ボールをクリックしていれば、ボールを非表示状態に
                ball_alive_flag = false;
            }
        }

    }
}
	

ここでは、ボールの更新処理とマウスクリック処理のどちらも、ball_alive_flag の中身が true の場合にのみ行っています。
ボールが非表示になっている場合には、ボールを動かす必要もなく、ボールをクリックしたかどうかを調べる必要もないからです。

マウスクリック処理では、まず if(gc.isMousePushed()) で、マウスをクリックした瞬間かどうかを調べて、true な場合にのみボールとマウス座標の当たり判定を行っています。
gc.getMouseX、gc.getMouseY はマウスクリックの状態に関係なくマウスカーソルの座標値を返すので、当たり判定より先にマウスクリックの状態を調べて、クリックした瞬間にだけ当たり判定処理を行う必要があるためです。

ボールとマウス座標との当たり判定では、ボールの幅・高さにボールの大きさである ball_size を指定しています。
マウス座標には、クリックした位置を点として計算するため、幅・高さのどちらにも 1 を指定しています。

そして、ボールにクリックした点が重なっていれば(当たり判定が true なら)、ボールを非表示状態に設定しています。( ball_alive_flag = false; )

 

最後は描画処理です。
ball_alive_flag が true である場合にのみ、ボールを画面に描画しています。

/********* 画像の描画はこちらに *********/
public void drawGame()
{
    // 画面を白で塗りつぶします
    gc.clearScreen();

    // ボールが表示状態なら
    if( ball_alive_flag )
    {
        // img0.png を(ball_x, ball_y)に描画します
        gc.drawImage(0, ball_x, ball_y);
    }
}
	

跳ね返る度にボールの速度をランダムに変える

乱数という仕組みを使って、跳ね返るたびにボールの速度が変わるプログラムを書いてみましょう。

乱数

乱数とは、ランダムな数値(バラバラな数字)のことです。
要するに、サイコロと同じだと考えて下さい。

例えば、サイコロを振ると、1 〜 6 の数字のどれかを返します。
(つまり、サイコロは 1 〜 6 の乱数を生成しています。)
GameCanvas では、gc.rand(1, 6); と書くと、サイコロを一回振ったのと同じことになります。

以下のような感じで使用します。

// 受け取る変数を定義
int random_num;

(中略)

// gc.rand(1, 6); は 1 〜 6 のうちいずれかの値を返し、random_num はその値を保持する
random_num = gc.rand(1, 6);
	

実際に使ってみましょう。
ダウンロードした資料を解凍して、Sample02フォルダ直下にあるGame.javaを開いて下さい。

乱数を利用しているのは、初期化処理と更新処理の中身です。
まずは initGame の中身を見てください。

/********* 初期化の手順はこちらに *********/
public void initGame()
{
    // ボールの座標を初期化する
    ball_x = 0;
    ball_y = 0;

    // ボールの速度を 3 〜 6 のランダムな数字で初期化する
    ball_speed_x = gc.rand(3, 6);
    ball_speed_y = gc.rand(3, 6);

    // ボールのサイズを初期化する
    ball_size = 24;
}

太字の箇所が乱数を扱っている箇所です。
ball_speed_x = gc.rand(3, 6); で、ボールのX方向の速度を 3, 4, 5, 6 のどれかで初期化しています。ball_speed_y についても同様です。

続いて、updateGameを見ていきましょう。

/********* 物体の移動等の更新処理はこちらに *********/
public void updateGame()
{
    // X方向に ball_speed_x ずつ進める
    ball_x = ball_x + ball_speed_x;

    // Y方向に ball_speed_y ずつ進める
    ball_y = ball_y + ball_speed_y;

    // ボールが画面の左を越えた場合
    if(ball_x < 0)
    {
        // ボールのX方向の速度を 3 〜 6 のランダムな数字にする
        ball_speed_x = gc.rand(3, 6);
    }

    // ボールが画面の右を越えた場合
    if(ball_x > 640 - ball_size)
    {
        // ボールのX方向の速度を -3 〜 -6 のランダムな数字にする
        ball_speed_x = -gc.rand(3, 6);
    }
    // ボールが画面の上を越えた場合
    if(ball_y <0)
    {
        // ボールのY方向の速度を 3 〜 6 のランダムな数字にする
        ball_speed_y = gc.rand(3, 6);
    }

    // ボールが画面の下を越えた場合
    if(ball_y >> 480 - ball_size)
    {
        // ボールのY方向の速度を -3 〜 -6 のランダムな数字にする
        ball_speed_y = -gc.rand(3, 6);
    }
}

ボールが画面の左端を超えたら、右側に跳ね返らせなければならないため、gc.rand(3, 6) でボールのX方向の速度を 3, 4, 5, 6 のどれかにセットしています。
逆に、画面の右端を超えたら左側に跳ね返らせなければならないため、-gc.rand(3, 6) で、ボールのX方向の速度を -3, -4, -5, -6 のどれかにセットしています。
gc.rand(-6, -3) と書く事はできないので、gc.rand(3, 6) の結果にマイナスを付けることで、マイナスの乱数を作っています。

Y方向の速度についても、同じような処理を行っています。
画面の上端を超えたらボールのY方向の速度を 3 〜 6 のどれかいずれかとし、下端を超えたら -3 〜 -6 のいずれかとしています。

それでは、Sample02をコンパイルして実行してみましょう。
跳ね返るたびにボールの速さが変わっていることが確認できると思います。

課題

画面上のランダムな位置に正方形のブロックを10個表示して、マウスでクリックしたらそのブロックが消えるようなプログラムを作成してください。

Kadai01フォルダの中のGame.javaを元に、今回学んだマウス処理・乱数処理と、これまでに学んだ配列・for文を活用してプログラムを書いていきましょう。。
Kadai01フォルダの中のanswer01.jar ファイルを開くと、どのようにすれば良いか見ることができます。


図:課題の実行画面。バラバラな位置に10個のブロックが表示され、クリックするとそのブロックが消える

戻る