スクリプト言語の HSP については、公式ホームページの「HSPTV!」をどうぞ。
なお、このページはシューティング・ゲームのミニ講座シリーズの1つです。
今回は第2回「自機の操作」について説明します。(戻る)
キーボードの検出
自機を移動する方法は、キーボード、マウス、ジョイパッドなどがあります。
今回は処理を簡単にするため、キーボード操作のみに限定します。
HSPにはキーボードの入力チェックに getkey 命令、stick 命令の2つが用意されてます。
どちらも押されてるキーボードをチェックできますが、1回の呼び出しで必要キーの全てを取得できる stick 命令を使います。
この命令は、カーソル・キー(4個)、特殊キー(5個)、マウス・ボタン(2個)を1回の呼び出しでチェックできます。
特殊キーは、ゲームで良く使われる[SPC]キー、[ENTER]キー、[CTRL]キー、[ESC]キー、[TAB]キーが含まれます。
この命令は、押されてるか、押されてないかを 0 と 1 のビットデータで返します。
チェックする場合は、ビットデータを2進数(バイナリ値)の考えで 0 と 1 を調べます。
まずは、次の一覧をご覧ください。
押されてるキー | 変数の値 | |||
---|---|---|---|---|
種類 | キーボード | 2進表記 | 10進表記 | 16進表記 |
カーソル・キー 「左上/右下」と覚えよう |
[←]キー(左) | %00000000001 | 1 | $001 |
[↑]キー(上) | %00000000010 | 2 | $002 | |
[→]キー(右) | %00000000100 | 4 | $004 | |
[↓]キー(下) | %00000001000 | 8 | $008 | |
特殊キー 「SOURCE」と覚えよう |
[SPC]キー(Space) | %00000010000 | 16 | $010 |
[RET]キー(Enter) | %00000100000 | 32 | $020 | |
[CTRL]キー(Control) | %00001000000 | 64 | $040 | |
[ESC]キー(Escape) | %00010000000 | 128 | $080 | |
マウス・ボタン 「左右」と覚えよう |
マウスの[左]ボタン | %00100000000 | 256 | $100 |
マウスの[右]ボタン | %01000000000 | 512 | $200 | |
特殊キー | [TAB]キー(Tab) | %10000000000 | 1024 | $400 |
上記の一覧は[←]キー、[↑]キー、[SPC]キーの3つが同時に押されてると次の値が変数に代入されてます。
- 2進数で解釈すると「%00000010011」の値が変数にセットされる。
- 10進数で解釈すると「19」の値が変数にセットされる。
- 16進数で解釈すると「$013」の値が変数にセットされる。
上記の「19」とは、「1+2+16」の値ですよ。
この「19」を2進数で表現すると「%00000010011」、16進数で表現すると「$013」となるのです。
チェックするときは、ビット論理積の「&」演算子、または「and」マクロ演算子を使います。
等号の「=」演算子を使うと1つしかキーが押されてない時しかチェックできません。
この方法が意図的なものなら良いのですが、通常は複数のキーをチェックするので「=」演算子は使いません。
stick命令のテスト
それでは、以下のサンプルを試してみましょう。
[←][↑][→][↓]キー、[SPC][RET][CTRL][ESC][TAB]キー、[左]ボタン、[右]ボタンを押すことで表示が変わります。
同時に複数のキーを押すと複数の表示になりますよね。
これで複数のキーをチェックできます。
*Main screen 0,600,400,SCREEN_FIXEDSIZE font MSGOTHIC,20 repeat redraw 0 color $00,$00,$00:boxf color $00,$FF,$00 stick key,$7FF if(key & %00000000001):pos 0, 0:mes " 1:[←]キー" if(key & %00000000010):pos 0, 20:mes " 2:[↑]キー" if(key & %00000000100):pos 0, 40:mes " 4:[→]キー" if(key & %00000001000):pos 0, 60:mes " 8:[↓]キー" if(key & %00000010000):pos 0, 80:mes " 16:[SPC]キー" if(key & %00000100000):pos 0,100:mes " 32:[RET]キー" if(key & %00001000000):pos 0,120:mes " 64:[CTRL]キー" if(key & %00010000000):pos 0,140:mes " 128:[ESC]キー" if(key & %00100000000):pos 0,160:mes " 256:[左]ボタン" if(key & %01000000000):pos 0,180:mes " 512:[右]ボタン" if(key & %10000000000):pos 0,200:mes "1024:[TAB]キー" redraw 1 await (1000/60) loop stop
上記のソースでは、key 変数のチェックに2進数を使ってます。
その他にも10進数、16進数でも同じことが出来ます。
16進数の記述
stick key,$7FF if(key & $001):pos 0, 0:mes " 1:[←]キー" if(key & $002):pos 0, 20:mes " 2:[↑]キー" if(key & $004):pos 0, 40:mes " 4:[→]キー" if(key & $008):pos 0, 60:mes " 8:[↓]キー" if(key & $010):pos 0, 80:mes " 16:[SPC]キー" if(key & $020):pos 0,100:mes " 32:[RET]キー" if(key & $040):pos 0,120:mes " 64:[CTRL]キー" if(key & $080):pos 0,140:mes " 128:[ESC]キー" if(key & $100):pos 0,160:mes " 256:[左]ボタン" if(key & $200):pos 0,180:mes " 512:[右]ボタン" if(key & $400):pos 0,200:mes "1024:[TAB]キー"
10進数の記述
stick key,$7FF if(key & 1):pos 0, 0:mes " 1:[←]キー" if(key & 2):pos 0, 20:mes " 2:[↑]キー" if(key & 4):pos 0, 40:mes " 4:[→]キー" if(key & 8):pos 0, 60:mes " 8:[↓]キー" if(key & 16):pos 0, 80:mes " 16:[SPC]キー" if(key & 32):pos 0,100:mes " 32:[RET]キー" if(key & 64):pos 0,120:mes " 64:[CTRL]キー" if(key & 128):pos 0,140:mes " 128:[ESC]キー" if(key & 256):pos 0,160:mes " 256:[左]ボタン" if(key & 512):pos 0,180:mes " 512:[右]ボタン" if(key & 1024):pos 0,200:mes "1024:[TAB]キー"
また、一般的にはカーソル・キー部分を次のように記述してます。
一般的な記述
stick key,15 if(key&1):[←]キーの処理 if(key&2):[↑]キーの処理 if(key&4):[→]キーの処理 if(key&8):[↓]キーの処理
それから stick 命令の第2引数は、非トリガー・タイプのキーをビットデータで指定します。
この非トリガー・タイプとは、押しっぱなし状態でもキーボードが押されてるか検出できる点です。
そのためカーソル・キーなどの場合は、押しっぱなし状態でも検出可能にするために 15 を指定しましょう。
この 15 の値は 1+2+4+8 の合計で10進数を意味し、2進数ならば「%1111」、16進数ならば「$F」となります。
なお、自機ショット(弾丸)の発射は、キーボードを押した瞬間だけ単発で打ちたいことがあります。
このような場合にはトリガー・タイプですから第2引数の非トリガー・タイプを指定しません。
つまり、指定しないとキーボードを押した瞬間の1回だけを検出するのが基本となります。
自機の移動
それでは本題のカーソル・キーによる自機の移動を考えてみます。
全体的には、次のような感じです。
- [←]キーが押されてるかチェック → 横軸の変数(x)を減少
- [→]キーが押されてるかチェック → 横軸の変数(x)を増加
- [↑]キーが押されてるかチェック → 縦軸の変数(y)を減少
- [↓]キーが押されてるかチェック → 縦軸の変数(y)を増加
*Main screen 0,600,400,SCREEN_FIXEDSIZE font MSGOTHIC,50 repeat redraw 0stick key,%1111 if(key&1):x-=5 if(key&2):y-=5 if(key&4):x+=5 if(key&8):y+=5color $00,$00,$00:boxf color $00,$FF,$00:pos x,y:mes "山" redraw 1 await (1000/60) loop stop
どうですか?
これで自機が画面を自由自在に動き回れますね。
しかし、ずっと移動し続けると画面から消えてしまいます。
そこで画面外に移動したら画面内に座標を戻す処理を追加してみましょう。
画面外の補正
*Main screen 0,600,400,SCREEN_FIXEDSIZE font MSGOTHIC,50 repeat redraw 0 stick key,%1111if(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=350color $00,$00,$00:boxf color $00,$FF,$00:pos x,y:mes "山" redraw 1 await (1000/60) loop stop
上記の[←]キーの処理だけを考えると次のようになります。
- [←]キーが押されてるかチェック
- 横軸の変数(x)を減少
- 横軸の変数(x)が画面左端から消えたかチェック
- 横軸の変数(x)に画面左端を意味する 0 をセット
フローチャート
全体のフローチャートは次のようになります。
- [←]キーが押されてるかチェック
- 横軸の変数(x)を減少
- 横軸の変数(x)が画面左端から消えたかチェック
- 横軸の変数(x)に画面左端を意味する 0 をセット
- [↑]キーが押されてるかチェック
- 縦軸の変数(y)を減少
- 縦軸の変数(y)が画面上部から消えたかチェック
- 縦軸の変数(y)に画面上部を意味する 0 をセット
- [→]キーが押されてるかチェック
- 横軸の変数(x)を増加
- 横軸の変数(x)が画面右端から消えたかチェック
- 横軸の変数(x)に画面右端を意味する 550 をセット
- [↓]キーが押されてるかチェック
- 縦軸の変数(y)を増加
- 縦軸の変数(y)が画面下部から消えたかチェック
- 縦軸の変数(y)に画面下部を意味する 350 をセット
自機の操作
それでは第2回目の「自機の操作」ソースを紹介します。
//------------------------------------------------------------------------------ // シューティング・ゲームのミニ講座 for HSP(Ver.3.3.2) //============================================================================== // 第2回「自機の操作」by 科学太郎 //------------------------------------------------------------------------------ //-------------------------------------- // メイン部 //-------------------------------------- *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 color $00,$00,$00:boxf color $00,$FF,$00:pos x,y:mes "山" redraw 1 await (1000/60) loop stop //------------------------------------------------------------------------------ // End of lesson-2.hsp //------------------------------------------------------------------------------
上記のソースで x-=5 という記述は x=x-5 と同じ処理です。
これは変数(x)の内容を -5 するという意味で、C/C++言語の複合代入と呼ばれる演算子です。
HSPでも、この省略された記述が許されてるので便利に使いましょう。
それから 600 ではなく 550 で比較してるのは、自機を表す「山」文字の左上隅が座標になってます。
そのため自機の横サイズである 50 を画面の横サイズ 600 から引いた 550 という値で比較するのです。
同様に、自機の縦サイズである 50 を画面の縦サイズ 400 から引いた 350 という値で比較します。
これで「自機の操作」は終わります。
次はスペース・キーで「弾丸の発射」を紹介します。(次を読む)
※コメント投稿者のブログIDはブログ作成者のみに通知されます