How can I press two keys with a different outcome for each key singularally and a combined effect?
Author |
Message |
isaiahk9
|
Posted: Mon Jul 28, 2008 7:46 pm Post subject: How can I press two keys with a different outcome for each key singularally and a combined effect? |
|
|
The title either explains it all, or makes no sense. But to put it in easier terms to understand, I plan on making a fighting game and I want J key to be the "basic attack", and the arrow keys to direct the avatar of the gamer. To cut down on control keys, I thought combo-ing keys would make the game simpler (Up + J, Down + J, Right/Left + J , or just J would all initiate different attacks).
So to test if this was possible, I whipped this up :
var key : array char of boolean
var key2 : array char of boolean
setscreen ("graphics")
loop
cls
Input.KeyDown (key)
Input.KeyDown (key2)
if key (KEY_RIGHT_ARROW) and key2 (KEY_UP_ARROW) then
Draw.FillBox (100 + 200, 100 + 200, 105 + 200, 105 + 200, black)
elsif key2 (KEY_RIGHT_ARROW) then
delay (100)
if key2 (KEY_UP_ARROW) then
else
Draw.FillBox (100 + 100, 100, 105 + 100, 105, blue)
end if
elsif key (KEY_UP_ARROW) then
Draw.FillBox (100, 100 + 100, 105, 105 + 100, green)
else
Draw.FillBox (100, 100, 105, 105, red)
end if
delay (100)
end loop
I want the black box to go off without either the green or blue boxes going off first. Any clue how? It's fundamental to my game. If it's not possible, I could simplify my game, but I would like to know.
- thanx |
|
|
|
|
|
Sponsor Sponsor
|
|
|
Euphoracle
|
Posted: Mon Jul 28, 2008 8:03 pm Post subject: RE:How can I press two keys with a different outcome for each key singularally and a combined effect? |
|
|
You don't need 2 arrays of the same thing. They'll be storing the same thing UNLESS you manage to release the key within the fraction of milliseconds of delay inbetween the calls. |
|
|
|
|
|
Tony
|
Posted: Mon Jul 28, 2008 8:09 pm Post subject: RE:How can I press two keys with a different outcome for each key singularally and a combined effect? |
|
|
Indeed, the name "key" is very misleading. Input.KeyDown record the entire keyboard (or as much of it as it can...). It helps to think of it in such terms.
Also, things like
code: |
elsif key2 (KEY_RIGHT_ARROW) then
delay (100)
if key2 (KEY_UP_ARROW) then
|
are really weird... since the value of the "key2" doesn't change during the delay. And it seems strange to arbitrary slow down the game for a certain key press. |
Tony's programming blog. DWITE - a programming contest. |
|
|
|
|
Euphoracle
|
Posted: Mon Jul 28, 2008 8:14 pm Post subject: RE:How can I press two keys with a different outcome for each key singularally and a combined effect? |
|
|
What I don't think he is understanding is that this stuff is being checked every frame. You'll want to write some sort of wrapper to determine when a key has been released. KeyDown returns whether it is being pressed at that exact moment. It is impossible to use only that for combinations, unless you are going to make a game about "can you press the keys at the exact same millisecond". Key combinations work by determining when keys are released, or waiting for all required keys to be pressed at the same time. It's the difference between pressing, say, Windows Key + D (on windows xp) and Windows Key + L (on windows xp) for Show Desktop and Lock Computer functionality.
It's a bit more complicated than is led to believe, and if it is designed an implemented well, there won't be any gripes about poor controls (see: prerender frames & unreal<3 engine) |
|
|
|
|
|
isaiahk9
|
Posted: Tue Jul 29, 2008 7:46 am Post subject: RE:How can I press two keys with a different outcome for each key singularally and a combined effect? |
|
|
Thanks for the advice on only needing one keyboard variable.
Tony, that was only put there to test if it would make it so that when the user presses two keys within a 100 millisecond difference, then it would record the same. I know it is bad programming, and doesn't work or make sense.
This may be kind of stupid, but I am still wondering about my question - can I have two keys called at the same time without triggering the reactions of the keys individually? Besides the player responding in one frame? b/c if not, then my game will be severely lowered in quality. I want
- thanx |
|
|
|
|
|
Tony
|
Posted: Tue Jul 29, 2008 11:22 am Post subject: RE:How can I press two keys with a different outcome for each key singularally and a combined effect? |
|
|
What you would have to do is build a buffer for the key states in between frames. When a key is first pressed, it's not immediately executed (if the game mechanics allow for that) -- the reaction is delayed by a couple of frames. At that point you can scan the buffer for the longest combination of keys (a single key being a combination of 1). |
Tony's programming blog. DWITE - a programming contest. |
|
|
|
|
isaiahk9
|
Posted: Tue Jul 29, 2008 11:31 am Post subject: RE:How can I press two keys with a different outcome for each key singularally and a combined effect? |
|
|
Tony - it sounds possible, and I think it would work, but the only way I can think of how to do that would seriously delay reaction time and still bug out. In principle, how would one do what you suggest? |
|
|
|
|
|
Tony
|
Posted: Tue Jul 29, 2008 4:40 pm Post subject: Re: RE:How can I press two keys with a different outcome for each key singularally and a combined effect? |
|
|
isaiahk9 @ Tue Jul 29, 2008 11:31 am wrote: seriously delay reaction time
Well the delay needs only be the max time allowed in between button presses, to count them as combo. This time could actually be shortened if a large combo is allowed to be completed after the initial part of it is triggered (one could think of this as a combo of combos... I know some fighting video games implement this).
It could also be sped up by executing combos as soon as it's determined to be complete (including the combos of one). This is kind of like parsing syntax, in a compiler...
It should be something like
code: |
loop
// frame start
keys = Input.KeyDown
add current keys to the buffer
drop expired keys from the buffer
scan the buffer from the earliest to the latest, looking for combos
execute move
end loop
|
Assuming we have moves A, B, C; and they make a combo if you hit all 3...
Frame 1: [A]
Frame 2: [A] // still holding A
Frame 3: [A, B] // B was hit slightly later than A
Frame 4: [B, C] // C was hit as A was released, but also very close in time
Assume that we expire frames after elapsed time of 3 frames
so our history is something like
[A] [A] [_]
[_] [B] [B]
[_] [_] [C]
Scanning from left to right, we are trying to match a combo of [A,B,C]
Looking for A -- frame [A] -- good
Looking for B -- frame [A,B] contains B -- good
Looking for C -- frame [B,C] contains C -- done!
Things like delays, how strict your scanning is, figuring out if you should trigger single keys as soon as the combo is broken (or upon expiry of buffer records), allowing extra/redundant/whatever keys to be ignored if the combo is made anyway... it should all be considered, and they tweak the mechanics of gameplay... |
Tony's programming blog. DWITE - a programming contest. |
|
|
|
|
Sponsor Sponsor
|
|
|
isaiahk9
|
Posted: Tue Jul 29, 2008 8:09 pm Post subject: RE:How can I press two keys with a different outcome for each key singularally and a combined effect? |
|
|
I may be really stupid, but I've only started programming for 6 months in a class too old for my age. I've already completed the course but have only made one lengthy project.
That being said, I know how to create this game except for the "combo"s. That being said, I don't know what parsing syntax in a compiler or buffers is. If somebody could put it in lament's terms, that would help.
thanx anyway if nobody can answer. It's not too pressing b/c this game is being made for only my own pleasure. |
|
|
|
|
|
Tony
|
Posted: Wed Jul 30, 2008 1:38 am Post subject: RE:How can I press two keys with a different outcome for each key singularally and a combined effect? |
|
|
Don't worry about compilers... for now
A buffer is simply a queue that collects input. If you press a whole bunch of keys really fast
Turing: |
var c : string(1)
loop
getch(c )
put c. .
delay(500)
end loop
|
They will also still show up... eventually. Actually long after you've stopped abusing your keyboard. That's because keyboard sends all input into a queue, and getch reads from there.
Now we can build another layer of a buffer inside the game, but with an added feature of keeping a history of it, and ability to go back and forth (at least for a limited number of frames).
If Input.KeyDown records everything into an array of char, and we need multiple copies of that (one for each frame), then we'll just create... and array of array!
Turing: |
var buffer : array of array char of boolean
|
(I hope that works. Otherwise you'd have to create an array of a custom record type, and translate data into that).
A circular array would likely improve the performance, since you wouldn't have to change indexes of _a lot of data_ every frame.
Turing: |
var buffer_head : int % index input recorded in the current frame
var buffer : array of array char of boolean
.. .
loop
Input.KeyDown(buffer (buffer_head ))
.. .
% increment buffer_head
end loop
|
So then if you want to check for certain patterns in the input history... a trivial example being if a key A has been held down for all of the last 10 frames, then you just check from multiple indexes of the buffer
Turing: |
var check : boolean := true
for decrementing i: buffer_head .. buffer_head - 10
check = check and buffer(i)('A')
end for
|
Keep in mind that you might want to build a couple of functions to work with a circular array, since if it loops over, then a simple for-loop will obviously not work. |
Tony's programming blog. DWITE - a programming contest. |
|
|
|
|
isaiahk9
|
Posted: Wed Jul 30, 2008 6:12 am Post subject: RE:How can I press two keys with a different outcome for each key singularally and a combined effect? |
|
|
And if "array of array of char of boolean" doesn't work (it didn't for me)? |
|
|
|
|
|
isaiahk9
|
Posted: Wed Jul 30, 2008 8:49 am Post subject: RE:How can I press two keys with a different outcome for each key singularally and a combined effect? |
|
|
And if the delay is equal to the amount of time given to the user to combo their keys, then wouldn't this type of pseudo-code idea acomplish the same :
get key input
delay (time given for combo-ing)
if keyA and keyB are pressed then
run combo AB
elsif keyB and keyC are pressed then
run combo BC
elsif keyA is pressed then
run attackA
else
run attackB
??? |
|
|
|
|
|
DemonWasp
|
Posted: Wed Jul 30, 2008 8:56 am Post subject: RE:How can I press two keys with a different outcome for each key singularally and a combined effect? |
|
|
Try it. Write a small test program (don't edit your main game code) and try out the idea. If it works well, then use it; if it doesn't, then look for something new.
In principle your method should work, but you probably don't want to delay, since that would cause your program to appear to lock up (if briefly). It's a good first approximation; after that, you probably want what Tony suggested.
Better / easier would be to just choose some keys as modifiers (like Shift, Ctrl, Alt, etc). Those keys would have no effect on their own, so you wouldn't have to deal with ignoring them. This may not be quite what you want, however. |
|
|
|
|
|
isaiahk9
|
Posted: Wed Jul 30, 2008 9:15 am Post subject: RE:How can I press two keys with a different outcome for each key singularally and a combined effect? |
|
|
I tried a demo version of my idea, and through a series of an extra 50 lines of code, I managed to make the program not lock up when pressing a key (only a lag of a tenth of a second, which I can live with). Tony's method would work better, but this way is so much more simpler, and because this game is just for my own pleasure, I'll go with my way (with DemonWasp's advice , making combos a lot easier to use)
- thanx, problem solved |
|
|
|
|
|
|
|