Click here to Skip to main content
14,331,823 members
Rate this:
Please Sign up or sign in to vote.
See more:
Hi All,


Background::
Currently as a challenging project for myself I am creating a game engine without the use of DirectX or XNA. I have done this merely for the learning curve. I have a fully functioning 3D system where I can load 3D primitives in and stuff. However when walking round the scene you can only press one key at a time. I have looked into game pad input but with no prevail.


Question::
Can I accept multiple keyboard input key strokes (e.g I press 'W' to move forward then at the same time press 'right' to look right)? :confused: I must not use DirectX or XNA or any other framework because that defeats the entire point of the project.

P.S. if any body else would like to have a go at this project, I would happily give a hand.

Thankyou all in advance :)

--------------------------------------
current code for key down

private void main_KeyDown(object sender, KeyEventArgs e)
{
    switch (e.KeyData.ToString().ToLower())
    {
    case "a":
        {
            WorldScene.TranslationX += (int)(Impulse * WorldScene.ZMth.Cos(ZRotRad - 90));
            WorldScene.TranslationY -= (int)(Impulse * WorldScene.ZMth.Sin(ZRotRad - 90));
        }
        break;
    case "d":
        {
            WorldScene.TranslationX -= (int)(Impulse * WorldScene.ZMth.Cos(ZRotRad - 90));
            WorldScene.TranslationY += (int)(Impulse * WorldScene.ZMth.Sin(ZRotRad - 90));
        }
        break;
    case "s":
        {
            WorldScene.TranslationX -= (int)(Impulse * WorldScene.ZMth.Cos(ZRotRad));
            WorldScene.TranslationY += (int)(Impulse * WorldScene.ZMth.Sin(ZRotRad));
        }
        break;
    case "w":
        {
            WorldScene.TranslationX += (int)(Impulse * WorldScene.ZMth.Cos(ZRotRad));
            WorldScene.TranslationY -= (int)(Impulse * WorldScene.ZMth.Sin(ZRotRad));
        }
        break;
    case "j":
        {
            WorldScene.RotationZ -= 5;
        }
        break;
    case "l":
        {
            WorldScene.RotationZ += 5;
        }
        break;
    case "i":
        {
            WorldScene.RotationX += 5;
        }
        break;
    case "k":
        {
            WorldScene.RotationX -= 5;
        }
        break;
    case "space":
        {
            ZCamVel = 48;
        }
        break;
    }
}
Posted
Rate this:
Please Sign up or sign in to vote.

Solution 1

Interesting project. It has been very long since I worked with keyboard inputs, that too in c++. But I don't think much has changed.

Apart from the controls keys (ALT, CTRL, SHIFT ...) you can only get one char at a time. You can't accept multiple keystokes. But, you can always handle this very easily.

If you to handle two keys, keep in mind last key pressed, say 'D' then when you get 'right arrow' key pressed, you logic can do for both, continue the logic as long as right arrow is pressed. when other key is pressed, break from multi logic and process individual key handler.

Hope that helps.
   
Comments
Thomas.D Williams 13-Jan-11 10:13am
   
I've never thought of doing it that way. Sometimes a simple solution is the best. I was thinking of when detecting a key down storing it as down in some boolean. And then once it is released setting it as not down in the boolean. Then it's processes could be handled in the main game loop.

Thank you for your quick response, its a great help :)
fjdiewornncalwe 13-Jan-11 10:16am
   
That is a great suggestion, Yusuf. +5
Sergey Alexandrovich Kryukov 13-Jan-11 10:19am
   
Yusuf. Simple enough. - 5
Rate this:
Please Sign up or sign in to vote.

Solution 2

Just an addition to Yusuf's Answer:

You usually need to handle both KeyDown and KeyUp.
For example, you press Right and Up means you're moving diagonally north-east, if you will, but if you simply remove Right and keep Up presses, you change direction. Just an example.

Also, you will gain well in supportability if you stop using auto-generated handlers and use anonymous method (with C# 3 and 4 even in lambda form which is even better):

MyControl.KeyDown += (sender, eventArgs) = {
    var key = eventArgs.KeyData.ToString().ToLower();
    KeySet.Add(key);
    Act(key, true, KeySet)
}
MyControl.KeyUp += (sender, eventArgs) = {
    var key = eventArgs.KeyData.ToString().ToLower();
    KeySet.Remove(key);
    Act(key, false, KeySet)
}


Assuming you support set of keys. This way, you can Act based on both most most recent key (second argument can indicate up or down), and a current KeySet (third argument).

The anonymous syntax is better because you can keep event assignment and handlers where you want them, your real handlers (methods) profiles can be free (you don't have to carry sender is you're not using it, sometimes you don't need eventArgs). And lambda form is better because you don't need to type exact types of the arguments -- they are obtained by compiler via type inference.
   
Comments
Thomas.D Williams 13-Jan-11 10:43am
   
Thank you for your response. I have now implemented a solution that works well. You can now navigate the 3d scene without the issues. Great answer :)
   
My pleasure :-)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100