Solved

Keyboard handler (for game) with Delphi or C++ Builder

Posted on 1998-10-05
6
504 Views
Last Modified: 2010-04-06
How to make a keyboard handler (usually games use it, like
doom, duke nukeem so it can run very fast) with Delphi or C++ Builder. I want to get very immediate respons when I press keyboard so I can move fastly.
0
Comment
Question by:mince
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
6 Comments
 

Author Comment

by:mince
ID: 1341814
Please answer my question immediately because I need it very much to complete my
study.
0
 
LVL 4

Expert Comment

by:erajoj
ID: 1341815
Hi,
Isn't "OnKeyDown"/"OnKeyUp" fast enough?

/// John
0
 
LVL 1

Expert Comment

by:Roadrunner100598
ID: 1341816
If your program should recieve (and maybe process) the keyboard message first, try a hook function (see: SetWindowsHookEx). This will gain some extra microseconds.

And of course there is DirectX 5 - DirectInput as described in Mircosoft Press's 'Inside Direct X'. But I have never tried it myself...

Generally I would recommend using 'OnKeyDown'/'OnKeyUp' as the savest and easiest solution.

. and set the repetition rate in the control panel/keyboard to maximum.

Roadrunner
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 10

Expert Comment

by:viktornet
ID: 1341817
Yup, as the guys told you what you should do I guess I don't need to repeat that suggestion again.... OnKeyPress/OnKeyDown/OnKeyUp/SetWindowsHookEx/UnhookWindows.....and so on.....

P.S. Especially for games I guess the Hook is better, but it's more comlex to implement.... By complex I mean that you need more, code, more though, and a DLL which should be provided with your program...

Regards,
Viktor Ivanov
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1341818
though = thought, actually it's though too ;->
0
 
LVL 5

Accepted Solution

by:
scrapdog earned 200 total points
ID: 1341819
It is not a good idea to use events alone for a keyboard handler in a game.  In games, it is necessary to check whether or not several keys or pressed at a time.

The best way to do this is to use an array of booleans.  

var
  KeysDown :array[0..255] of boolean;

During your program, at any time you could check if a key is down or not by checking the array.  For example if you want to see if the A key is down, you would use:

if KeysDown[65] then ...

(where 65 is the key code for A).

And if you wanted to check if the A key AND the B key are both down, you could use:

if KeysDown[65] and KeysDown[66] then...



In order to keep this array updated, you can use the OnKeyUp and OnKeyDown events for your form.



procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin

  KeysDown[Key and 255] := true;
end;



When the key is pressed, its respective value in the array is set to true.  And then when the key is released, it is set back to false.

It is important that you intialize the KeysDown array to all false values before you start though. (like this)


procedure TForm1.FormCreate(Sender: TObject);
var i :integer;
begin
  for i := 0 to 255 do KeysDown[i] := false;
end;


---------------------------------------

This is the way DOS games handle the keyboard.  Any keypress or release generates make or break codes which are processed and the results are stored in an array.  Using this method allows to detect exactly which keys (even all of them) are down at any given moment.


Here is a demo program.  It shows which of the keys from a to z are pressed, in a label.


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Timer1: TTimer;
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure FormKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  KeysDown :array[0..255] of boolean;

implementation

{$R *.DFM}

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin

  KeysDown[Key and 255] := true;
end;



procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  KeysDown[Key and 255] := false;
end;

procedure TForm1.FormCreate(Sender: TObject);
var i :integer;
begin
  for i := 0 to 255 do KeysDown[i] := false;
end;

procedure TForm1.Timer1Timer(Sender: TObject);  //interval of 1 msec or so
var KeyStr :string;
    i      :integer;
begin
  KeyStr := '';
  for i := 65 to 90 do
    if KeysDown[i] then KeyStr := KeyStr + Chr(i);
  Label1.Caption := KeyStr;

end;

end.



Make sure you set the timer to a small interval (to make sure the label is updated quickly).  The keyboard handler is operating at all times though.


Here is a list of scan codes, taken from the Windows source code that came with Delphi
------------------------------------------

VK_LBUTTON = 1;
  VK_RBUTTON = 2;
  VK_CANCEL = 3;
  VK_MBUTTON = 4;  { NOT contiguous with L & RBUTTON }
  VK_BACK = 8;
  VK_TAB = 9;
  VK_CLEAR = 12;
  VK_RETURN = 13;
  VK_SHIFT = $10;
  VK_CONTROL = 17;
  VK_MENU = 18;
  VK_PAUSE = 19;
  VK_CAPITAL = 20;
  VK_ESCAPE = 27;
  VK_SPACE = $20;
  VK_PRIOR = 33;
  VK_NEXT = 34;
  VK_END = 35;
  VK_HOME = 36;
  VK_LEFT = 37;
  VK_UP = 38;
  VK_RIGHT = 39;
  VK_DOWN = 40;
  VK_SELECT = 41;
  VK_PRINT = 42;
  VK_EXECUTE = 43;
  VK_SNAPSHOT = 44;
  VK_INSERT = 45;
  VK_DELETE = 46;
  VK_HELP = 47;
{ VK_0 thru VK_9 are the same as ASCII '0' thru '9' ($30 - $39) }
{ VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' ($41 - $5A) }
  VK_LWIN = 91;
  VK_RWIN = 92;
  VK_APPS = 93;
  VK_NUMPAD0 = 96;
  VK_NUMPAD1 = 97;
  VK_NUMPAD2 = 98;
  VK_NUMPAD3 = 99;
  VK_NUMPAD4 = 100;
  VK_NUMPAD5 = 101;
  VK_NUMPAD6 = 102;
  VK_NUMPAD7 = 103;
  VK_NUMPAD8 = 104;
  VK_NUMPAD9 = 105;
  VK_MULTIPLY = 106;
  VK_ADD = 107;
  VK_SEPARATOR = 108;
  VK_SUBTRACT = 109;
  VK_DECIMAL = 110;
  VK_DIVIDE = 111;
  VK_F1 = 112;
  VK_F2 = 113;
  VK_F3 = 114;
  VK_F4 = 115;
  VK_F5 = 116;
  VK_F6 = 117;
  VK_F7 = 118;
  VK_F8 = 119;
  VK_F9 = 120;
  VK_F10 = 121;
  VK_F11 = 122;
  VK_F12 = 123;
  VK_F13 = 124;
  VK_F14 = 125;
  VK_F15 = 126;
  VK_F16 = 127;
  VK_F17 = 128;
  VK_F18 = 129;
  VK_F19 = 130;
  VK_F20 = 131;
  VK_F21 = 132;
  VK_F22 = 133;
  VK_F23 = 134;
  VK_F24 = 135;
  VK_NUMLOCK = 144;
  VK_SCROLL = 145;
{ VK_L & VK_R - left and right Alt, Ctrl and Shift virtual keys.
  Used only as parameters to GetAsyncKeyState() and GetKeyState().
  No other API or message will distinguish left and right keys in this way. }
  VK_LSHIFT = 160;
  VK_RSHIFT = 161;
  VK_LCONTROL = 162;
  VK_RCONTROL = 163;
  VK_LMENU = 164;
  VK_RMENU = 165;
  VK_PROCESSKEY = 229;
  VK_ATTN = 246;
  VK_CRSEL = 247;
  VK_EXSEL = 248;
  VK_EREOF = 249;
  VK_PLAY = 250;
  VK_ZOOM = 251;
  VK_NONAME = 252;
  VK_PA1 = 253;
  VK_OEM_CLEAR = 254;


Scrapdog

0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
This video Micro Tutorial shows how to password-protect PDF files with free software. Many software products can do this, such as Adobe Acrobat (but not Adobe Reader), Nuance PaperPort, and Nuance Power PDF, but they are not free products. This vide…
There are cases when e.g. an IT administrator wants to have full access and view into selected mailboxes on Exchange server, directly from his own email account in Outlook or Outlook Web Access. This proves useful when for example administrator want…

726 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question