我如何减少在ncurses的C应用输入延迟 [英] How do I reduce input lag in an NCurses C Application

查看:227
本文介绍了我如何减少在ncurses的C应用输入延迟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我收到输入延迟主要量,当我运行我的应用程序。

I am getting major amounts of input lag when I run my application.

详细信息:
当我preSSW,一个,s的,D(我的分配的输入键),不过对象移动它继续键已被释放之后,为在延长的时间周期移动。该人士$ ​​C $ c是低于code的不过一小部分已经被切出然而,以缩短问题如果源$ C ​​$ C以下无法编译我都在GitHub上code起来。
https://github.com/TreeStain/DodgeLinuxGame.git 谢谢你们的时间。 -Tristan

More details: When I press 'w', 'a', 's', 'd' (My assigned input keys) the object moves however it continues to move for an extended period of time after the key has been released. The source code is below however small parts of the code have been cut out to shorten the questions however if the source code below does not compile I have all of the code up on github. https://github.com/TreeStain/DodgeLinuxGame.git Thankyou for your time. -Tristan

dodge.c:

#define ASPECT_RATIO_X 2
#define ASPECT_RATIO_Y 1
#define FRAMES_PER_SECOND 60

#include <ncurses.h>
#include "object.h"
#include "render.h"

int main()
{
    initscr();
    cbreak();
    noecho();
    nodelay(stdscr, 1);

    object objs[1];

    object colObj; colObj.x = 10; colObj.y = 6;
                   colObj.w = 2;  colObj.h = 2;
                   colObj.sprite = '*';
                   colObj.ySpeed = 1;
                   colObj.xSpeed = 1;

    objs[0] = colObj;

    //halfdelay(1);

    while (1)
    {
        char in = getch();
        if (in == 'w')
            objs[0].y -= objs[0].ySpeed * ASPECT_RATIO_Y;
        if (in == 's')
            objs[0].y += objs[0].ySpeed * ASPECT_RATIO_Y;
        if (in == 'a')
            objs[0].x -= objs[0].xSpeed * ASPECT_RATIO_X;
        if (in == 'd')
            objs[0].x += objs[0].xSpeed * ASPECT_RATIO_X;
        render(objs, 1);
        napms(FRAMES_PER_SECOND);
    }

    getch();

    endwin();
    return 0;
 }

render.h:

render.h:

void render(object obj[], int objectNum);

void render(object obj[], int objectNum)            //Takes array of objects and prints them to screen
 {
    int x, y, i, scrWidth, scrHeight;
    getmaxyx(stdscr, scrHeight, scrWidth);          //Get terminal height and width

    for (y = 0; y < scrHeight; y++)
    {
        for (x = 0; x < scrWidth; x++)
        {
            mvprintw(y, x, " ");
        }
    }

    for (i = 0; i < objectNum; i++)
    {
        int xprint = 0, yprint = 0;
        for (yprint = obj[i].y; yprint < obj[i].y + (obj[i].h * ASPECT_RATIO_Y); yprint++)
        {
            for (xprint = obj[i].x; xprint < obj[i].x + (obj[i].w * ASPECT_RATIO_X); xprint++)
                mvprintw(yprint, xprint, "%c", obj[i].sprite);
        }
    }
    refresh();
}

object.h:

object.h:

typedef struct
{
    int x, y, w, h, ySpeed, xSpeed;
    char sprite;
}object;

P.S。因为我在编程相当新的,可以采取所有的批评我可以请随意批评我的方法和code。

P.S. please feel free to critique my methods and code as I am fairly new at programming and can take all the criticism I can get.

推荐答案

我相信原因是因为残培()将只在一个时间(即使有许多输入流中排队)释放一个输入字符等等如果他们排队比你从流中删除他们更快,循环将继续下去,直到你松开按键后连队列被清空。此外,你想要去(1000 / FRAMES_PER_SECOND),以获得您想要的延迟时间以毫秒为单位(这将创建每秒60帧)。

I believe the reason is because getch() will only release one input-character at a time (even if there are many queued up in the input stream) so if they queue up faster than you 'remove' them from the stream, the loop will continue until the queue is emptied even after you release the key. Also, you'll want to go (1000 / FRAMES_PER_SECOND) to get your desired delay-time in milliseconds (this creates 60 frames per second).

试试这个在您的while循环来代替。

Try this in your while loop instead.

while (1)
    {
        char in;
        /* We are ready for a new frame. Keep calling getch() until we hear a keypress */
        while( (in = getch()) == ERR) {}

        if (in == 'w')
            objs[0].y -= objs[0].ySpeed * ASPECT_RATIO_Y;
        if (in == 's')
            objs[0].y += objs[0].ySpeed * ASPECT_RATIO_Y;
        if (in == 'a')
            objs[0].x -= objs[0].xSpeed * ASPECT_RATIO_X;
        if (in == 'd')
            objs[0].x += objs[0].xSpeed * ASPECT_RATIO_X;
        render(objs, 1);

        /* Clear out any other characters that have been buffered */
        while(getch() != ERR) {}

        napms(1000 / FRAMES_PER_SECOND);
    }

从你的循环的顶部:,而((在=残培())== ERR){} 将调用函数getch(),直到迅速一键$ P $检测到的PSS。如果没有检测到一个键preSS,则getch()将返回ERR。
什么而(残培()!= ERR){} 做的就是继续调用函数getch(),直到所有缓冲的输入字符从队列中删除,那么残培()返回ERR和在移动。然后循环应该睡〜17MS和重复。这两根线应强制循环仅计数一键preSS每个〜17MS,并没有更多的时候比。

From the top of your loop: while( (in = getch()) == ERR) {} will call getch() rapidly until a keypress is detected. If a keypress isn't detected, getch() will return ERR. What while(getch() != ERR) {} does is keep calling getch() until all buffered input characters are removed from the queue, then getch() returns ERR and moves on. Then the loop should sleep ~17ms and repeat. These lines should force the loop to only 'count' one keypress every ~17ms, and no more often than that.

请参阅: http://linux.die.net/man/3/getch

这篇关于我如何减少在ncurses的C应用输入延迟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆