Skip to content

Instantly share code, notes, and snippets.

@kaievns
Created November 29, 2013 05:30
Show Gist options
  • Save kaievns/7701961 to your computer and use it in GitHub Desktop.
Save kaievns/7701961 to your computer and use it in GitHub Desktop.
Brutus on the walk
require 'curses'
class Engine
def self.inst
@inst
end
def self.inst=(inst)
@inst = inst
end
def self.width
Curses.cols
end
def self.height
Curses.lines
end
def initialize
Curses.noecho # do not show typed keys
Curses.init_screen
Curses.stdscr.keypad(true) # enable arrow keys
Curses.stdscr.nodelay = 1
Curses.start_color
begin
Engine.inst = self
yield(self)
ensure
Curses.close_screen
end
end
def gets
Curses.getch
end
def clear
Curses.clear
end
def flush
Curses.refresh
end
def render
clear
yield
at 0, 0
flush
end
def at(x, y, &block)
Curses.setpos(y,x)
yield if block_given?
end
def puts(text, color=nil)
Curses.attron attrs_for(color) do
Curses.addstr text
end
end
def attrs_for(color, pick=true)
@color_indexes ||= {}
@colors_counter ||= 100
# A_DIM
if ! @color_indexes[color]
@color_indexes[color] = @colors_counter += 1
foreground = color.is_a?(Array) ? color[0] : color
background = color.is_a?(Array) ? color[1] : nil
foreground = Curses.const_get("COLOR_#{(foreground || :white).to_s.upcase}")
background = Curses.const_get("COLOR_#{(background || :black).to_s.upcase}")
Curses.init_pair(@color_indexes[color], foreground, background)
end
Curses.color_pair(@color_indexes[color]) | Curses::A_NORMAL
end
end
class Sprite
attr_accessor :src, :lines, :color, :background
def initialize(src, color=nil, background=nil)
self.src = src
@color = color
@background = background
end
def src=(string)
@src = string
@lines = parse(string)
end
def color=(color)
@color = color
end
def background=(color)
@background = color
end
def width
@lines[0].size
end
def height
@lines.size
end
def position(x, y)
@x = x; @y = y
end
def render
engine = Engine.inst
@lines.each_with_index do |line, index|
engine.at @x, @y + index
engine.puts line, [@color || :white, @background]
end
end
def render_at(x, y)
position x, y
render
end
protected
def parse(string)
string.gsub(/\A\n/, '').gsub(/\n[ \t]*\Z/, '').split("\n").tap do |lines|
max_size = lines.map(&:size).max
min_size = lines.map{|l| l[/^\s*/].size}.min
lines.each_with_index do |line, index|
lines[index] = line.slice(min_size, max_size - min_size)
end
end
end
end
class Flower
SPRITES = [
Sprite.new('
`
'),
Sprite.new('
‟/
')
]
def self.random
new SPRITES.random
end
def initialize(sprite)
@sprite = sprite
end
end
class Brutus
SPRITES = {
:regular => Sprite.new('
(___)
"""""" . ‟
/" """""/ ⁃
/\""/\ "
'),
:walk_1 => Sprite.new('
(___)
″″″″″″ . ‟
/″ ″″″″″/ ⁃
\/″″\/ ″
'),
:walk_2 => Sprite.new('
(___)
″″″″″″ . ‟
|″ ″″″″″/ ⁃
/\″″/\ "
'),
:jump => Sprite.new('
(___)
"""""" . ‟
|" """""/ ⁃
||""|| "
')
}
def initialize
@speed = 5
@counter = 0
@sprite = SPRITES[:regular]
end
def render
@counter = @counter == @speed ? 0 : @counter + 1
@sprite = @sprite == SPRITES[:walk_1] ? SPRITES[:walk_2] : SPRITES[:walk_1] if @counter == 0
@sprite.render_at 10, Engine.height - @sprite.height - 1 - jump_offset
end
def jump!
@jump_height = 3
@jump_offset = 0
@jump_speed = 10
@jump_counter = 0
end
protected
def jump_offset
@jump_offset ||= 0
if @jump_height != nil
@jump_counter += 1
if @jump_counter % @jump_speed == 0
if @jump_offset > @jump_height
@jump_speed *= -1
elsif @jump_offset < 0
@jump_height = nil
end
@jump_offset += @jump_speed
end
end
@jump_offset < 0 ? 0 : @jump_offset
end
end
class Grass
TEXTURES = ["'\"″'‟", "\"″'‟'"]
def initialize
@speed = 5 # move every 5 ticks
@counter = 0
@texture = swap_texture
@sprite = Sprite.new(@texture, :green)
end
def render
@counter = @counter == @speed ? 0 : @counter + 1
swap_texture if @counter == 0
@sprite.src = @texture * (Engine.width / @texture.size)
@sprite.render_at 0, Engine.height - 1
end
def swap_texture
@texture = @texture == TEXTURES[1] ? TEXTURES[0] : TEXTURES[1]
end
end
class Sun
def initialize
@sprite = Sprite.new('
......
......
......
', :yellow, :yellow)
end
def render
@sprite.render_at Engine.width - 10, 2
end
end
class Game
FPS = 60
def initialize
@sun = Sun.new
@grass = Grass.new
@brutus = Brutus.new
Engine.new do |engine|
@engine = engine
start_the_loop
end
end
def start_the_loop
@i = 0
loop do
sleep FPS.to_f / 1000
@engine.render do
@brutus.jump! if @engine.gets == " "
@brutus.render
@grass.render
@sun.render
end
end
end
end
Game.new
# ■
# ◼︎
# ✿
# ❀
# ″
# ‟
# ˘
# ✄
# ☹
# ✂
# ︎⩊
# ⩏•◦・⁃
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment