微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C - 如何在 ncurses 库中使用 halfdelay(i)

如何解决C - 如何在 ncurses 库中使用 halfdelay(i)

我正在尝试使用 ncurses 库在 C 中创建一个蛇游戏。我希望我的程序以恒定的滴答速度检测用户输入。如果一段时间后没有输入,我希望我的程序继续(即更新游戏)。

这是我为了测试 halfdelay(i) 函数而写的:

#include <ncurses.h>

int main(void)
{
    initscr();
    halfdelay(5);
    
    int user_input;

    do
    {
        user_input = getch();

        if (user_input != -1)
        {
            clear();
            printw("Key pressed: %d\n",user_input);
        }
        else
        {
            //printf("Timeout.\n");  
            printw("Timeout.\n");
        }
    } while (user_input != ESC);

    endwin();

    return 0;
}

编辑#1:
I would like to see
Timeout.
Timeout.
Timeout.

使用的代码

#include <ncurses.h>

int main(void)
{
    initscr();
    halfdelay(5);

int in;

    do
    {
        timeout(1);
        in = getch();

        if (in != -1)
        {
            clear();
            printw("Key pressed: %d\n",in);
        }
        else
        {
            //printf("Timeout.\n");  
            printw("Timeout.\n");
        }

        refresh();
    } while (in != 27);

    endwin();

    return 0;

}

解决方法

先介绍一下历史。

传统上,ESC 键值已用作 escape sequences 的前缀,它表示可以解释为非图形字符的特殊字符序列(例如,箭头键、功能键等)

由于 (n)curses 专注于便携性(和电信),它开箱即用支持这种转义序列的概念,因此按下 ESC 键会产生一些副作用。值得注意的是,当启用 keypad 时,程序会等待决定用户是简单地按下 ESC 还是需要等待更多信息来完成转义序列,因此存在内置延迟.此时间可通过 ESCDELAY 环境变量或 set_escdelay 函数进行调整。

当您继续工作时,所有这些都很重要,因为您可能希望最终启用 keypad 的功能,这将在使用 ESC 时创建一些额外的步骤键。

因此,没有用于转义键的 ESCKEY_ESC 宏。相反,它的原始代码是 27(或八进制 033)。

您对 halfdelay 函数的使用对我来说似乎非常好,只要知道参数是 十分之一秒,所以 5 是半秒。十分之一秒可能无法在游戏中达到预期效果,因此请考虑改用 timeout 函数,这样可以获得更高的精度。

一个简单有效的例子:

#include <ncurses.h>

int main(void) {
    initscr();
    halfdelay(5);
    
    int user_input;
    
    while ((user_input = getch()) != 27) {                
        clear();                                     
                                                     
        if (user_input == ERR)
            printw("Timeout.");
        else
            printw("Key pressed: %d\n",user_input);                                                                  
                                                                                                                      
        refresh();                                                                                                    
    }                                                                                                                 
                                                                                                                      
    endwin();                                                                                                         
}

您更新的程序“有效”,只是无法正确清除屏幕。请注意,您可能不想混用对 printwprintf 的调用,因为这会造成奇怪的屏幕混乱。

此外,您应该使用 halfdelay timeout,但不能同时使用。请记住,timeout毫秒 为单位接受其参数,即 1/1000 秒,并为 窗口({{1} } 代表 timeoutstdscr 代表特定窗口)。这不是“睡眠”风格的功能。

一次使用一个延迟函数,将 wtimeout 移到 clear 语句之外,并使用 if。这在功能上与上面发布的程序相同,只是有一个 printw 循环。

do ... while

如果您希望此程序的显示类似于

#include <ncurses.h>

int main(void) {
    initscr();
    /*
    noecho();
    scrollok(stdscr,TRUE);
    */
    timeout(500);
                   
    int in;        

    do {
        in = getch();
        
        clear();
        
        if (in != ERR)
            printw("Key pressed: %d\n",in);
        else
            printw("Timeout.\n");
        
        refresh();
    } while (in != 27);

    endwin();
}

像更传统的终端一样,您只需要将 Timeout. Timeout. Key pressed: 65 Timeout. ... 全部删除,并取消注释 clearnoecho

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。