informal survey, collect information and share your input(method)

Started by
4 comments, last by RolandofGilead 20 years, 4 months ago
(This first paragraph is about why I''m doing this post, you can skip it.) Most of the posts here at gdnet are about specific problems and strategies. I have learned much here, but it was all learned very slowly. New techniques have come slowly and without fanfare. I would like to more fully use the internet''s capability in this post. Other areas have many formal definitions and papers and well-known pros and cons to ponder and learn. Input doesn''t, AFAIK, so that is what I want us all to share. How do you do input? I''ll go first. I have not completed the entire input subsystem so the section I''m describing is the interpretation layer. This handles taking input from the OS to interpret what exactly the player wants to do. I haven''t completed the part where the input received from an entity(such as the player, ai, or over the network) is processed and effects are caused. I''m using SDL. I''m using events, though I will add the ability to use polling. The basis of my entire input subsystem is that you create game_input''s and activate accordingly. For the player input interpretation part of it, you create structs containing the exact event(or state, if you''re polling) you want covered and other necessary information(like if you are comparing relative or absolute mouse coordinates, or the acceptable range of a joystick input since it will almost never be an exact value and will vary even if you try to hold it steady). Then you check the events on the queue(or poll the hardware) to see if they match, if they do, you can send off the game_input(just an int) that was attached to that description to be processed so it can affect the game world. AI entities and over the network can just send their inputs directly.
Advertisement
GameCore->UpdateInput();

I have a global InputCore class that I can just check values from. Don''t make things more complicated than they need to be .
____________________________________________________________AAAAA: American Association Against Adobe AcrobatYou know you hate PDFs...
(sigh) Thanks for posting.
So, in that function, I suppose you poll for input?
How do you do user-mapping? How does the game know that receiving an input we''ll call ''fire'' means to fire?
Come on ppl, share.
Check values? What values? What happens based on those values?
Excellent post - I'm working on the same issue with my project, but I haven't any real useful ideas to offer. I'm just interested in this thread.

I haven't gone as far as you have to have game events as structs just yet. For the moment I simply have keyboard and mouse states in simple arrays. I have two functions in my game loop, one for taking input (keyboard, mouse, whatever) and one that processes the current input states. I don't whether this is even a valid solution because I'm only 20% done coding it. I've included the code for my event handling function and subfunction for keyboards. If we're thinking about it as a Model-View-Controller, what I've done below is implement the controller :

/** * Handle events from SDL message pump.  It is called for each loop in * gameLoop() and dispathes all outstanding events to their proper handlers * (keyboard, mouse, or window). * It simply updates the mouse and keyboard states for the business logic * functions ( ie. processInput() ) to handle. * * @see gameLoop * @see processInput */void CGame::handleEvents(){	//assert( this->event );			// debug	// Loop until there are no events left on the queue	while( SDL_PollEvent( &event ) )	{		// pass off handling functions to different input handlers		switch( event.type )		{		case SDL_KEYDOWN:		case SDL_KEYUP:			this->handleKeyboardEvent( this->event.key );			break;		case SDL_MOUSEMOTION:			this->handleMouseMoveEvent( this->event.motion );		case SDL_MOUSEBUTTONDOWN:		case SDL_MOUSEBUTTONUP:			this->handleMouseButtonEvent( this->event.button );		case SDL_ACTIVEEVENT:			// dunno yet?		case SDL_QUIT:			this->exitGameLoop = true;		default:			// push remaining events on the queue			break;		}//switch( event.type )	} //while( SDL_PollEvent( &event ) )}//handleEvents/** * Processes any keyboard events. It does not act on them, it only updates * the keyboard array so we can deal with it later. * @see keyDown */void CGame::handleKeyboardEvent( SDL_KeyboardEvent k ){	//assert( this->event);	// Process UP or DOWN	switch (k.type)	{	case SDL_KEYDOWN:		keyDown[ k.keysym.sym ] = 1;			//temp exit		if ( k.keysym.sym == SDLK_0)			this->exitGameLoop = true;		break;		case SDL_KEYUP:		keyDown[ k.keysym.sym ] = 1;		break;	default:		// we should NEVER be here.		break;	} //switch( k.type )	return;}//processKeyboard


The second function is presumably my 'business logic' which acts on whatever the model is. It would look at the state of the keyDown[] or mouseDown[] array and change statuses and what not. ie.:

void CGame::ProcessInput(){	if (this->keyDown[ SDLK_UP ] == 1)	{		this->player->accelerate( player->speed );	}	... (and so on)	} 


[edited by - d0hboy on December 17, 2003 3:04:03 PM]
I have written an Input Mapper. The one I wrote uses SDL, I do not have the code on hand so I''ll have to write this from memory.

I would create my own list of constants, such as follows:

const int PLAYER1_UP = 0;
const int PLAYER2_UP = 1;
const int PLAYER1_DOWN = 2;
const int PLAYER2_DOWN = 3;
....
etc etc etc.

I wrote an input mapper object. It uses 2 std::maps internally. The first one maps an integer to an SDL virtual key. The second maps a virtual key to a bool.

In my initialization code, I would do something like this:

	InputMapper myInput;	myInput.MapKey(PLAYER1_UP, SDLK_UP);	myInput.MapKey(PLAYER2_UP, SDLK_w);	myInput.MapKey(PLAYER1_DOWN, SDLK_DOWN);	myInput.MapKey(PLAYER2_DOWN, SDLK_s);	// etc, etc, etc.


Then, on my message loop, I would have something like this (pseudocode):

while(has messages) {	if(message.type == key pressed) {		myInput.KeyPressed(message.key);	} else if(message.type == key released) {		myInput.KeyReleased(message.key);	}}


The since I mapped the key SDLK_UP to PLAYER1_UP, if SDLK_UP is sent to the input mapper''s KeyPressed function, the bool that is associated with it is set to true. Likewise, if SDLK_UP is send to KeyReleased, the bool becomes false.

I then coded the operator[] of the input mapper class to return the boolean associated with the constant ints I declared and mapped.

Then all I have to do is this, anywhere in my code:

if(myInput[PLAYER1_UP]) {	// Player 1 move up key has been pressed}if(myInput[PLAYER2_UP]) {	// player 2 move up key has been pressed}if(!myInput[PLAYER2_DOWN) {	// player 2 down key has NOT been pressed..	// not too useful, but it shows the flexibility.}// etc, etc, etc.



I was thinking on trying my hand at writing an article on my input mapper class, or at least a sweet snippet. Would anyone be interested in such a thing?

InputMapper will be included in my project, Dusty Engine (for Irrlicht), to which there is a link below.

daveandrews.org - a Christian Programmer''s Weblog | Dusty Engine - a task engine using Irrlicht | Computer Guys Run the World
How to be a Programmer
The issue comes up enough and is common detail when implementing a game -- how to properly manage input? Of course, it can survive in a sticky or a forum thread but it''s so much easier if it was arranged and categorized as a snippet.

This topic is closed to new replies.

Advertisement