2

I made something like a game, you move your character(black box) up and down and there is a wall with some blank in middle of it, that wall is at right side, its coming from right to left side and if you touch the wall game ends.

I get keypresses in a while loop like;

while(keyboardInput=getKeyPress()){
        switch(keyboardInput){/*checks the key and goes up or down*/}
        //draws the main character, then also draws the wall.
}

and I made a wall() function, it prints blocks to make a wall.

Problem is, the wall moves only after getting a keypress, my keypress function works with _getch()

The thing I want to see is, that wall will always move like every one second to left side even if user doesn't press any key, and key press/movement will work the same way.

I put wall() function into the wall() function. It prints it just like I want but I cant get any keypress because that wall() loops forever.

Game looks like this:

                                    *
                                    *
                                    *
                                    *
                                    *

■

                                    *
                                    *
                                    *
                                    *
                                    *

I am waiting for your answers, thank you!

Kara
  • 6,115
  • 16
  • 50
  • 57
  • What you want is an asynchronous reading of input. `_getch()` is a **blocking** call, meaning that your code stops executing at that point and waits for input. I think that the only way to get around it is with multithreading (google `pthreads`) and reading the input in one thread while updating the screen in another. I could be wrong and there might be an easier way though. – nonsensickle Mar 18 '14 at 21:30
  • 1
    I don't believe that there is a C++ answer for this exactly. Ultimately it may depend on the OS you are using or the hardware associated with it. Essentially what you want is an interrupt or a callback to occur when keyboard input happens. You may want to look into existing libraries like SDL, OpenGL, or DirectX (DirectInput) that have non-blocking ways of reading from the input. – YoungJohn Mar 18 '14 at 22:25
  • My Code::Blocks got broken while I am trying to install pthreads thing... It says ld.exe cannot find -lpthread.h damnit! **edit** Its ok now, I'm gonna learn and try the pthread thing. –  Mar 18 '14 at 22:37

2 Answers2

3

For anything that is close to a game or a simulation, you need to learn what is a "game loop" also called "main loop". There is a nice explaination of the principle on wikipedia.

Basically you should NOT be waiting the input, but you should loop to update the state of the game even if nothing happen: observe the input, see if something happened and if not, just continue looping, if something happen, do it, then continue looping. You must NEVER wait for the input, you just check if there is something to do or not.

This also mean that you should not use a blocking call like _getch(). You have to use whatever input function you have available that only check if there is something to do. It depends a lot on what input API you are using exactly, so I can't get into details without knowing which API you use.

A simple (or more correctly: naive) game loop looks like this:

while( !exit_game )
{
     read_input(); // acquire inputs then generate actions interpreted from inputs, if any
     update_game(); // update the game to generate it's new state after applying all the actions from all the game entities
     render(); // render the graphics and audio
}

This is very naive and don't work well in a real case but it's basically the idea.

I recommand reading this and this to better understand what a game loop is, but it don't focus on getting inputs.

Klaim
  • 67,274
  • 36
  • 133
  • 188
1

If you're programming in Windows, take a look at _kbhit(). You can find the MSDN page for _kbhit() here.

Although _kbhit() was historically an MS-DOS (and later, Windows) function (it's defined in <conio.h> on Windows systems), you can roll your own version of it in Linux, as shown here and here.

However, an easier route might be to use the ncurses library to turn getch() into a non-blocking call by calling nodelay(stdscreen, TRUE), as shown here and here.

Community
  • 1
  • 1
Mike Holt
  • 4,452
  • 1
  • 17
  • 24
  • I changed getch with kbhit program instantly ended with return 0x0. What can I do about it? Also I couldn't find any information about installing ncurses to Code::Blocks in Windows. Waiting for your help, thanks! –  Mar 18 '14 at 23:32
  • You can't just replace `getch` with `_kbhit` and expect it to work. The two functions do different things. The `_kbhit()` function lets you know **if** the user has pressed the keyboard. It doesn't actually *read* the input character. For that, you still have to call `getch()`. The purpose of `_kbhit()` is to allow you to avoid calling `getch()` *until* there is an input character waiting to be read. That way, your loop won't block *waiting* for keyboard input. – Mike Holt Mar 19 '14 at 00:04
  • I put _kbhit() in front of getch and it didn't work like I want, tried the same with putting it after getch. Same :( –  Mar 19 '14 at 08:53
  • 1
    It sounds like maybe you need to stop just trying stuff, take a step back, and *read* the documentation. Learn precisely what these functions do, work through some examples, etc. The fact that you even tried putting kbhit *after* getch indicates that you haven't fully read the documentation. I can only assume that you're here because you're trying to learn programming. If so, then you need to slow down and get comfortable with the idea of spending lots of time reading documentation. There are no shortcuts on the path to becoming a proficient programmer. – Mike Holt Mar 19 '14 at 16:04