HSP3 ゲームのプログラミング
 シューティング・ゲーム制作 前へ 目次へ 次へ 

(5) 自玉の発射

サンプル(shoot14.hsp)
 自機から自玉を発射する。

 最大10発まで同時に画面上に表示されるようにする。

 自玉の座標(jtx, jty)、状態jtbは配列で格納し、敵機と同じように処理する。まず、自玉用の配列を宣言する。

    tama = 10        ;自玉の数
    dim jtx, tama : dim jty, tama    ;自玉の座標
    dim jtb, tama        ;自玉の状態 0=あり、-1=なし

 自玉状態jtbを-1で初期設定する。敵機状態の初期設定と同じ場所で行う。

    foreach jtb
        jtb(cnt) = -1    ;自玉状態、なし
    loop
 自玉の数tamaの値で配列の個数を設定している。この数が画面上に同時に表示される自玉の最大数となる。

 キー入力はサブルーチン*key_inputで受け取るようにしている。スペースキーも同じサブルーチン内で処理をする。
 スペースキーを押したとき、自玉状態がなし(-1) の自玉があれば、座標を設定して、自玉状態をあり(0)に設定する。自玉は自機の中央(jkx+1, jky-1)から発射させる。

;キー入力 -----
*key_input
    << 省略 >>
    if kk & 16 {        ;[SPACE]
        foreach jtx
            if jtb(cnt) = -1 {    ;自玉状態なしのとき
                jtx(cnt) = jkx + 1    ;x座標
                jty(cnt) = jky - 1    ;y座標
                jtb(cnt) = 0          ;自玉状態、あり
                break
            }
        loop
    }
    return

 最後に、自玉移動の処理をサブルーチン*tama_moveとして作成する。メインにサブルーチン*tama_moveの呼び出しを追加する。

        ;自玉移動
        gosub *tama_move
;自玉移動 -----
*tama_move
    foreach jtx
        if jtb(cnt) = 0 {    ;自玉状態ありのとき
            pos jtx(cnt) * mm, jty(cnt) * mm
            gcopy 1, 0, 32, 16, 16
            jty(cnt) = jty(cnt) - 1
            if jty(cnt) = -2 : jtb(cnt) = -1    ;上の壁を越えたとき自玉状態なしに設定
        }
    loop
    return

実行スペースキーを押すと自玉が発射される。画面上には最大で10発まで表示される。

 "gcopy 1, 0, 32, 16, 16"で自玉を描画している。自玉画像の開始座標が(0, 32)、画像サイズは16×16ドットである。別の自玉画像に変更することも可能である。
 次の"jty(cnt) = jty(cnt) - 1"で座標を計算している。



(6) 自玉と敵機の衝突判定

サンプル(shoot15.hsp)
 自玉と敵機の当たり判定を追加する。

 図のような状態で自玉と敵機の当たり判定をする。自玉の座標は(jtx,jty)、敵機の座標は(tkx,tky)の配列である。

・x座標
tkx-1 ≦jtx ≦ tkx+3  → tkx-1 ≦jtx
 → jtx ≦ tkx+3
 → tkx-jtx ≦1
 → -3 ≦ tkx-jtx
 → tkx-jtx+1 ≦1+1
 → -3+1 ≦ tkx-jtx+1
 → tkx-jtx+1 ≦2
 → -2 ≦ tkx-jtx+1
 → abs(tkx-jtx+1) <= 2
・y座標
tky ≦ jty ≦ tky+4  → tky ≦ jty
 → jty ≦ tky+3
 → tky-jty ≦ 0
 → -3 ≦ tky-jty
 → tky-jty+1.5 ≦ 0+1.5
 → -3+1.5 ≦ tky-jty+1.5
 → tky-jty+1.5 ≦ 1.5
 → -1.5 ≦ tky-jty+1.5
 → (整数のみ)  → abs(tky-jty+1) <= 2
 座標を格納している変数は整数型なので、実数1.5を加算しても小数以下は無視される、すなわち、整数型の変数に1.5を加算しても1を加算したことになる。abs(tky-jty+1) <= 2とすることで、図のような判定範囲になる。

 自玉、敵機ともに複数あるので当たり判定には二重ループを使用する。

−− foreach jtx     ;Loop1  自玉の個数分(配列の個数分)繰り返す
−−foreach tkx  ;Loop2  敵機の個数分(配列の個数分)繰り返す




     座標(jtx(Loop1)とtkx(Loop2)、jty(Loop1)とtky(Loop2))の比較
       自玉を消去する
       敵機を消去する
−−loop   ;Loop2の終端
−− loop      ;Loop1の終端

 ループのカウントはシステム変数cntで参照できる。しかし、二重ループでは外側(Loop1)のカウントが参照できないので、配列jtx,jtyの添字が必要になる。そこで、2つ目のループに入る前に1つ目のループのカウントを別の変数に記憶しておく。
 自玉の消去と敵機の消去は、配列変数tmb, tkbに状態なしである-1を格納するだけである。

 自玉と敵機の当たり判定の処理をサブルーチン*atari1として作成する。メインにサブルーチン*atari1の呼び出しを追加する。

        ;自玉と敵機の当たり判定・敵機消去・得点加算表示
        gosub *atari1
;自玉と敵機の当たり判定・敵機消去・得点加算表示 -----
*atari1
    foreach jtx    ;自玉の個数分
        cnt1 = cnt
        if jtb(cnt) = -1 : continue
        foreach tkx    ;敵機の個数分
            if tkb(cnt) = 0 & abs(tky(cnt) - jty(cnt1) + 1) <= 2 & abs(tkx(cnt) - jtx(cnt1) + 1) <= 2 {
                jtb(cnt1) = -1    ;自玉消去
                tkb(cnt) = -1     ;敵機消去(爆破)
            }
        loop
    loop
    return



課題(shoot65.hsp)
 「自玉の発射」と「自玉と敵機の衝突判定」の処理を追加する。また、実行したり、自機が爆破した後、すぐにゲームが始まる。次に示すサブルーチンを追加して、ゲーム領域に「START」と表示してからゲームが始まるようにする。

;スタート表示 -----
*restart_disp
    xcls0
    font "MS ゴシック", 18, 1
    color 200, 200, 200
    pos 18 * mm, 28 * mm
    mes "START"
    wait 100
    return


(リスト)


 シューティング・ゲーム制作 前へ 目次へ 次へ 
2007 © Hiroshi Masuda

 

 

inserted by FC2 system