# Have a while loops but inputs depend on events fired, what are some ways on getting the input?

I think I'm at a conundrum here, I've creating a matching game in C# winforms. And I'm 90% done, the only thing left is the game loop.

The matching games consits of two multidimensional arrrays which are panels. And after I set everything up, I can RunGame(), which where my game loop is, the problem I am having is getting input. I'm not sure how to do that yet.

For example.

It's a while loop.

So,

while(game.isRunning()){

//get input from player.

//getchoice then redraw panels accordingly

//get input from player 2.

//getchoice then redraw panels accordingly

}


The problem is my players click on panels that's how I get the choice they've made. So I wanted to know if you guys have any good ways of getting input in a loop from an event that will be launched outside the loop for a game.

Thanks.

This kind of game loop is a poor choice if you're using winforms. In winforms UI, input events are processed in the same thread as your program logic - in this case, game loop. This means that you won't get any input events while the loop is running (unless you create a second thread, of course.)

It is much better to use events for everything. There's a Timer class that you can use to have events fired periodically - every 100, or 50, ms. That's not enough resolution for an action game, but will probably be OK for a puzzle.

Then, you can have your matching, animation etc in OnTimer event handler, and input in OnClick event handler. Or, for simplicity, OnClick could just set some state like "player clicked here", and OnTimer would then check this state and act accordingly - that way, all game logic would be in the same place.

Take a look at Timer documentation here. What you need is place code that updates panels inside your timer handler (TimerEventProcessor in the example), and user input code inside corresponding Click handlers for your panels. Something along the lines of

panel1.Click += HandlePlayerInput; // this methods handles player's clicking on the panel. Use other events to capture other input like dragging.
panel2.Click += HandlePlayerInput;
panel1.Paint += RedrawPanel; // this method actually draws whatever there is in the panel
panel2.Paint += RedrawPanel;
timer1.Tick += UpdatePanelContents; // this is whatever logic is left in your game loop - generally, checking the state of panels, finding matches, and the like...

• can you give a pseudo example of what you mean. – Bombcode Apr 11 '11 at 11:06
• I added a bit more to the answer. Hope this helps. – Nevermind Apr 11 '11 at 12:32
• My bad I thought I made this the answers. We used your method, and thanks! – Bombcode Jun 13 '11 at 17:08

Attach a function that set a variable to each event, like:

gloabl eventfired=false
eventhandler=function(){
eventfired=true
}

while(...){
if(eventfired){
//do stuff
eventfired=false
}
}


Since you are using WinForms, I suggest that you drop the game loop (by the way, where exactly are you planning to put it?), add a timer component and process game logic in timer "Tick" event handler. Each tick should be equivalent to one iteration of the loop.

And for the input handling you should probably do something like this:

1. Create a buffer where you store information about recently pressed keys. It can be as simple as an array with as many entries, as there are keys. Each entry should be a boolean value that indicates whether the specific key was pressed (where the index of the array is the same as the key code). Alternatively, you could create something like a HashSet. For each pressed key, you would then add it's key code.
2. Add event handlers to KeyDown/KeyUp or KeyPress events. Each handler should change the key press state information in the earlier mentioned buffer.
3. Each time the "Tick" event handler gets called, simply check the buffer for the state of the keys that you are interested in and run the appropriate game logic.
while(game.isRunning()){
if(player1InputKey())
DoSomething();

if(player2InputKey())
DoSomethingElse();

Draw();
}

• This won't work in winforms. You don't get any input if you don't let the UI thread run. – Nevermind Apr 11 '11 at 9:01