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

ボスキャラ の例

 次の例は、得点が100点になったらボスキャラが出るというものである。
 得点が100点になったら、すべて消去してボスが出るというのではなく、100点になったときの通常敵が消えた段階でボスが出るようにしている。変数bossfで0のときはボスなし、1のときは通常敵を新たに出さない、2のときにボスを出す、というようにしている。
 メインの処理を2通りにしてbossfが2以外のとき(通常敵)と2のとき(ボス)に分けている。この中で、ボスの処理(teki2_job)と自玉とボスの当たり判定(atari4)だけを変更している。teki2_jobはteki_jobを変更したものである。同じようにatari4はatari1を変更したものである。ボスキャラの情報のために変数を用意するのが面倒だったので、敵機の情報を格納する配列の0番を使用した。その結果、このような処理となった。
 ボスは得点が100点になったときに1度だけ出るだけである。

;shoot73.hsp
#define winx 50
#define winy 60
#define mm 8 ;間隔
#define xcls0 color 0, 0, 0 : boxf 0, 0, winx * mm - 1, winy * mm - 1
#define xcls1 color 0, 30, 50 : boxf winx * mm, 0

    ;初期設定 -----;配列宣言
    teki = 10 ;敵機の数
    dim tkx, teki : dim tky, teki ;敵機の座標
    dim tkdx ,teki : dim tkdy, teki ;敵機の移動量
    dim tkb, teki ;敵機の状態 0=あり、-1=なし
    dim tkg, teki ;敵機の画像
    tama = 10 ;自玉の数
    dim jtx, tama : dim jty, tama ;自玉の座標
    dim jtb, tama ;自玉の状態 0=あり、-1=なし
    tama2 = 5 ;敵玉の数
    dim ttx, tama2 : dim tty, tama2 ;敵玉の座標
    dim ttb, tama2
    ;敵玉の状態 0=あり、-1=なし;画像読み込み
    buffer 1
    picload "shoot.bmp"
    ;メインウィンドウ
    screen 0
    gmode 2, 32, 32
    title "シューティング・ゲーム" ;タイトルバー設定
    randomize ;乱数初期化
    goto *hiscr_read ;ハイスコアー読み込み
*ret1
    ;スタート -----
*start
    jiki = 3 ;自機残数
    tokuten = 0
    tkgg = 1 ;敵機画像番号
    bossf = 0 ;ボスキャラフラグ(0:なし/1:移行/2:出現)
    foreach tkb
        tkg(cnt) = tkgg ;敵機画像番号1
    loop
    gosub *title_disp ;タイトル表示
    gosub *jiki_disp ;自機残り表示
    gosub *score_disp ;得点表示
    gosub *hiscr_disp
    ;ハイスコアー表示;げーむMain -----
*restart
    ;ゲーム開始前の設定
    foreach tkb
        tkb(cnt) = -1 ;敵機状態、なし
    loop
    foreach jtb
        jtb(cnt) = -1 ;自玉状態、なし
    loop
    foreach ttb
        ttb(cnt) = -1 ;敵玉状態、なし
    loop
    jkx = 20 : jky = 55 ;自機の初期位置
    jkb = 0 ;自機の状態 0=あり、-1=なし
    gosub *restart_disp
    tekib = 0 ;敵機爆破数
    repeat
        redraw 0
        xcls0
        if bossf != 2 {
            ;敵機の処理
            gosub *teki_job
            ;自機移動
            pos jkx * mm , jky * mm
            gcopy 1, 0, 0
            ;キー入力
            gosub *key_input
            ;自玉移動
            gosub *tama_move
            ;敵玉移動
            gosub *tama_move2
            ;敵玉と自機、自玉の当たり判定・消去・残機減算表示
            gosub *atari3
            ;自玉と敵機の当たり判定・敵機消去・得点加算表示
            gosub *atari1
            ;自機と敵機の当たり判定・自機消去・残機減算表示
            gosub *atari2
        } else {
            ;ボス機の処理
            gosub *teki2_job
            ;自機移動
            pos jkx * mm , jky * mm
            gcopy 1, 0, 0
            ;キー入力
            gosub *key_input
            ;自玉移動
            gosub *tama_move
            ;敵玉移動
            gosub *tama_move2
            ;敵玉と自機、自玉の当たり判定・消去・残機減算表示
            gosub *atari3
            ;自玉と敵機の当たり判定・敵機消去・得点加算表示
            gosub *atari4
            ;自機と敵機の当たり判定・自機消去・残機減算表示
            gosub *atari2
        }

        if jkb = -1 : break ;自機状態なし
        redraw 1
        await 80
    loop
    ;ゲームオーバー判定
    if jiki > 0 : goto *restart ;自機の残数が0より大きいとき、げーむMainに移動
    goto *hiscr_write ;ハイスコアー書き込み
*owari
    gosub *hiscr_disp ;ハイスコアー表示
    dialog "ゲーム・オーバーです。\nもう一度しますか。", 2, "シューティング・ゲーム"
    if stat = 6 :goto *start
    end

;-------------------------
;ボス機の処理 -----
*teki2_job
    ;敵機の数(配列の個数)だけ繰り返す;敵機初期位置・移動量設定
    if tkb(0) = -1 {
        tkx(0) = rnd(winx - 4) + 1 ;x座標
        tky(0) = -4 ;y座標
        tkdx(0) = 0 ;移動量x
        tkdy(0) = 1 ;移動量y
        tkb(0) = 0 ;敵機状態
        tkg(0) = 3 ;敵機画像番号
        bosscnt = 0 ;*****
    }
    ;敵機移動
    pos tkx(0) * mm , tky(0) * mm
    gcopy 1, 32 * tkg(0), 0
    ;自機に向かわせる
    tkr = rnd(20) ;乱数発生0〜19
    if tkr = 0 { ;tkr=0
        if jkx - tkx(0) > 0: tkdx(0) = 1
        if jkx - tkx(0) < 0: tkdx(0) = -1
    }
    if tkr > 15 : tkdx(0) = 0 ;tkr=16,17,18,19
    if tky(0) < 10 {
        tkx(0) = tkx(0) + tkdx(0)
        tky(0) = tky(0) + tkdy(0)
    }
    ;ウィンドウ外
    ;if tky(0) >= winy : tkb(0) = -1 ;下枠
    ;if tkx(0) < 0 : tkb(0) = -1 ;左枠
    ;if tkx(0) > winx - 4 : tkb(0) = -1 ;右枠
    ;敵機爆破アニメーション
    if tkb(0) >= 1 {
        pos tkx(0) * mm , tky(0) * mm
        gcopy 1, (4 - tkb(0)) * 32, 32
        tkb(0) = tkb(0) - 1
        if tkb(0) = 0 : tkb(0) = -1
    }
    ;敵機玉発射             ←この部分
    tr = rnd(20)
    cnt1 = 0
    if tr = 1 {
        foreach ttb
            if ttb(cnt) = -1 & tkb(cnt1) = 0{
                ttx(cnt) = tkx(cnt1)
                tty(cnt) = tky(cnt1)
                ttb(cnt) = 0
                break
            }
        loop
    }
    return
;自玉とボス機の当たり判定・ボス機消去・得点加算表示 -----
*atari4
    foreach jtx ;自玉の個数分
        cnt1 = cnt
        if jtb(cnt) = -1 : continue
        if tkb(0) = 0 & abs(tky(0) - jty(cnt1) + 1) <= 2 & abs(tkx(0) - jtx(cnt1) + 1) <= 2 {
            jtb(cnt1) = -1 ;自玉消去
            bosscnt = bosscnt + 1
            if bosscnt > 20 {
            tkb(0) = 3 ;敵機消去(爆破)
            bossf = 0
        }
        tokuten = tokuten + 10 ;得点加算
        gosub *score_disp ;得点表示
    }
    loop
    return

;自玉と敵機の当たり判定・敵機消去・得点加算表示 -----
*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) = 3 ;敵機消去(爆破)
                tekib = tekib + 1 ;敵機爆破数加算
                if tekib = 100 {
                    jiki = jiki + 1 ;自機加算
                    if jiki > 5 : jiki = 5 ;自機数の制限
                    tekib = 0 ;敵機爆破数クリア
                    tkgg = tkgg \ 3 + 1 ;敵機画像変更
                    gosub *jiki_disp ;自機残り表示
                }
                tokuten = tokuten + 10 ;得点加算
                gosub *score_disp ;得点表示
                if tokuten = 100 : bossf = 1 ;*****
            }
        loop
    loop
    return
;敵機の処理 -----
*teki_job
    tksum = 0 ;*****
    foreach tkx
        tksum = tksum - tkb(cnt) ;*****
        if tksum = teki & bossf = 1 : bossf = 2 ;*****
        ;敵機の数(配列の個数)だけ繰り返す;敵機初期位置・移動量設定
        if tkb(cnt) = -1 & rnd(5) = 0 & bossf = 0 { ;*****
            tkx(cnt) = rnd(winx - 4) + 1 ;x座標
            tky(cnt) = -4 ;y座標
            tkdx(cnt) = 0 ;移動量x
            tkdy(cnt) = 1 ;移動量y
            tkb(cnt) = 0 ;敵機状態
            tkg(cnt) = tkgg ;敵機画像番号
        }
        ;敵機移動
    <<以下、略>>
 
<<ほかのサブルーチンは同じ>>
 


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

 

 

inserted by FC2 system