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 |