HSP3 ゲームのプログラミング
 レース・ゲーム制作 前へ 目次へ 次へ 

(2) キャラクタ移動と着順判定

 前のサンプルでは、キャラクタの移動量を1に固定していた。ある時は1、ある時は2、というように移動量を変えるため、乱数を使う。
 HSPの乱数は、randomize命令で初期化して、rnd()関数で乱数を取り出す。例えば、rnd(5)とすると0〜4の整数値を取り出すことができる。
 ここでは、移動量を1または2とする。rnd(2)とすると、0または1の整数値が取り出せる。これに1を加算すれば1または2の値になる。これを移動量として加算する。式は次のようになる。

chx(cnt) += 1 + rnd(2)  (chx(cnt) = chx(cnt) + 1 + rnd(2)と同じ)

サンプルrace02.hsp
 移動量を1または2としてプログラムを作成する。

;race02.hsp
    screen 0, 640, 480
    randomize    ;乱数初期化
    ;配列宣言、データ初期化
    char_max = 8
    dim chx, char_max
    dim chy, char_max
    foreach chx
        chx(cnt) = 0
        chy(cnt) = cnt  ;コース
    loop
    repeat
        redraw 0
        color 255, 255, 255 : boxf      ;画面消去
        ;コース描画
        color 0, 0, 0
        repeat char_max + 1
            y = cnt * 20 + 10
            line 100, y, 600, y
        loop
        line 100, 10, 100, 170
        line 600, 10, 600, 170
        ;キャラクタ移動・ゴール判定
        foreach chx
            x = 600 - chx(cnt) * 5 - 20         ;x座標変換
            y = chy(cnt) * 20 + 10              ;y座標変換
            hsvcolor cnt * 23, 255, 255
            circle x + 2, y + 2, x + 18, y + 18         ;キャラクタ描画
            chx(cnt) += 1 + rnd(2)   ;移動量加算
        loop
        if chx(7) > 99 : break
        redraw 1
        ;if ゴールした : break
        await 200
    loop
    stop

実行8個のキャラクタが移動する。進むスピードに差がつく。

 乱数の初期化命令randomizeがなくても動作はするが、毎回同じ結果になる。rnd()関数はある値を元に計算によって求められているので、そのある値が同じであれば同じ順序で乱数が作られるからである。

○ 着順判定

 着順を格納する配列chjをキャラクタ数分用意する。
 ゴールはマス目(chx)の数が99を超えたときである。99を超えたものから順に1位、2位、3位…と順位を格納していく。今は同着については考えないことにする。すべてのキャラクタに順位がついたら、順位を表示して終了する。

サンプルrace03.hsp
 レース後、着順を表示するプログラムを作成する。

;race03.hsp
    screen 0, 640, 480
    randomize    ;乱数初期化;
    ;配列宣言、データ初期化
    char_max = 8
    dim chx, char_max
    dim chy, char_max
    dim chj, char_max    ;着順
    foreach chx
        chx(cnt) = 0
        chy(cnt) = cnt  ;コース
    loop
    juni = 1    ;順位
    repeat
        redraw 0
        color 255, 255, 255 : boxf      ;画面消去;
        ;コース描画
        color 0, 0, 0
        repeat char_max + 1
            y = cnt * 20 + 10
            line 100, y, 600, y
        loop
        line 100, 10, 100, 170
        line 600, 10, 600, 170
        ;キャラクタ移動・ゴール判定
        foreach chx
            x = 600 - chx(cnt) * 5 - 20         ;x座標変換
            y = chy(cnt) * 20 + 10              ;y座標変換
            hsvcolor cnt * 23, 255, 255
            circle x + 2, y + 2, x + 18, y + 18         ;キャラクタ描画
            chx(cnt) += 1 + rnd(2)   ;移動量加算
            if chx(cnt) > 99 and chj(cnt) = 0 {    ;ゴールした
                chj(cnt) = juni    ;順位格納
                juni += 1          ;順位加算
            }
        loop
        redraw 1
        ;すべてがゴールした
        if juni = 9 : break
        await 200
    loop
    ;着順表示
    color 0, 0, 0
    pos 50, 200
    foreach chj
        mes "" + (cnt + 1) + "号車->" + chj(cnt) + "着"
    loop
    stop

実行1号車(コース)から順に順位が表示される。

 着順はコース番号の小さい方から判定するので、同着の場合はコース番号の小さい方が早いと判定される。
 着順の結果は、1着から順に表示した方が見やすい。

サンプルrace04.hsp
 着順の処理を変更して1着から順に表示されるようにする。

        ;キャラクタ移動・ゴール判定
        foreach chx
            x = 600 - chx(cnt) * 5 - 20         ;x座標変換
            y = chy(cnt) * 20 + 10              ;y座標変換
            hsvcolor cnt * 23, 255, 255
            circle x + 2, y + 2, x + 18, y + 18         ;キャラクタ描画
            chx(cnt) += 1 + rnd(2)  ;移動量加算
            if chx(cnt) > 99 and chx(cnt) < 102 {    ;ゴールした
                chj(juni - 1) = cnt + 1    ;順位格納
                chx(cnt) = 102
                juni += 1          ;順位加算
            }
        loop
        redraw 1
        if juni = 9 : break
        await 200
    loop
    ;着順表示
    color 0, 0, 0
    pos 50, 200
    foreach chj
        mes "" + (cnt + 1) + "着->" + chj(cnt) + "号車"
    loop
    stop

実行1着から順に結果が表示される。

 マス目が100または101のときだけゴールしたと判定する。これは、移動量として1または2を加算しているからである。ゴールした後、移動量を加算すると102以上になる。
 前のサンプルでも、同じようなゴール判定が使える。(if文と式chx(cnt)=102)


試してみようキャラクタの差がもっと少なくなるようにする。

 移動量加算の式のrnd(2)が0または1になるため、1 + rnd(2)が1または2になる。rnd(2)が1になる確率を減らせば差が少なくなるはずである。
 rnd(10)とすれば0〜9の整数が得られる。これを9で割れば、すなわち、rnd(10) / 9とすればrnd(10)が9のときだけ1になる。9以外のときは0である。これはrnd(10)も9も整数なので計算結果も整数になるためである。

chx(cnt) += 1 + rnd(10) / 9     ;移動量加算

 乱数rnd(10)では0〜9の10個の値がそれぞれ同じ確率で現れる。つまり、rnd(10)で9が現れる確率は10%ということになる。ということは、移動量が2になるのは全体の10%ということになる。
 計算式を工夫すれば、いろいろな確率(%)で移動量を変えることができる。

 rnd(20) / 19 … 確率1/20 = 5%
 rnd(100) / 80 … 確率20/100 = 20% (rnd(10) / 8 でも同じ)

 分母の数を大きくする方が、ばらつきが大きくなるので確率も計算値に近いものになる。


 レース・ゲーム制作 前へ 目次へ 次へ 
2007 © Hiroshi Masuda 

 

 

inserted by FC2 system