如何用ncurses同时打印两件东西

时间:2014-07-10 03:17:53

标签: c printing ncurses usleep

我正在制作类似于太空入侵者的ncurses游戏。

到目前为止,我已经开始行动并且击落了,但我遇到了一个问题。

当玩家发射激光时,我正在使用睡眠呼叫来延迟激光在屏幕上移动,这样它就不会从屏幕的一端显示到另一端。

使用usleep延迟激光的问题意味着当激光穿过屏幕直到环路退出时,播放器无法移动。

我的问题是,是否有另一种方法可以打印激光在屏幕上移动,同时用用户输入移动播放器/光标?

当用户按下“f”键时,以下代码将线(激光)移动到屏幕上。但是,在激光离开屏幕之前,用户无法再次移动:

void combat(int y, int x)
{
    do
    {
        mvprintw(y -1, x, "|");
        refresh();
        y--;
        usleep(50000);
        mvprintw(y , x, " ");   
    }
    while(y>0);
}

3 个答案:

答案 0 :(得分:0)

如果没有外部线程,这个问题就无法轻易解决。通过将激光器的运动绑定到输入来移除睡眠功能(这样只有当屏幕应该通过外部输入刷新时才更新位置)将无法工作,因为您需要激光器独立于其他所有部件。

肮脏的黑客可能会:

  • 通过int nodelay(WINDOW *win, bool bf)进行非阻塞输入功能,以便输入功能不会阻止任何内容
  • 给定(足够高)刷新率,例如10 FPS(睡眠100毫秒)
  • 每帧数量只更新一次激光位置,让它移动得足够慢,但能够经常轮询输入

答案 1 :(得分:0)

最简单的解决方案是使用包含一条睡眠指令的循环编写程序,例如:

frame_timer = 0;
while (1) {
  if (player_is_alive) {
    move_player();
    move_aliens();
    move_laser_bullets();
    check_collisions();
  }
  else {
    draw_explosion();
    if (explosion_finished) break;
  }
  frame_timer++;
  usleep(20000);  /* Refresh at approximately 50fps */
}

答案 2 :(得分:0)

我实际上找到了一个解决我自己问题的合适解决方案,所以我将把它留在这里以防万一将来有类似的问题。

当我的程序进入战斗功能时,它也进入nodelay模式,进行非阻塞getch()。当函数循环休眠时,用户可以随时输入一个字符,导致船只移动,因为它没有延迟模式,如果用户选择保持静止,则getch()不会阻止执行睡眠功能。

当用户按下'f'时执行的战斗功能:

void combat(int y, int x)
{
int input;
int y2 = y;
int x2 = x;
do
{
    mvprintw(y2 -1, x2+1, "|");
    refresh();
    y2--;
    mvprintw(y2 , x2+1, " ");
    usleep(50000);
    nodelay(stdscr, TRUE);
    input = getch();

    switch(input)
    {
        case 'w':
        mvprintw(y, x,"   ");
        y--;
        mvprintw(y, x,"^V^");
        break;

        case 'a':
        mvprintw(y, x+2," ");
        x--;
        mvprintw(y, x,"^V^");
        break;

        case 's':
        mvprintw(y, x,"   ");
        y++;
        mvprintw(y, x,"^V^");
        break;

        case 'd':
        mvprintw(y, x," ");
        x++;
        mvprintw(y, x,"^V^");
        break;

    }

}
while(y2>0);
movement(y,x);

}