キーボード、マウス、ジョイスティックの情報取得 ~Delphiソースコード集
シューティングゲーム等のゲームプログラミングの場合、
タイマー(TTimer)や、
TApplicationEvent.onIdoleで(Winapi.MMSystem.)timeGetTime、timeBeginPeriod(1)、timeEndPeriod(1)、
又はApplicationEvent.onIdoleで QueryPerformanceFrequency(qpf)、QueryPerformanceCounter(qpc)等でタイミングを見計らって
リアルタイムに現在のキーボードのキーの状態(押されているか)、マウスの状態(マウス座標、ボタンが押されているか)、
ジョイスティックコントローラーの状態(ティックの傾き、各ボタンの状態)を調べる必要があると思います。
(参考)ジョイスティックコントローラー(ゲームパッド)の情報を取得している拙作フリーソフト(FMX)
シューティングゲーム NoTitle2
Delphiを起動して新規作成を行う
Delphiを起動し、ファイル→新規作成→Windows VCLアプリケーションをクリックし、 空のアプリケーションを選択してOKボタンを押してプロジェクトを作成します。TTimerを1つ、TMemoを3つフォームにドラッグ&ドロップします。
すべて保存を押して、プロジェクトフォルダを作成してプロジェクトとユニットを保存します。
ソースコードの記述
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls
,Winapi.MMSystem;
type
TForm1 = class(TForm)
Timer1: TTimer;
Memo1: TMemo;
Memo2: TMemo;
Memo3: TMemo;
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
Timer1.Interval:=33;
Timer1.Enabled:=True;
Memo1.DoubleBuffered:=True;
Memo2.DoubleBuffered:=True;
Memo3.DoubleBuffered:=True;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var mp:TPoint; //マウス座標
mb:SmallInt;//マウスボタンの状態
sb:Integer;//OS上で左右入れ替わっているか
k:SmallInt; //キーの状態
ji: TJoyInfo;
begin
memo1.Lines.BeginUpdate;
memo2.Lines.BeginUpdate;
memo3.Lines.BeginUpdate;
memo1.Lines.Clear;
memo2.Lines.Clear;
memo3.Lines.Clear;
//■現在のマウスの座標
//VCLの場合、マウスの現在位置を取得 スクリーン座標になる
GetCursorPos(mp);
Memo1.Lines.Add(
'GetCursorPos スクリーン座標:'+Format('x=%4d,y=%4d',[mp.X,mp.Y])
);
//フォーム上の座標に変換 = Form1.OnMouseMoveと一致する
mp:=self.ScreenToClient(mp);
Memo1.Lines.Add(
'GetCursorPosからフォーム座標へ変換:'+Format('x=%4d,y=%4d',[mp.X,mp.Y])
);
//マウスカーソルの現在位置を変更する場合
//SetCursorPos(mp.X,mp.Y);
//FMXの場合、マウスの現在位置を取得 スクリーン座標になる
//mp:TPointf:=Screen.MousePos;
//■現在のマウスの物理ボタンの状態(OS上で左右入れ替えても無視)
//物理左ボタン
mb:=GetAsyncKeyState(VK_LBUTTON);
if mb<0 then
memo1.Lines.Add('GetAsyncKeyState(VK_LBUTTON):押されている')
else
memo1.Lines.Add('GetAsyncKeyState(VK_LBUTTON):押されてない');
//物理中ボタン
//mb:=GetAsyncKeyState(VK_MBUTTON);
//物理右ボタン
//mb:=GetAsyncKeyState(VK_RBUTTON);
//OS上で左右入れ替わっているかどうかは以下でわかる
sb:=GetSystemMetrics(SM_SWAPBUTTON);
if sb<>0 then
memo1.Lines.Add('GetSystemMetrics(SM_SWAPBUTTON):マウスボタン左右入れ替わっている')
else
memo1.Lines.Add('GetSystemMetrics(SM_SWAPBUTTON):マウスボタン左右入れ替わってない');
//■現在の特定のキーボードのキー押されているか
//Aキー
k:=GetKeyState(ord('A'));
if k<0 then //負の値だと押されている
Memo2.Lines.Add('Aキー:押されている')
else
Memo2.Lines.Add('Aキー:押されてない');
//SHIFTキー
k:=GetKeyState(VK_SHIFT);
if k<0 then //負の値だと押されている
Memo2.Lines.Add('SHIFTキー:押されている')
else
Memo2.Lines.Add('SHIFTキー:押されてない');
//左シフトキー
mb:=GetAsyncKeyState(VK_LSHIFT);
if mb<0 then
memo2.Lines.Add('GetAsyncKeyState(VK_LSHIFT):押されている')
else
memo2.Lines.Add('GetAsyncKeyState(VK_LSHIFT):押されてない');
//右シフトキー
mb:=GetAsyncKeyState(VK_RSHIFT);
if mb<0 then
memo2.Lines.Add('GetAsyncKeyState(VK_RSHIFT):押されている')
else
memo2.Lines.Add('GetAsyncKeyState(VK_RSHIFT):押されてない');
//■ジョイスティックコントローラーの状態を取得する
//ジョイスティック1
if joyGetPos(JOYSTICKID1,@ji)=JOYERR_NOERROR then
begin
memo3.Lines.Add('JOYSTICKID1:接続されている');
//スティックX座標
memo3.Lines.Add(
'JOYSTICKID1:X='+Format('%5d',[ji.wXpos])
);
//スティックY座標
memo3.Lines.Add(
'JOYSTICKID1:Y='+Format('%5d',[ji.wYpos])
);
//ボタン1
if (ji.wButtons and JOY_BUTTON1)=JOY_BUTTON1 then
memo3.Lines.Add('JOYSTICKID1:JOY_BUTTON1が押されている')
else
memo3.Lines.Add('JOYSTICKID1:JOY_BUTTON1が押されてない');
//ボタン2
if (ji.wButtons and JOY_BUTTON2)=JOY_BUTTON2 then
memo3.Lines.Add('JOYSTICKID1:JOY_BUTTON2が押されている')
else
memo3.Lines.Add('JOYSTICKID1:JOY_BUTTON2が押されてない');
end
else
memo3.Lines.Add('JOYSTICKID1:接続されてない');
//ジョイスティック2
if joyGetPos(JOYSTICKID2,@ji)=JOYERR_NOERROR then
begin
memo3.Lines.Add('JOYSTICKID2:接続されている');
//スティックX座標
memo3.Lines.Add(
'JOYSTICKID2:X='+Format('%5d',[ji.wXpos])
);
//スティックY座標
memo3.Lines.Add(
'JOYSTICKID2:Y='+Format('%5d',[ji.wYpos])
);
//ボタン1
if (ji.wButtons and JOY_BUTTON1)=JOY_BUTTON1 then
memo3.Lines.Add('JOYSTICKID2:JOY_BUTTON1が押されている')
else
memo3.Lines.Add('JOYSTICKID2:JOY_BUTTON1が押されてない');
//ボタン2
if (ji.wButtons and JOY_BUTTON2)=JOY_BUTTON2 then
memo3.Lines.Add('JOYSTICKID2:JOY_BUTTON2が押されている')
else
memo3.Lines.Add('JOYSTICKID2:JOY_BUTTON2が押されてない');
end
else
memo3.Lines.Add('JOYSTICKID2:接続されてない');
memo1.Lines.EndUpdate;
memo2.Lines.EndUpdate;
memo3.Lines.EndUpdate;
end;
end.