Creating Terminal Code Rain with C and Ncurses

CCBeginner
Practice Now

Introduction

In this project, you will learn how to create a simple code rain using the ncurses library in the C programming language. Ncurses is a library that facilitates text-based user interfaces in the terminal. This project will guide you through setting up the project, initializing the necessary components, and implementing the code rain.

👀 Preview

Code Rain

🎯 Tasks

In this project, you will learn:

  • How to install the ncurses library
  • How to define constants and structures for the raindrops
  • How to initialize colors for the animation
  • How to create an animation loop to display the raindrops falling
  • How to read user input to exit the animation

🏆 Achievements

After completing this project, you will be able to:

  • Use the ncurses library in C
  • Implement structures in C
  • Create animations in the terminal

Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL c(("`C`")) -.-> c/BasicsGroup(["`Basics`"]) c(("`C`")) -.-> c/ControlFlowGroup(["`Control Flow`"]) c(("`C`")) -.-> c/CompoundTypesGroup(["`Compound Types`"]) c(("`C`")) -.-> c/FunctionsGroup(["`Functions`"]) c/BasicsGroup -.-> c/comments("`Comments`") c/BasicsGroup -.-> c/variables("`Variables`") c/BasicsGroup -.-> c/data_types("`Data Types`") c/BasicsGroup -.-> c/operators("`Operators`") c/ControlFlowGroup -.-> c/if_else("`If...Else`") c/ControlFlowGroup -.-> c/while_loop("`While Loop`") c/ControlFlowGroup -.-> c/for_loop("`For Loop`") c/ControlFlowGroup -.-> c/break_continue("`Break/Continue`") c/CompoundTypesGroup -.-> c/structures("`Structures`") c/FunctionsGroup -.-> c/function_parameters("`Function Parameters`") c/FunctionsGroup -.-> c/function_declaration("`Function Declaration`") subgraph Lab Skills c/comments -.-> lab-298826{{"`Creating Terminal Code Rain with C and Ncurses`"}} c/variables -.-> lab-298826{{"`Creating Terminal Code Rain with C and Ncurses`"}} c/data_types -.-> lab-298826{{"`Creating Terminal Code Rain with C and Ncurses`"}} c/operators -.-> lab-298826{{"`Creating Terminal Code Rain with C and Ncurses`"}} c/if_else -.-> lab-298826{{"`Creating Terminal Code Rain with C and Ncurses`"}} c/while_loop -.-> lab-298826{{"`Creating Terminal Code Rain with C and Ncurses`"}} c/for_loop -.-> lab-298826{{"`Creating Terminal Code Rain with C and Ncurses`"}} c/break_continue -.-> lab-298826{{"`Creating Terminal Code Rain with C and Ncurses`"}} c/structures -.-> lab-298826{{"`Creating Terminal Code Rain with C and Ncurses`"}} c/function_parameters -.-> lab-298826{{"`Creating Terminal Code Rain with C and Ncurses`"}} c/function_declaration -.-> lab-298826{{"`Creating Terminal Code Rain with C and Ncurses`"}} end

Create the Project Files

First, make sure you have the ncurses library installed on your system, if not, you can use the following command to install it:

sudo apt-get install libncurses5-dev

Next, create a new file named code_rain.c and open it in your preferred code editor.

cd ~/project
touch code_rain.c

Define Constants

Now, create the necessary header files including Ncurses, standard library, and time. Define the maximum number of raindrops, and create a structure for the raindrops with their properties.

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

#define MAX_RAIN 200

typedef struct {
    int x, y;
    char ch;
    int color;
    int speed;
} Raindrop;

Initializing Colors

Create a function to initialize the colors that will be used in the animation. This function will set up color pairs using the start_color and init_pair functions provided by ncurses.

void init_colors() {
    start_color();
    init_pair(1, COLOR_GREEN, COLOR_BLACK);
    init_pair(2, COLOR_CYAN, COLOR_BLACK);
    init_pair(3, COLOR_MAGENTA, COLOR_BLACK);
    init_pair(4, COLOR_YELLOW, COLOR_BLACK);
}

The start_color() function is the function that enables the color function of ncurses. This function needs to be called before any other color manipulation function is used.

The init_pair(1, COLOR_GREEN, COLOR_BLACK) function is then used to change the definition of the color pair. It accepts three parameters: the number of the color pair, the number of the foreground color, and the number of the background color. Here, the init_pair function is used to define four color pairs with a foreground color of green, cyan, magenta, and yellow, and a background color of black.

Implementing the Main Function

Inside the main function, set up the ncurses environment, including turning off line buffering and echoing. Enable the keypad for special keys and set non-blocking input. Get the maximum screen dimensions and initialize the colors using the previously defined function.

int main() {
    initscr();
    cbreak();
    noecho();
    curs_set(0);
    keypad(stdscr, TRUE);
    nodelay(stdscr, TRUE);

    int max_x, max_y;
    getmaxyx(stdscr, max_y, max_x);
    init_colors();

    Raindrop rain[MAX_RAIN];

    srand(time(NULL));

    // ... (remaining code to be covered in subsequent steps)
}

Initializing Raindrop Parameters

Initialize the properties for each raindrop using a loop. Set their initial positions, characters, colors, and falling speeds.

for (int i = 0; i < MAX_RAIN; i++) {
    rain[i].x = rand() % max_x;
    rain[i].y = rand() % max_y;
    rain[i].ch = rand() % 94 + 33;
    rain[i].color = rand() % 4 + 1;
    rain[i].speed = rand() % 3 + 1;
}

Implementing the Animation Loop

Set up a loop to continuously update the raindrops' positions and display them on the screen. Check for user input to exit the animation loop.

while (1) {
    int ch = getch();

    if (ch == 'q') {
        break;
    }

    for (int i = 0; i < MAX_RAIN; i++) {
        attron(COLOR_PAIR(rain[i].color));
        mvaddch(rain[i].y, rain[i].x, ' ');
        rain[i].y += rain[i].speed;
        if (rain[i].y >= max_y) {
            rain[i].y = 0;
            rain[i].x = rand() % max_x;
        }
        mvaddch(rain[i].y, rain[i].x, rain[i].ch);
        attroff(COLOR_PAIR(rain[i].color));
    }

    refresh();
    napms(50);
}

Use the getch() function to get the user's input characters and store them in the integer variable ch.

The for loop is used to simulate the effect of raindrops. It traverses an array called rain, which contains information about multiple raindrops. Each raindrop consists of the following properties: color, position coordinates (x and y), falling speed (speed), and character (ch).

This loop will continue until you press the q key, at which point the program will pass break; The statement exits the loop, thus ending the program.

After the animation loop ends, clean up the ncurses environment and exit the program.

endwin();
return 0;

Compilation and Running

The compilation command is slightly different from the usual. It requires adding the -l option to gcc to include the ncurses library:

cd ~/project
gcc -o code_rain code_rain.c -l ncurses
./code_rain
Code Rain

Summary

In this project, you learned how to create a simple raindrop animation using the ncurses library in the C programming language. You set up the project, initialized necessary components, implemented the animation loop, and handled user input for exiting the program. Ncurses provides a powerful toolset for creating text-based user interfaces, and you can use it to create various types of terminal-based applications.

Other C Tutorials you may like