如何在ncurses中的窗口(游戏和暂停窗口)之间切换?

问题描述 投票:0回答:1

我正在用 C 创建一个游戏。我不是在 stdscr 中玩它,而是在一个名为

basewin
的胜利中玩。我希望,当用户按“P”时,打开另一个名为
pausewin
的窗口,并暂停
basewin
上运行的游戏。然后,当用户按“R”恢复时,我想“关闭”
pausewin
,并恢复我的游戏。特别是,我希望看到我的
basewin
处于我按“P”之前离开它的状态。

我想我可以通过使用窗口来做到这一点,因为:

  1. 它会让我的代码更干净。
  2. Windows是内存空间上的指针,所以我可以轻松恢复
    basewin
  3. 这将是暂停任何游戏的通用方法,退出后不会遇到
    printw
    的麻烦
    pausewin

但是我的想法行不通。我在一个简化的游戏上尝试过这个:

#include <ncurses.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <stdlib.h> 
    
int main() {
    /* INIT NCURSES */ 
    initscr(); 
    curs_set(0); 
    noecho();
    
    /* INIT PAUSE WIN */
    WINDOW *pausewin = newwin(LINES/3, COLS/3,LINES/3, COLS/3);
    keypad(pausewin,TRUE);
    int cMax_pause, lMax_pause; getmaxyx(pausewin,lMax_pause, cMax_pause);
    box(pausewin,0,0);
    mvwprintw(pausewin,1,cMax_pause/2 -5,"PAUSE WIN");
    mvwprintw(pausewin,lMax_pause/2, cMax_pause/3-4, "[R]ESUME");
    mvwprintw(pausewin,lMax_pause/2, 2*cMax_pause/3-3, "[Q]UIT");
    
    /* INIT BASE WIN */
    WINDOW *basewin = newwin(LINES, COLS/2, 0, COLS/4);
    keypad(basewin,TRUE);
    int lMax, cMax; getmaxyx(basewin, lMax, cMax);
    box(basewin,0,0);
    mvwprintw(basewin,0,2, "[P]AUSE");
    mvwprintw(basewin,1,cMax/2 -4,"BASE WIN");
    
    /* INIT VAR */
    bool loop = true;
    bool pause = false;
    int ch,chp;
    
    /* INIT VARS PLAYER */
    int pline = lMax/2;
    int pcol = cMax/2;
    char pch[2] ; pch[0] = 'M';
    
    /* AFFICHAGE BASE WIN : PRE-LOOP */
    wrefresh(basewin);
    
    /* "GAME" LOOP */
    while(loop){
        
        ch = wgetch(basewin);
        switch(ch){
            case 'p': /* On met le jeu en pause */
            case 'P':
                pause = true;
                break;
            case KEY_LEFT: /* Sinon deplacement */
                pcol -= 1;
                break;
            case KEY_RIGHT:
                pcol += 1;
                break;
            case KEY_UP:
                pline -= 1;
                break;
            case KEY_DOWN:
                pline += 1;
                break;
            default:
                break;
        }
    
    if (pause){
        wrefresh(pausewin);  // HERE IS THE PLACE I HAVE MY PROBLEM
        while(pause){
            chp = wgetch(pausewin);
            switch (chp){
            case 'q':
            case 'Q':
                pause = false;
                loop = false;
                break;
            case 'r':
            case 'R':
                pause = false;
                wrefresh(basewin); // HERE TOO
                break;
            default:
                break;
            }
        }
        
    }
    
    else{
        mvwprintw(basewin,pline,pcol,pch);
    }
    
    wrefresh(basewin);
    }
    
    
    delwin(pausewin);
    delwin(basewin);
    endwin();
    return EXIT_SUCCESS;
}

我对 ncurses 手册有相对较好的理解,但我无法让它工作。 我试图用

tempwin
来解决这个问题,但它只能工作一次,然后再也不会打印
pausewin
了。 我也尝试过使用
overwrite()
但它看起来并不是解决这个问题的好方法。

c window ncurses pause game-loop
1个回答
0
投票

一个非常简单的方法是调用

touchwin
来指示整个窗口应该重新绘制到屏幕上。

(请注意,当窗口被修改时,

wgetch(pausewin)
意味着
wrefresh(pausewin)
,否则必须调用
wrefresh
才能实际产生输出。
wrefresh(basewin)
在主循环的底部被调用,无论暂停如何。
)

if (pause) {
    touchwin(pausewin);

    while (pause) {
        chp = wgetch(pausewin);

        switch (chp) {
            case 'q':
            case 'Q':
                pause = false;
                loop = false;
                break;
            case 'r':
            case 'R':
                pause = false;
                touchwin(basewin);
                break;
            default:
                break;
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.