views:

540

answers:

3

I have a game that I am working on in a C# console application, purely as practice before going on to better methods. As opposed to using something such as a Windows Forms App, which has button functionality built in, I am endeavoring to grab the cursor position (which I know how to do) and compare it to a number of area's inside a console application as defined by perhaps pixel location, but I also do not know if there is some sort of built in unit of space other than pixels (this last bit is the part I am unable to figure).

P.S. I know this is in general terms, with no code already provided, but I do not feel that it is needed as all I am asking for is a brief explanation of how to grab X Y coordinates inside a console application, and stick them in int variables.

Many Thanks in advance! :D

A: 

What @Frank Krueger said. Do you really want to do this? Windows Forms is deisnged to make this much easier.

If you do, you'll need to use PInvoke into the low level Windows API. Try this as a starting point - but be aware that this is considerably more complex than the Windows Forms application would be.

Jeremy McGee
Wow, that is extremely complicated. I was under the impression that games are written as a console app, or something like it as opposed to Windows Forms and the such, as they are event based. Is there no simpler way?
Bloodyaugust
We did warn you! Console applications are really only used for utilities that process text or files. On the PC graphically intensive games use typically use DirectX, WPF or Windows Forms - Windows Forms is probably the easiest to start with. UI frameworks like Windows Forms are all about events and how to handle them, as you'll find.
Jeremy McGee
Then why have I always heard that games are not event based, but rather loop-based?
Bloodyaugust
A: 

When you write a game without using events... all you are really doing it implementing events yourself. This is advantageous, because you can make it so much more efficient than by using your language's built-in events. Games written this way are less error prone if you know what you are doing.

For example, when I was trying to teach my brother how games are written, I wrote a simple snake game for him. I had the main loop in a thread, move the snake and draw it at it's new position in a cycle. I would have a thread running at the same time that continuously checks 4 things:

1) If the snake crashed into itself (game over); if game over occurs, halt the main thread that updates the main position of the snake, print game over onto the screen, await key input, then restart the game.

2) If the snake had eaten an apple; increment the counter variable that says how many apples have been eaten, and print this new value on the screen, over-writing what was previously there.

3) If the snake had eaten an amount of apples divisible by 10 (snake grows by 1 cell, subtract from a wait variable that says how much time should pass between each movement the snake makes)

4) If an arrow key has been pressed. If left, set move to 0, if right set move to 1, if down set move to 2, if up set move to 3. The int that this is stored in is a pointer to an array of 4 delegates that make the snake move in the right direction.

The main loop that updates the position of the snake would tell the thread checking these 4 things what the snake is doing. The way I do this is I have every cell on the screen that the snake's head moves to refer to a 2-dimensional array of delegates. About this array of delegates:

The game is written in console mode, and uses console colours. The console is set to 80x50 characters. A delegate as follows: "delegate void ptr()"; then I create the array with: "ptr[,] pos = new ptr[80,50]". Say the snake's head is at position (4,5) on the screen, after it has moved there the main loop would execute "pos[4,5].Invoke();".

One of them: When the snake moves to a new position, the main loop thread would get each cell that the snake covers on the screen, and set the delegate at that position to point to a function called "void gameover()" which would set the gameover_ variable to true. So when the loop thread that checks the status of the game checks for gameover, it freezes the game and prints game over on the screen.

Another: When an apple is drawn on the screen, the delegate position it gets drawn at (which is randomized) is set to point to "void increment_apple()" which increments the apple counter, removes the current apple from view, and draws a new apple on the screen, setting the old apple position to point to a "void nop()" which does nothing, and the new apple position to point to "void increment_apple()".

This is basically how the game works. As you can see, the snake moves to these positions on the screen, and it without performing any explicit checks like "if(snake_position == some_position)", the game automatically does everything it is supposed to for everything that happens in the game, much like how when you click a button on a form, an action assigned to that event is automatically executed, without you having to check for the event yourself.

So you see, I could have used a form and the default events that C# provides, but I didn't. I used the console interface, and implemented my own events system.

This is how it works behind the scenes: the main loop for your form app will run in a thread that checks for input from all the buttons, etc on the screen. Each of these items will set a boolean variable they use to true. When you click this button, another thread running a loop checks what you have pressed, and say you pressed a button called "button1", that button would have had a delegate assigned to it; that delegate is then executed with whatever it points to.

Kind of hard to explain, but does this make sense to you?

Francis
A: 

Also, the console isn't just for text processing. You can write pretty decent window managers for it. You can do anything with it. It's just harder.

It's slower, though. I implemented a virtual machine in C# using the console for the user interface. It doesn't print lines of text one after the other; it [the interface] acts rather like a GUI.

If you want mouse input on the console, try this hook: http://blogs.msdn.com/b/toub/archive/2006/05/03/589468.aspx?PageIndex=2#comments

Francis