lefunkster
asked on
Keyboard access for Delphi game loop
Hello! I wonder whether anyone can help me -
I would like to write a simple loop with the ability to 'poll' the keyboard for key presses, so that if say the Down Arrow is pressed, something in the code will respond (I guess using a Case statement).
I have found some code that appears to work in exe form but that my version of Delphi will not compile - John Ayres Delphi Rocks (asteriods clone) - the code uses 'outdated' keyboard HOOKS.
HookProc:=MakeProcInstance (@Keyboard Hook, HInstance);
KBHook:=SetWindowsHookEx(W H_KEYBOARD ,THookProc (HookProc) ,HInstance ,GetCurren tTask);
How can I access the Windows handles to check if any keys are being pressed?
Also if I'm right in my thinking am I limited to just detecting one keypress at a time?
As you might have guessed the loop is intended for simple games/simulators w/o Direct X (for now).
I would like to write a simple loop with the ability to 'poll' the keyboard for key presses, so that if say the Down Arrow is pressed, something in the code will respond (I guess using a Case statement).
I have found some code that appears to work in exe form but that my version of Delphi will not compile - John Ayres Delphi Rocks (asteriods clone) - the code uses 'outdated' keyboard HOOKS.
HookProc:=MakeProcInstance
KBHook:=SetWindowsHookEx(W
How can I access the Windows handles to check if any keys are being pressed?
Also if I'm right in my thinking am I limited to just detecting one keypress at a time?
As you might have guessed the loop is intended for simple games/simulators w/o Direct X (for now).
why not just use the key down/up on the draw or on the form ?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Procedure wmgetdlgCode(var Message:Twmgetdlgcode); message
WM_GetDlgCode;
Procedure TMycomponent.wmgetdlgCode( var Message:Twmgetdlgcode);
begin
message.result:=DLGC_WantA rrows;
end;
This will force the form to recognize the arrow key strokes and you can
do what ever you like with them
please keep in mind that you have to zero the key variable on the
onkeydown event if you don't want delphi's key handling procedure to
take any action on them.
like this...
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift:
TShiftState);
begin
if key = vk_space then key := 0;
end;
WM_GetDlgCode;
Procedure TMycomponent.wmgetdlgCode(
begin
message.result:=DLGC_WantA
end;
This will force the form to recognize the arrow key strokes and you can
do what ever you like with them
please keep in mind that you have to zero the key variable on the
onkeydown event if you don't want delphi's key handling procedure to
take any action on them.
like this...
procedure TForm1.FormKeyDown(Sender:
TShiftState);
begin
if key = vk_space then key := 0;
end;
ASKER
OK - thanks for the response!
This is were I am with this:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
// Let's move the sprite every time the arrow keys are pressed
if Key = vk_left then PosX := PosX - 1; // Left
if Key = vk_up then PosY := PosY - 1; // Up
if Key = 39 then PosX := PosX + 1; // Right
if Key = 40 then PosY := PosY + 1; // Down
end;
This works but just for one keystroke - ie pressing 2 keys isn't processed; stepping through the code shows that the whole procedure is run through yet only one keystoke (ie move) is registered... is there a way around this?
I've only gone this way as this appears to be the simplest way to get the job done. I am a beginner and will of course look at Handles soon (I can't say I like the look of them - but I'm sure once I get a 'handle' on them...)
This is were I am with this:
procedure TForm1.FormKeyDown(Sender:
Shift: TShiftState);
begin
// Let's move the sprite every time the arrow keys are pressed
if Key = vk_left then PosX := PosX - 1; // Left
if Key = vk_up then PosY := PosY - 1; // Up
if Key = 39 then PosX := PosX + 1; // Right
if Key = 40 then PosY := PosY + 1; // Down
end;
This works but just for one keystroke - ie pressing 2 keys isn't processed; stepping through the code shows that the whole procedure is run through yet only one keystoke (ie move) is registered... is there a way around this?
I've only gone this way as this appears to be the simplest way to get the job done. I am a beginner and will of course look at Handles soon (I can't say I like the look of them - but I'm sure once I get a 'handle' on them...)
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
It's probably not the best way to do this but it works.
Just remember to set the timer intervall to something low like 100 or 50 depending on what refresh rate you want.
Just remember to set the timer intervall to something low like 100 or 50 depending on what refresh rate you want.
The easy way - make an array of keys. The keyboard has <256 keys. So:
keys: array [0..255] of boolean; //the size is 256 if you will not use special keys.
Init somewere:
for i:=0 to 255 do
keys[i]:=false;
In KeyDown proc:
keys[Key]:=true;
In KeyUp proc:
keys[Key]:=false;
In the procedure where you draw (for example before drawing scene):
if (keys[VK_UP])and(keys[VK_L EFT]) then
begin
keys[VK_UP]:=false;
keys[VK_LEFT]:=false;
// Do anything;
end;
______
Best regards,
Thespian.
keys: array [0..255] of boolean; //the size is 256 if you will not use special keys.
Init somewere:
for i:=0 to 255 do
keys[i]:=false;
In KeyDown proc:
keys[Key]:=true;
In KeyUp proc:
keys[Key]:=false;
In the procedure where you draw (for example before drawing scene):
if (keys[VK_UP])and(keys[VK_L
begin
keys[VK_UP]:=false;
keys[VK_LEFT]:=false;
// Do anything;
end;
______
Best regards,
Thespian.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.