首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何用ncurses同时打印两件东西

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

Stack Overflow用户
提问于 2014-07-10 03:17:52
回答 3查看 905关注 0票数 0

我在做一个类似太空入侵者的诅咒游戏。

到目前为止,我已经得到了移动和击落,但我遇到了一个问题。

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

使用usleep延迟激光的问题意味着,当激光穿过屏幕时,玩家不能移动,直到环路退出。

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

当用户按下'f‘键时,下面的代码将行(激光)移动到屏幕上。但是,直到激光离开屏幕之后,用户才能再次移动:

代码语言:javascript
复制
void combat(int y, int x)
{
    do
    {
        mvprintw(y -1, x, "|");
        refresh();
        y--;
        usleep(50000);
        mvprintw(y , x, " ");   
    }
    while(y>0);
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-07-11 03:51:07

我已经找到了一个很好的解决方案来解决我自己的问题,所以我会把这个放在这里,以防将来有类似的问题出现。

当我的程序进入战斗函数时,它也会进入无延迟模式,从而形成一个非阻塞getch()。当函数循环通过睡眠时,用户可以在任何时候输入一个字符,导致船只移动,而且由于处于无延迟模式,如果用户选择保持不变,getch()不会阻止睡眠函数的执行。

当用户按‘f’时执行的战斗函数:

代码语言:javascript
复制
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);

}

票数 0
EN

Stack Overflow用户

发布于 2014-07-10 03:39:21

如果没有外部线程,这个问题是无法轻易解决的。通过将激光的运动绑定到输入(以便只有当屏幕被外部输入刷新时才更新位置)将无法消除睡眠功能,因为您需要激光独立于其他一切。

肮脏的黑客可以是:

  • 通过int nodelay(WINDOW *win, bool bf)实现非阻塞输入函数,这样输入函数就不会阻塞任何东西
  • 给定的(足够高的)刷新速率,如10 FPS (睡眠100毫秒)
  • 每隔一帧更新一次激光位置,使其移动足够慢,但能够经常轮询输入。
票数 0
EN

Stack Overflow用户

发布于 2014-07-10 06:52:39

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

代码语言:javascript
复制
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 */
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24666939

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档