How to allow simultaneous input from two users on one keyboard

Started by
8 comments, last by WithoutRemorse 19 years ago
I'm trying to make a simple multiplayer fighting game and I want the users to keep it as simple a possible so I was thinking that allowing the users to use only one keyboard would be easier, but I don't know how to do it so any suggestions would be helpful.
Peace!
Advertisement
you can do it just like you'd do it with a single player game ... i'm not sure what game library your using (allegro, sdl, etc) but something along these will work fine ...

if (key[KEY_D]) player1->moveRight();
// ... rest of player 1 controls

if (key[KEY_RIGHT]) player2->moveRight();
// ... rest of player 2 controls
Woop woop woop woop!
Thanx for the reply!

But it looks like your using the same method I already tried. The API I'm using is DX9.

I'm using a switch that checks for which key is pressed, but when I press two keys a the same time one object moves while the other doesn't. So how can I get them to move at the same time?
Peace!
I don't understand how you made it a switch. It implies that only one key can be pressed per frame in your app. Note that the example he provided is NOT if/else statements, it is just if statements. Thus, his method can detect all of the keys each frame, while your's will escape out at the first one it finds.

Please post your key-press detection code so we can help you rework it.

-me
A switch statement is essentially just a long chain of if...else statements. Ergo, you're code will break from the switch as soon as one it's cases is executed. Solutions would be to have separate switches, one for each user, or get rid of it all together using code very similar to what DrZoidberg gave, with lots of if statements with no elses.

Edit: You could also use a message driven system, but this would probably be beyond overkill.
hey thanx for the helpful replys!

anyway here's my switch
void CMyEngineApplication::KeyMessageProc( WPARAM wParam )   {   switch ( wParam )      {   case 'W': case 'w':           {			 bool bCollided = false;			 if(bSphereTest(copyPos, copyPos2))				{						bCollided = true;					break;				} // stop forward movement			 			 if(!bCollided)    // if false			{				x+= 0.5;			    m_pCamera->SetRotationSpeedY( -0.08f );			}// if         } break;      case 'S': case 's':          {         //m_pCamera->SetSpeed( -3.0f );			 x-= 0.5;			 m_pCamera->SetRotationSpeedY( 0.08f );         } break;      case 'Q': case 'q':          {         m_pCamera->SetRotationSpeedX( -1.2f );         } break;      case 'E': case 'e':          {         m_pCamera->SetRotationSpeedX( 1.2f );         } break;      case 'D': case 'd':          {         //m_pCamera->SetRotationSpeedY( -1.2f );         } break;      case 'A': case 'a':          {         //m_pCamera->SetRotationSpeedY( 1.2f );         } break;	  case 'I': case 'i':          {         //m_pCamera->SetRotationSpeedY( 1.2f );			 x2-=0.5;         } break;	  case 'O': case 'o':          {         //m_pCamera->SetRotationSpeedY( 1.2f );			 x2+=0.5;         } break;      default: break;      }    } // KeyMessageProc/*----------------------------------------------------------------*/


I going to try your suggestions now any further advice would also be welcomed.

Thanx
--Karl
Peace!
Hi.

I used you guys advice and changed my input control from a switch to a set of if statements, but I still get the same result.

here's what I changed it to:
void CMyEngineApplication::KeyMessageProc( WPARAM wParam )   {           if( wParam =='W'||wParam =='w')     {			 bool bCollided = false;			 if(bSphereTest(copyPos, copyPos2))				{						bCollided = true;				} // stop forward movement			 			 if(!bCollided)    // if false			{				x+= 0.5;			    //m_pCamera->SetRotationSpeedY( -0.08f );			}// if    }// W     if(wParam=='S'||wParam == 's')      {         //m_pCamera->SetSpeed( -3.0f );			 x-= 0.5;			 //m_pCamera->SetRotationSpeedY( 0.08f );     }// S      	 if(wParam =='I'||wParam =='i')      {         //m_pCamera->SetRotationSpeedY( 1.2f );		 bool bCollided2 = false;			 if(bSphereTest(copyPos2, copyPos))				{						bCollided2 = true;				} // stop forward movement			 			 if(!bCollided2)    // if false			{				x2-=0.5;			    //m_pCamera->SetRotationSpeedY( 0.08f );			}// if			       }// I	  if(wParam == 'O'||wParam =='o')       {         //m_pCamera->SetRotationSpeedY( 1.2f );			 x2+=0.5;      }//O                } // KeyMessageProc
and this function is called here:
switch(msg)       {      // our app has the focus      case WM_ACTIVATE: {         if ( (BOOL)wParam ) m_pEngine->SetActive( true  );         else                m_pEngine->SetActive( false );         } break;               // key was pressed      case WM_KEYDOWN:          {         switch (wParam)             {            case VK_ESCAPE:                {               // this will post WM_DESTROY message               // if not handled otherwise by us               PostMessage(hWnd, WM_CLOSE, 0, 0);               return 0;               } break;            case VK_F1:               {               m_pRenderDevice->EnableWireframe( !m_pRenderDevice->IsWireframe() );               } break;            case VK_F2:               {               m_pRenderDevice->EnableTextures( !m_pRenderDevice->IsTextured() );               } break;            default: KeyMessageProc( wParam );            }         } break;
So is it operating the same because it is being called in a switch?

help me please! Thanx
--Karl
Peace!
you should probobly make that second function if's too. And, why did you not just include thouse in the first function?
"All I want to know is who the man is that looked at a cow and said "I think I'll drink whatever comes out of those things when I squeeze them."Calvin and Hobbes
Something you may run into, even if you get the code working, is keyboard-ghosting issues.

Most keyboards have a hardware limitation on the number of keys that can be pressed simultaneously. This is usually done internally as a matrix of sorts.
I found this page which might explain it better http://www.dribin.org/dave/keyboard/html


This problem is seen all over the emulation scene, when people try and play a game like street fighter on a keyboard. Pressing and holding up, right, kick, block, etc, and the keyboard quits accepting keystrokes after the third press, leaving the second player locked out.

If you choose your keys carefully, you might be able to get some of this to work, although if you change keyboards you'll have to change the keys.

Actually, the problem may be with the keyboard's key repeat function. This has to be disabled first, then you can simply test whether a key is being held down or not. Then, as long as a key is registered as being held down, the computer can perform the action associated with that key if that's what you want (like movement, for example). Only thing is, I've never seen this problem with MS's window code before.

EDIT:

Didn't see Nohup's post before. Now there's an issue I didn't know about... wow.

EDIT EDIT: Actually, considering that he has the issue in trying to use just two keys at the same time, it could be a key repeat issue.

This topic is closed to new replies.

Advertisement