Bash Script

This Bash script creates a simple animation of terrain and clouds in the terminal
 avatar
unknown
sh
a year ago
3.4 kB
42
Indexable
#!/bin/bash

WIDTH=$(tput cols)
HEIGHT=$(tput lines)
SCROLL_SPEED=1
SLEEP_TIME=0.05
MAX_LENGTH=$((WIDTH + 200))

CHARS=(" " "." ":" "-" "=" "+" "*" "#" "%" "@")

# Colores ANSI
CLR_RESET="\033[0m"
CLR_STAR="\033[1;33m"       # Amarillo brillante (estrellas)
CLR_CLOUD="\033[1;37m"      # Blanco brillante (nubes)
CLR_PEAK="\033[0;32m"       # Verde oscuro (cima montaña)
CLR_MID="\033[0;37m"        # Gris claro (parte media montaña)
CLR_LOW="\033[1;37m"        # Blanco brillante (faldas montaña)

generate_terrain() {
    for ((x=0; x<MAX_LENGTH; x++)); do
        h=$(( (RANDOM % (HEIGHT / 2)) + HEIGHT / 4 ))
        terrain[$x]=$h
    done
    for ((j=0; j<5; j++)); do
        for ((x=1; x<MAX_LENGTH-1; x++)); do
            terrain[$x]=$(( (terrain[x-1] + terrain[x] + terrain[x+1]) / 3 ))
        done
    done
}

generate_clouds() {
    cloud_length=15
    for ((i=0; i<5; i++)); do
        cloud_pos[$i]=$(( RANDOM % (MAX_LENGTH - cloud_length) ))
        cloud_row[$i]=$(( RANDOM % (HEIGHT / 4) ))
    done
}

draw_frame() {
    local start=$1
    buffer=""

    for ((y=0; y<HEIGHT; y++)); do
        line=""
        for ((x=0; x<WIDTH; x++)); do
            star_char=" "
            cloud_char=" "
            char=" "

            # Estrellas arriba
            if (( y < HEIGHT / 4 )); then
                if (( RANDOM % 100 < 5 )); then
                    star_char="${CLR_STAR}*${CLR_RESET}"
                fi
            fi

            # Nubes
            for ((c=0; c<5; c++)); do
                cx=${cloud_pos[$c]}
                crow=${cloud_row[$c]}
                if (( y == crow )) && (( x + start >= cx && x + start < cx + 15 )); then
                    cloud_char="${CLR_CLOUD}#${CLR_RESET}"
                fi
            done

            height=${terrain[$((x + start))]}
            if (( HEIGHT - y <= height )); then
                rel=$(( height - (HEIGHT - y) ))
                total_height=$height
                pct=$(( 100 * rel / total_height ))

                # Cambia colores:
                # cima (pct > 80) verde oscuro
                # media (pct > 40) gris claro
                # baja (pct <= 40) blanco brillante
                if (( pct > 80 )); then
                    color=$CLR_PEAK
                elif (( pct > 40 )); then
                    color=$CLR_MID
                else
                    color=$CLR_LOW
                fi

                idx=$(( (HEIGHT - y) * ${#CHARS[@]} / HEIGHT ))
                [[ $idx -ge ${#CHARS[@]} ]] && idx=$((${#CHARS[@]} - 1))
                char="${color}${CHARS[$idx]}${CLR_RESET}"
            else
                if [[ $cloud_char != " " ]]; then
                    char=$cloud_char
                elif [[ $star_char != " " ]]; then
                    char=$star_char
                else
                    char=" "
                fi
            fi

            line+="$char"
        done
        buffer+="$line\n"
    done
    echo -ne "\033[H$buffer"
}

tput civis
trap "tput cnorm; clear; exit" SIGINT

generate_terrain
generate_clouds

offset=0
while true; do
    draw_frame $offset
    ((offset+=SCROLL_SPEED))
    ((offset >= MAX_LENGTH - WIDTH)) && offset=0

    for ((c=0; c<5; c++)); do
        ((cloud_pos[c]++))
        if (( cloud_pos[c] > MAX_LENGTH )); then
            cloud_pos[c]=0
            cloud_row[c]=$(( RANDOM % (HEIGHT / 4) ))
        fi
    done

    sleep $SLEEP_TIME
done
Editor is loading...
Leave a Comment