ジョイスティックからの入力取得


●ウインドウズの命令を利用する前段取り

ジョイスティックに関する命令は
DELPHI自体には実装されていない。
ウインドウズのOSにあるAPIというものに
直接指令してやらなければいけない。
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
UNITの最初のほうにusesという文がある。
これはどんなシステムを使うのか?
ということが書いてある部分である。

ここの最後にMMSystemという文字列を加え
Dialogs, MMSystem;
という形にする。

●まずは受け取った内容を直接表示

前準備にタイマーコンポーネントを貼り付け
インターバル時間を20に設定しておく。
private
{ Private 宣言 }
num :Integer; //この行を追加。表示用変数
JoyInfo: TJOYINFO; //この行を追加。ジョイスティック入力用

〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
procedure TForm1.FormCreate(Sender: TObject);
begin
num :=0; //NUMの初期化
Timer1.Enabled := True; //タイマーイベントを有効にする。
end;


procedure TForm1.Timer1Timer(Sender: TObject);
begin

 joyGetPos(JOYSTICKID1, @JoyInfo);//これが入力命令

num :=JoyInfo.wXpos; //横移動の数値を取り込み
Caption:=IntToStr(num); //値を文字列にして上のバーに表示
end;
joyGetPos(JOYSTICKID1, @JoyInfo);

ここの部分でジョイスティック1の入力を受け取っている。
横方向の結果はJoyInfo.wXposで出てくる。
縦方向ならJoyInfo.wYposで。

値を上のバーに表示してみればわかるが
入力があると0から65536までの数値が入る。
これはアナログスティックからの入力を考慮しているから。

●スティック入力を使いやすい値に

procedure TForm1.Timer1Timer(Sender: TObject);
begin

joyGetPos(JOYSTICKID1, @JoyInfo);

num :=0; //最初にリセット

if JoyInfo.wXpos < (65535*0.1) then //左入力
begin
num :=-1;
end
else if JoyInfo.wXpos > (65535*0.9) then //右入力
begin
num :=+1;
end;

Caption:=IntToStr(num); //値を文字列にして上のバーに表示

end;
入力無しで0。左を入力すれば-1。右で1が表示されるはず。

XYの両方で使えるようにすれば十字キーの入力は完成。

●ボタンの内容の直接表示

ボタンの場合も直接値を表示させると少し変わった数値が出てくる。
procedure TForm1.Timer1Timer(Sender: TObject);
begin

joyGetPos(JOYSTICKID1, @JoyInfo);

num :=JoyInfo.wButtons; //ボタンの内容をNUMに

Caption:=IntToStr(num); //値を文字列にして上のバーに表示

end;
ボタン1で1。ボタン2で2。ボタン3で4。ボタン4で8が入力。

ただし同時押しの場合それぞれの合計数値が表示される。
ボタン1とボタン3なら5。ボタン3とボタン4なら12、ボタン1とボタン2なら3になる。
これは2進数によるやりかたで一つの数値で
複数の入力をチェックできる方法。
andの演算を使うことなどでそれぞれの入力が判定できる。

●ボタン入力を使いやすい形に

procedure TForm1.Timer1Timer(Sender: TObject);
begin

joyGetPos(JOYSTICKID1, @JoyInfo);

num := 0; //まずはリセット
if (JoyInfo.wButtons and 4)>0 then num=1; //ボタン入力にアンドをとる

Caption:=IntToStr(num); //値を文字列にして上のバーに表示

end;
4はボタン3の数値なのでボタン3が押された時にnumが1になる。
この場合、他のボタンが同時に押された時もちゃんと1になるのに注目。
andの演算で4を抽出しないとこのようにはならない。

●未接続の検知

ジョイスティックが接続されていない場合、エラーが出て
プログラムが動かない場合も考えられる。
こういう時も想定し、プログラムが止まらないような処理を
しなければならない。
private
{ Private 宣言 }
num :Integer; //この行を追加。表示用変数
JoyInfo: TJOYINFO; //この行を追加。ジョイスティック入力用
err: Cardinal; //この行をさらに追加。

〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

procedure TForm1.Timer1Timer(Sender: TObject);
begin

JoyIn; //プロシージャとして別で処理

Caption:=IntToStr(num); //値を文字列にして上のバーに表示

end;


procedure JoyIn;
begin
num := 0; //まずはリセット

err:=joyGetPos(JOYSTICKID1, @JoyInfo); //検知しながらエラーを取得
//ジョイスティックが使用不可ならエラーとしてexit
if not (err=MMSYSERR_NOERROR) then exit;

if (JoyInfo.wButtons and 4)>0 then num=1; //ボタン入力にアンドをとる

end;

●もっと使いやすい形式へは各自で

このままのプログラムでは入力として中途半端だが
入力取得方法の解説としては完了しているのでこれまで。
これ以上の加工は他で解説。もしくは各自で勉強。

実際に使うとしたなら
キーボードの入力も受け付けるようにしたり
ファンクション形式で数値情報として返り値をもらうなどの
方法が考えられる。

 戻る