简体   繁体   中英

How to build complex “graphics” using ncurses?

I've been told to use code like this:

    void printCharacter(int row, int col) {
        move(row, col);
        addch(' ');
        addch(' ');
        addch('0');
        addch(' ');
        addch(' ');
        move(row + 1, col);
        addch('<');
        addch('-');
        addch('|');
        addch('-');
        addch('>');
        move(row + 2, col);
        addch(' ');
        addch('/');
        addch(' ');
        addch('\\'); // Escape required for using '\'
        addch(' ');
    }

to build "graphics" of stick-man shapes while programming a game with the ncurses library. I feel like this is extremely repetitive. Is there a better Right Way to do this?

I've found mvaddch(row, col, ' ') but that still seems too verbose.

(And yes, this is for a homework assignment, but I'm not asking for The Answer, just a way to solve a problem nicely. Too many CS classes only teach the how, they don't teach the craft.)

Think of the console as a very low resolution raster display - when you do this you can see how ncurses can be used as a kind of primitive graphics API, allowing you to set per-pixel value (where a pixel is a single character), as well as basic shapes, such as lines and boxes.

By calling addch repetitively (along with move ) you draw a graphical object to the screen the same way you can make complex scenes with repetitive calls to a Graphics object in Java or GDI - just doing it very slowly ;)

The only thing that feels "wrong" about the example you've given is that the artwork is hard-coded (quite literally) into your code. This means your code is super-fast, but it makes it a nightmare to edit.

A long-term solution is to move your artwork to a separate file in the filesystem, and modify your program to read this file into a buffer. To draw the art using ncurses you just iterate through the (ascii) characters in the buffer and act accordingly, for example (pusedocode):

void drawBuffer(int x, int y, char[] artBuffer) {
    move( x, y );
    foreach(char c in artBuffer) {
        if( c == '\n' ) move( x, ++y );
        else addch( c );
    }
}

EDIT: Or just use drawBuffer directly from code, like so:

char* stickFigure = "   0\n<-|->\n / \\";
void drawStickFigure(int x, int y) {
    drawBuffer( x, y, stickFigure );
}

Ta-da.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM