Имитация сценария bash "снегопад" в ncurses / C - PullRequest
1 голос
/ 22 декабря 2011

Итак, на днях я видел этот скрипт bash, имитирующий падение снега на терминале. Я думал, что это будет легкий проект для изучения ncurses в C, но я полностью испортил это. Мой подход состоял в том, чтобы просто заполнить некоторые строки случайными снежинками и записать их на экран. Я не получаю ничего, что я ожидал. По сути, это большой беспорядок, который пролетает со скоростью света.

Может кто-нибудь поставить меня на правильный путь? Вот скрипт, который я хочу скопировать.

#!/bin/bash

LINES=$(tput lines)
COLUMNS=$(tput cols)

declare -A snowflakes
declare -A lastflakes

clear

function move_flake() {
    i="$1"

    if [ "${snowflakes[$i]}" = "" ] || [ "${snowflakes[$i]}" = "$LINES" ]; then
snowflakes[$i]=0
    else
if [ "${lastflakes[$i]}" != "" ]; then
printf "\033[%s;%sH \033[0;0H " ${lastflakes[$i]} $i
        fi
fi

printf "\033[%s;%sH*\033[0;0H" ${snowflakes[$i]} $i

    lastflakes[$i]=${snowflakes[$i]}
    snowflakes[$i]=$((${snowflakes[$i]}+1))
}

while :
do
i=$(($RANDOM % $COLUMNS))

    move_flake $i

    for x in "${!lastflakes[@]}"
    do
move_flake "$x"
    done

sleep 0.1
done

1 Ответ

0 голосов
/ 22 декабря 2011

Ну, если вы можете жить без линии в нижней части экрана, которая притворяется, что снег накапливается на земле, это довольно просто. Основная хитрость заключается в том, чтобы прокрутить экран вниз, а не вверх. Однако, если вы действительно хотите, чтобы этот результат был сложнее, и вам, возможно, придется попробовать другой подход, чем этот.

Я только что проверил это на своей машине, так что во всех случаях ругательства применяются обычные предостережения о пробеге вашего терминала. В любом случае, что-то для вас, чтобы жевать и играть. Cntl-C должен убить его, но было бы неплохо использовать правильную обработку ошибок.

#include <ncurses.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>

int main(int argc, char *argv[])
{
    srand (time(NULL));

    initscr();

    int  maxRows, maxCols;

    getmaxyx(stdscr, maxRows, maxCols);

    int flakesPerRow = maxCols * 0.02;

    scrollok(stdscr, TRUE);

    while (true)
    {
        //setup top line
        for (int i = 0; i < flakesPerRow; ++i)
        {
            int x = rand() % maxCols;
            mvaddch(0, x, '*');
        }

        move(0,0);  //keeps cursor from bouncing around
        scrl(-1);   //scroll down, not up
        refresh();
        napms(200); //delay 200ms
    }

    endwin();
}
...