How can I use napms() in ncurses

I'm trying to create a game in c++ with ncurses library. When I shot a bullet with the player I have to use the napms() function to draw the bullet movement, but the player can't move because of the napms() function. How can I fix that? I have to use the thread or there is a function that can help me for that? Thank you for the attention.

2 answers

  • answered 2022-05-04 11:13 Sam Varshavchik

    The short answer: you don't use napms with ncurses. You use no-delay mode and poll(). You start by using nodelay() to put ncurses into no-delay mode (see ncurses documentation for more information).

    If you read getch() manual page, you will find it explained how in no-delay mode getch never blocks, but immediately returns ERR if no key has been pressed.

    At this point you can use poll() or select() to wait for a key to be pressed, with an explicit timeout. That's your delay in milliseconds. You will have to add a little bit of logic to determine what should be done.

    Your overall logic should be as follows:

    1. Call getch

    2. If getch returns a key, do whatever you want with it then go to step 1.

    3. Only if getch returns ERR: calculate whether it's now time to do whatever else your program needs to do, like drawing your bullet. It's entirely possible that you have already waited the prescribed number of milliseconds since the last time your bullet was drawn. Afterwards go to step 1.

    4. Only if your program reached a conclusion that it's not yet time to draw the bullet, calculate how much you need to wait before something needs to be done in step 3.

    5. poll() or select() for the prescribed interval of time. Then go back to step 1.

    So, for example, when you start from the beginning, getch gives you bupkis, then you decide that you just drew your bullet and you need to draw your bullet again in 100 milliseconds. You poll(), and after you wake up you have something from getch, and you work on that. Then whenever you end up back in step 5 you determine that the bullet was drawn 75 milliseconds ago (poll() returned because there's now something to be getch-ed, it did not time out, and after processing a key you consult the wall clock and see that it's now 75 milliseconds later) so you now poll() for 25 more milliseconds.

  • answered 2022-05-04 21:05 William McBrine

    The poll() / select() approach is popular, but -- unless you really need to check for non-curses input in the same loop -- I suggest that you instead look into a purely curses-based approach, built around halfdelay() or timeout(). You could also simply use napms() with a shorter delay, in a loop together with getch(), in nodelay() mode. For example, if you wanted to update the bullet every half-second, then instead of calling napms(500), you might call napms(50) ten times -- checking the input after each time, allowing the player to respond -- and only then update the bullet.

    (My bias here: If you stick to curses calls, your program will be easily portable to other implementations like PDCurses, which it won't be if you go the poll() / select() route.)

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum