スクリプト言語の HSP については、公式ホームページの「HSPTV!」をどうぞ。
なお、このページはシューティング・ゲームのミニ講座シリーズの1つです。
今回は第3回「弾丸の発射」について説明します。(戻る)
弾丸の管理
自機の弾丸は、最大10個発射できることを考えてみます。
まずは弾丸の横軸(x)、縦軸(y)は絶対に必要なので、この2つを配列で管理します。
さらに弾丸の配列が、画面内を移動中(有効)か、画面外に外れた(無効)かを判定するフラグ(flag)も必要になりますね。
それでは3つを配列で管理すると次のようになります。
dim tamaF,10 dim tamaX,10 dim tamaY,10
上記の3つの配列は次の意味があります。
- tamaF は、弾丸の有無フラグで 0 なら無効、1 なら有効を意味
- tamaX は、弾丸の横軸で 0 ~ 550 の値を管理(弾丸の横サイズが 50 の場合)
- tamaY は、弾丸の縦軸で 0 ~ 350 の値を管理(弾丸の縦サイズが 50 の場合)
弾丸の処理
弾丸を処理するには、弾丸の発射、移動、描画の最低でも3つの処理が必要です。
今回は、弾丸の発生部(TamaBirth)、弾丸の描画部(TamaDraw)の2つをサブルーチンにします。
なお、弾丸の移動は描画部(TamaDraw)処理と一緒に記述して、サブルーチンの数を減らしてみます。
それでは前回の「自機の操作」ソースに追加してみましょう。
*Init dim tamaF,10 dim tamaX,10 dim tamaY,10*Main screen 0,600,400,SCREEN_FIXEDSIZE font MSGOTHIC,50 repeat redraw 0 stick key,%1111 if(key&1):x-=5:if(x<0):x=0 if(key&2):y-=5:if(y<0):y=0 if(key&4):x+=5:if(x>550):x=550 if(key&8):y+=5:if(y>350):y=350if(key&16):gosub *TamaBirthcolor $00,$00,$00:boxf color $00,$FF,$00:pos x,y:mes "山"gosub *TamaDrawredraw 1 await (1000/60) loop stop*TamaBirth ; ;記述 ; return *TamaDraw ; ;記述 ; return
とりあえず、上記の4カ所を追加します。
弾丸の発生
それでは、弾丸の発生ルーチン(TamaBirth)を考えてみましょう。
弾丸の発生手順は、次のようになると思います。
- tamaF 配列から弾丸情報が無効である場所を探す
- 無効領域が見つかったら弾丸を発生(a)~(c)を行う
- 弾丸の有無フラグに 1 をセット
- 弾丸の横軸(x)に自機の x をセット
- 弾丸の縦軸(y)に自機の y をセット
- 繰り返しを抜ける
*TamaBirth foreach tamaF if(tamaF(cnt)==0){ tamaF(cnt)=1 tamaX(cnt)=x tamaY(cnt)=y break } loop return
上記のように tamaF 配列の分だけ繰り返す場合は repeat 命令よりも foreach 命令が便利です。
たったのこれだけで、無効領域に有効な弾丸情報をセットして、新しい弾丸を発生できます。
どうですか?
以外にも簡単ですね。
これで「弾丸の発生」は終わりですよ。
弾丸の描画
続いて、弾丸の描画ルーチン(TamaDraw)を考えてみましょう。
こちらは、弾丸の移動も含まれますので、先に移動処理、続いて描画処理を行います。
- tamaF 配列から弾丸情報が有効である場所を探す
- 有効領域が見つかったら弾丸の移動(a)~(d)を行う
- 弾丸の縦軸(y)から 8 ドット引く
- 弾丸の縦軸(y)が画面外に外れたかチェック
- 画面外に外れた場合は、弾丸の有無フラグに 0 をセット
- 次の繰り返しへジャンプ(continue)
- 弾丸の描画位置を設定(pos)
- 弾丸の描画色を設定(color)
- 弾丸の文字を描画(mes)
*TamaDraw foreach tamaF if tamaF(cnt){ tamaY(cnt)-=8:if(tamaY(cnt)<-50):tamaF(cnt)=0:continue pos tamaX(cnt),tamaY(cnt) color $FF,$FF,$00:mes ":" } loop return
上記のソースで continue 命令がありますが、これを実行すると次の繰り返し処理にジャンプします。
そのため次の行の pos 命令、color 命令、mes 命令は実行されません。
これで「弾丸の移動」+「弾丸の描画」は終わりですね。
弾丸の発射
それでは第3回目の「弾丸の発射」ソースを紹介します。
//------------------------------------------------------------------------------ // シューティング・ゲームのミニ講座 for HSP(Ver.3.3.2) //============================================================================== // 第3回「弾丸の発射」by 科学太郎 //------------------------------------------------------------------------------ //-------------------------------------- // メイン部 //-------------------------------------- *Init ;弾丸の管理 dim tamaF,10 dim tamaX,10 dim tamaY,10 *Main screen 0,600,400,SCREEN_FIXEDSIZE font MSGOTHIC,50 repeat redraw 0 stick key,%1111 if(key&1):x-=5:if(x<0):x=0 if(key&2):y-=5:if(y<0):y=0 if(key&4):x+=5:if(x>550):x=550 if(key&8):y+=5:if(y>350):y=350 if(key&16):gosub *TamaBirth color $00,$00,$00:boxf color $00,$FF,$00:pos x,y:mes "山" gosub *TamaDraw redraw 1 await (1000/60) loop stop //-------------------------------------- // 弾丸の発生 //-------------------------------------- *TamaBirth foreach tamaF if(tamaF(cnt)==0){ tamaF(cnt)=1 tamaX(cnt)=x tamaY(cnt)=y break } loop return //-------------------------------------- // 弾丸の描画 //-------------------------------------- *TamaDraw foreach tamaF if tamaF(cnt){ tamaY(cnt)-=8:if(tamaY(cnt)<-50):tamaF(cnt)=0:continue pos tamaX(cnt),tamaY(cnt) color $FF,$FF,$00:mes ":" } loop return //------------------------------------------------------------------------------ // End of lesson-3.hsp //------------------------------------------------------------------------------
上記のソースを実行すると[SPACE]キーを押すことで、1発だけ弾丸が発射されますね。
これは stick 命令で[SPACE]キーがトリガー・タイプなので単発なのです。
弾丸の連射
それでは連射する場合は、どうすれば良いでしょうか。
とりあえず、単純に[SPACE]キーを非トリガー・タイプにしてみましょう。
repeat redraw 0stick key,%11111if(key&1):x-=5:if(x<0):x=0 if(key&2):y-=5:if(y<0):y=0 if(key&4):x+=5:if(x>550):x=550 if(key&8):y+=5:if(y>350):y=350 if(key&16):gosub *TamaBirth color $00,$00,$00:boxf color $00,$FF,$00:pos x,y:mes "山" gosub *TamaDraw redraw 1 await (1000/60) loop
変更箇所は1カ所です。
メイン部の stick 命令の第2引数を「%1111」から「%11111」に変更してみました。
それでは、実行して見ましょう。
どうですか?
期待通りでしたか。
なぜかレーザのような弾丸が一気に発射されちゃいましたね。
あらら。何これ。という感じでしょうか。
このように一気に弾丸が発射されるのは[SPACE]キーが押しっぱなしの場合は、連続して発射されてるからですよ。
だって連射だもの。ね。おかしくはないでしょう。
でも、期待通りではないよね。
弾丸の間隔
それでは、期待通りの連射とは何か。考えてみましょう。
まずは、1個おきに弾丸が発射されるように改良しましょう。
改良する部分は TamaBirth のサブルーチンのみで行います。
*TamaBirthif(tamaTrigg):tamaTrigg--:returnforeach tamaF if(tamaF(cnt)==0){ tamaF(cnt)=1 tamaX(cnt)=x tamaY(cnt)=y break } looptamaTrigg=2return
上記の2カ所だけ追加します。
これで tamaTrigg 変数が 0 以外の場合は、デクリメントしてサブルーチンを終わります。
そして tamaTrigg 変数が 0 のみの場合は、弾丸を1発だけ発射しますね。
弾丸の発射が終わったら tamaTrigg 変数に 2 をセットします。
これで2サイクルで1回だけ弾丸が発射されるわけです。
でも、まだ、まだ、発射間隔が短すぎて一気に10発も発射されてますね。
それでは tamaTrigg 変数に 3、4、5、… 60 と発射間隔を多くしてみましょう。
5 ~ 10 当たりが丁度良さそうですが 15 もお気に入りの間隔です。
なお、60 にすると1秒間に1回しか弾丸が発射されず期待外れになります。
この発射間隔は、お好みで設定して欲しいと思います。
とりあえず、ミニ講座では 8 に設定しておきますよ。
弾丸の連射
それでは第3回目の「弾丸の連射」ソースを紹介します。
//------------------------------------------------------------------------------ // シューティング・ゲームのミニ講座 for HSP(Ver.3.3.2) //============================================================================== // 第3回「弾丸の発射」by 科学太郎 //------------------------------------------------------------------------------ //-------------------------------------- // メイン部 //-------------------------------------- *Init ;弾丸の管理 dim tamaF,10 dim tamaX,10 dim tamaY,10 *Main screen 0,600,400,SCREEN_FIXEDSIZE font MSGOTHIC,50 repeat redraw 0 stick key,%11111 if(key&1):x-=5:if(x<0):x=0 if(key&2):y-=5:if(y<0):y=0 if(key&4):x+=5:if(x>550):x=550 if(key&8):y+=5:if(y>350):y=350 if(key&16):gosub *TamaBirth color $00,$00,$00:boxf color $00,$FF,$00:pos x,y:mes "山" gosub *TamaDraw redraw 1 await (1000/60) loop stop //-------------------------------------- // 弾丸の発生 //-------------------------------------- *TamaBirth if(tamaTrigg):tamaTrigg--:return foreach tamaF if(tamaF(cnt)==0){ tamaF(cnt)=1 tamaX(cnt)=x tamaY(cnt)=y break } loop tamaTrigg=8 return //-------------------------------------- // 弾丸の描画 //-------------------------------------- *TamaDraw foreach tamaF if tamaF(cnt){ tamaY(cnt)-=8:if(tamaY(cnt)<-50):tamaF(cnt)=0:continue pos tamaX(cnt),tamaY(cnt) color $FF,$FF,$00:mes ":" } loop return //------------------------------------------------------------------------------ // End of lesson-3.hsp //------------------------------------------------------------------------------
これで「弾丸の発射」は終わります。
次は自動的に敵機が発生する「敵機の表示」を紹介します。(次を読む)
※コメント投稿者のブログIDはブログ作成者のみに通知されます