キー入力による操作を追加する
キャラクターを移動表示させることができたので、次はユーザーが自由に操作できるよう改造してみましょう。
ここでは、ゲームなどインタラクティブな操作に必要な入力を検出する方法について説明します。紹介するサンプルは、キャラクターをカーソルキーの[←]と[→]で、自由に移動させることができるというものです。
; 画像の読み込み buffer 1 ; ID1のバッファを初期化する picload "tinbear.bmp" ; 画像を読み込む gsel 0 ; ID0のバッファを操作する ; 変数の設定 x=220:y=100 ; X,Y座標 anim=0 ; アニメーションカウント ; メインループ repeat ; 無限に繰り返す redraw 0 ; 描画更新を無効にする gmode 0,640,480 ; コピーサイズを設定する color 216,233,236:boxf ; 背景を描画する gmode 0,200,300 ; コピーサイズを設定する pos x,y:gcopy 1,anim/4\8*200 ; 画像を描画する await 16 ; 一定時間待つ redraw 1 ; 描画内容を反映させる ; キーで動かす stick key,15 ; キー入力を行う if key&1 { ; 左のキーならば{}内を実行する x=x-2 : anim=anim+1 } if key&4 { ; 右のキーならば{}内を実行する x=x+2 : anim=anim+1 } x=limit( x, 0, 440 ) ; Xの範囲を決める loop ; 繰り返しの終わり
stick命令(キー入力情報取得)
HSPでは、キーの入力を検出するための命令としてgetkey
命令、onkey
命令などが用意されていますが、ここではstick
命令を使用しています。stick
命令は、ゲームなどでよく使われるカーソルキーなどの情報をまとめて取得するためのもので、次のようなパラメーターを記述できます。
stick p1,p2,p3
パラメータ | 説明 |
p1=変数 | 読み込むための変数 |
p2=0~(0) | 非トリガータイプキー指定 |
p3=0~1(1) | ウィンドウアクティブチェックのON/OFF |
stick
命令は、よく使われるキーボードおよびマウスボタンの状態をまとめてチェックして変数に代入します。stick
命令が実行されると、次のような複数のボタン情報がひとつの数値としてp1
で指定した変数に代入されます。
数値 | 対応するキーおよびマウス |
1 | [←]カーソルキー左 |
2 | [↑]カーソルキー上 |
4 | [→]カーソルキー右 |
8 | [↓]カーソルキー下 |
16 | [Space]キー |
32 | [Enter]キー |
64 | [Ctrl]キー |
128 | [Esc]キー |
256 | マウスの左ボタン |
512 | マウスの右ボタン |
1024 | [Tab]キー |
その他の場合は、以下のような処理になります。
- 何もボタンが押されていない場合…「0」が代入される。
- 複数のボタンが同時に押されていた場合…それらの数値がすべて加算される。
stick
命令は、通常ボタンが押された瞬間だけを検出します。ただし、p2
にキーコードを指定することで、ボタンが押されている間でもずっと検出されるようになります。
p3
でウィンドウがアクティブでない場合…入力を無効にする機能をON/OFFすることが可能。p3
が1か省略された場合…HSPウィンドウがアクティブでない場合にはキー入力が無効。p3
が0の場合…すべての状況下でキー入力を行う。
stick
命令で得られる値は、複数のキーをビット(2進数)単位で割り当てたものになっています。キーが押されているかどうかをif
命令で判断する場合には、同時に押されることを考慮してkey&1
のように&
(論理積)演算子を使うことが推奨されています。
ジョイスティックの利用
実際にゲームなどで入力を行う場合には、キーボードだけでなくゲームパッド(ジョイスティック)の入力を利用した方がよい場面も出てくると思います。その場合には、標準で同梱されているモジュール「mod_joystick.as」が利用できます。このモジュールを#include
命令によって追加することで、ゲームパッド入力を取得するためのjstick
命令が使用可能になります。詳しくは、HSPの「common」フォルダ内にある「mod_joystick.as」ファイルを参照してください。
「keymove.hsp」で使用しているlimit
関数は、HSP特有のもので、指定した範囲内の数値に丸める場合に利用します。
x=limit( x, 0, 440 )
という記述は、
if x<0 { x=0 } if x>440 { x=440 }
と同等になります。
タイルパターンの描画
2Dタイプのゲームなどでよく利用されるのが、格子状のマス目に合わせて決められた画像を配置する方法です。同じ画像をマス目ごとに配置したものを「タイルパターン」と呼び、決められたデータをもとに画像をマス目に配置したものを「マップ」と呼びます。
ここでは、基本となるタイルパターンを描画するサンプルを紹介します。
; 画像の読み込み buffer 1 ; ID1のバッファを初期化する picload "bg.bmp" ; 画像を読み込む gsel 0 ; ID0のバッファを操作する ; 変数の設定 bgx=0:bgy=0 ; 背景のX,Y座標 ; メインループ repeat ; 無限に繰り返す redraw 0 ; 描画更新を無効にする gmode 0,128,128 ; コピーサイズを設定する font msgothic,60,1 ; 文字フォントとサイズを設定 repeat 4 ; Y方向に4回繰り返す y=cnt*128-bgy ; Yの描画位置を計算する repeat 6 ; X方向に6回繰り返す x=cnt*128-bgx ; Xの描画位置を計算する pos x,y:gcopy 1 ; 画像を描画する loop ; 繰り返しの終わり(X) loop ; 繰り返しの終わり(Y) bgx=bgx+1 ; 背景の座標を移動させる if bgx>=128 { bgx=0 } ; 128以上の時は0に戻す color 100,160,255 ; 文字の色を設定する pos 140,200:mes "HSP3 Sample" ; 文字を描画する await 16 ; 一定時間待つ redraw 1 ; 描画内容を反映させる loop ; 繰り返しの終わり
このサンプルは、128×128ドットの画像(bg.bmp)を画面いっぱいに繰り返し配置しています。この画像が上下左右で違和感なくつながっている、いわゆる「シームレス」なパターンになっているのを利用して、背景が無限に流れ続けるような表現を行なっています。
タイルパターンを描画するしくみは単純なものです。repeat
~loop
命令による繰り返しを二重に行って、格子状のすべてのマス目座標に同じ画像がコピーされるようにしています。
マップを実現する場合には、2次元配列の変数を用意して、すべてのマス目に表示すべき画像を格納しておくとよいでしょう。基本的な考え方は、タイルパターンを描画する場合と同様です。