トップへ(mam-mam.net/)

キーボード、マウス、ジョイスティックの情報取得 ~Delphiソースコード集

検索:

キーボード、マウス、ジョイスティックの情報取得 ~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.

実行

実行画面