Skip to content

Instantly share code, notes, and snippets.

@alexdantas
Created September 8, 2013 01:32
Show Gist options
  • Save alexdantas/6481131 to your computer and use it in GitHub Desktop.
Save alexdantas/6481131 to your computer and use it in GitHub Desktop.
Shows circles around the screen with ruby Curses' console interface.
require 'curses'
# Hell yeah
DANI_NUMERO_CIRCULOS = 4
DANI_LIMPAR_TELA = false
# All possible colors.
Colors = {
:black => 1,
:white => 2,
:red => 3,
:yellow => 4,
:magenta => 5,
:blue => 6,
:green => 7,
:cyan => 8
}.freeze
# Starts curses terminal-handling library with all of it's colors.
def init_curses
Curses::init_screen
Curses::start_color
Curses::init_pair(Colors[:black], Curses::COLOR_BLACK, Curses::COLOR_BLACK)
Curses::init_pair(Colors[:white], Curses::COLOR_WHITE, Curses::COLOR_BLACK)
Curses::init_pair(Colors[:red], Curses::COLOR_RED, Curses::COLOR_BLACK)
Curses::init_pair(Colors[:yellow], Curses::COLOR_YELLOW, Curses::COLOR_BLACK)
Curses::init_pair(Colors[:magenta], Curses::COLOR_MAGENTA, Curses::COLOR_BLACK)
Curses::init_pair(Colors[:blue], Curses::COLOR_BLUE, Curses::COLOR_BLACK)
Curses::init_pair(Colors[:green], Curses::COLOR_GREEN, Curses::COLOR_BLACK)
Curses::init_pair(Colors[:cyan], Curses::COLOR_CYAN, Curses::COLOR_BLACK)
Curses::noecho
Curses::curs_set 0
end
# Executes a block of code encapsulated within a color on/off.
# Note that the color can be overrided
def with_color color=nil
Curses::attron(Curses::color_pair color) if (color != nil)
yield
Curses::attroff(Curses::color_pair color) if (color != nil)
end
# Puts a character `c` on (`x`, `y`) with optional `color`.
def mvaddch x, y, c, color=nil
return if x < 0 or x >= Curses::cols
return if y < 0 or y >= Curses::lines
with_color color do
Curses::setpos(y, x)
Curses::addch c
end
end
# Puts a string `str` on (`x`, `y`) with optional `color`.
def mvaddstr x, y, str, color=nil
return if x < 0 or x >= Curses::cols
return if y < 0 or y >= Curses::lines
with_color color do
Curses::setpos(y, x)
Curses::addstr str
end
end
# Puts a string `str` centered on `y` with optional `color`.
def mvaddstr_center y, str, color=nil
x = (Curses::cols/2) - (str.length/2)
mvaddstr x, y, str, color
end
class Circle
attr_accessor :x, :y, :radius, :char, :color
def initialize(x, y, radius)
@x = x
@y = y
@radius = radius
end
# Shows the circle on the screen
def print
return if (@x + @radius) > Curses::cols # avoiding infinity
angle = 0.01
angle_step = 1.0/@radius
while angle < (2 * Math::PI)
cur_x = @radius * Math.cos(angle)
cur_y = @radius * Math.sin(angle)
mvaddch(@x + cur_x, @y + cur_y, @char, @color)
angle += angle_step
end
end
end
# A container that spawns random circles with random colors at
# random positions with random radius sizes and random growth
# rates
class CircleContainer
def initialize
@circles = []
end
# Inserts a circle.
def add
circle = Circle.new(Random.new.rand(0..Curses::cols-1),
Random.new.rand(0..Curses::lines-1),
Random.new.rand(0..3))
circle.char = ['.', '*', '#'].sample # random array element
circle.color = Colors.to_a.sample[1] # random hask element
@circles.push circle
end
# Updates all circles.
def update
for i in 0..(@circles.length-1)
@circles[i].radius += 1
end
end
# Prints all circles.
def print
Curses::clear if DANI_LIMPAR_TELA
for i in 0..(@circles.length-1)
@circles[i].print
end
Curses::doupdate
end
end
# This is where the fun begins.
begin
init_curses
mvaddstr_center 1, "Wave", Colors[:red]
mvaddstr_center 2, "y = Asin(kx - wt - y) + D", Colors[:yellow]
circles = CircleContainer.new
for i in 0..DANI_NUMERO_CIRCULOS
circles.add
end
while true
circles.update
circles.print
Curses::refresh
sleep 0.03
end
Curses::getch
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment