更新ascii网格打印到屏幕而不重新打印网格

时间:2017-10-07 17:19:43

标签: c animation matrix

int main() {

    struct matrix m;

    m.rows = 20;
    m.columns = 20;

    m.grid = create_grid(m.rows,m.columns,'&');

    /* Example animation */
    printf("\033[H\033[2J");
    for (int i = 0; i < m.columns; i++) {
        update_matrix(m.grid,10,i,'x');

        if ( i > 0) {
            update_matrix(m.grid,10,i-1,'&');
        }
        printf("\033[H\033[2J");
        sleep(1);
        printMatrix(m.grid,m.rows,m.columns);
    }



    for (int i = 0; i < m.rows; i++) {
        free(m.grid[i]);
    }
    free(m.grid);

    return 0;
}


void update_matrix(char** grid, int row,int column,char symbol) {
    grid[row][column] = symbol;
}

char** create_grid(int rows, int columns, char symbol) {

    int i,j;

    char **grid = malloc(rows * sizeof(char *));

    for (i = 0; i < rows; i++) {
        grid[i] = malloc(columns * sizeof(char));
    }

    for (i = 0; i < rows; i++) {
        for(j = 0; j < columns; j++) {
           grid[i][j] = symbol;
        }
    }

    return grid;
}

void printMatrix(char** array, int rows, int columns) {

    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < columns; j++) {
            printf("%c",array[i][j]);
        }
        printf("\n");
     }
}

我的动画方法基本上是......

  • 打印矩阵
  • 更新矩阵
  • 暂停
  • 清除屏幕
  • 重印矩阵

这种动画方法的问题在于它会产生闪烁效果,我确信效率非常低。我能做什么,以便我不必每次都清除屏幕并重新打印整个矩阵。

我运行linux。

1 个答案:

答案 0 :(得分:0)

除了使用ncurses之外,你可以做

printf("\033%d;%df", row, column);

将光标设置为所需的行和列(注意,在这里,第一行是1不是 0)而不是

printf("\033[H\033[2J");

在设置后打印矩阵一次,然后在进行修改时更改显示的矩阵。

您可能希望在打印初始矩阵(如

)之前将光标定位到第一行和第一列
printf("\033[%d;%df", 1, 1);

m.grid = create_grid(m.rows,m.columns,'&');
printMatrix(m.grid, m.rows, m.columns);
/* Example animation */
for (int i = 0; i < m.columns; i++) {
    update_matrix(m.grid,10,i,'x');

    printf("%c[%d;%df", 0x1B, 10+1, i+1);
    printf("%c", 'x');

    if ( i > 0) {
        update_matrix(m.grid,10,i-1,'&');
        printf("%c[%d;%df", 0x1B, 10+1, i-1+1);
        printf("%c", '&');
    }
    sleep(1);
    fflush(stdout);
}
可能需要

fflush(stdout);来刷新输出流。否则,写入stdout的更改可能不会在更改时显示在屏幕上。

但是对于这样的用途,ncurses更好。

查看here以及this维基百科页面。