class PeterPan

Constants

VERSION

Attributes

empty_point_character[R]
viewport_height[R]
viewport_width[R]

Public Class Methods

new(opts={}) click to toggle source

Possible Options:

  • :viewport_width - Viewport width, integer, default 21

  • :viewport_height - Viewport height, integer, default 7

  • :empty_point_character - the char of an empty cell (default ‘ ’)

  • :buffer_width - Buffer width, integer, default 0

  • :buffer_height - Buffer height, integer, default 0

NOTE: The buffer will automatically expand dimensionally to hold any point that is plot()‘ed or text written with write().

# File lib/peter_pan.rb, line 26
def initialize(opts={})
  @viewport_width = (opts[:viewport_width] || 21).to_i # x
  @viewport_height = (opts[:viewport_height] || 7).to_i # y
  @font_name = 'transpo' # only font for now
  @empty_point_character = (opts[:empty_point_character] || ' ')
  buffer_changed!(false)
  clear_buffer!(
    :width => (opts[:buffer_width] || 0),
    :height => (opts[:buffer_height] || 0)
  )
end

Public Instance Methods

buffer_height() click to toggle source

Return an integer of the height of the buffer at it tallest point

# File lib/peter_pan.rb, line 77
def buffer_height
  @buffer.size
end
buffer_width() click to toggle source

Return an integer of the width of the buffer at it’s widest point.

# File lib/peter_pan.rb, line 66
def buffer_width
  if !@buffer_width || buffer_changed?
    @buffer_width = 0
    @buffer.each do |by|
      @buffer_width = by.size if by.size > @buffer_width
    end
  end
  @buffer_width
end
clear_buffer!(opts={}) click to toggle source

clears everything out of the buffer. By default, sets the buffer dimensions to 0x0. Optionally, you can pass :width and :height args and the buffer dimentions will be set accordingly. By default the buffer will be filled with space character, but you can set the char to be used by passing :clear_with

# File lib/peter_pan.rb, line 159
def clear_buffer!(opts={})
  opts = { :width => 0, :height => 0, :clear_with => @empty_point_character }.merge(opts)
  @buffer = [[]]
  opts[:height].times do |y|
    @buffer[y] = []
    opts[:width].times do |x|
      @buffer[y][x] = opts[:clear_with].to_s.slice(0,1)
    end
  end
  buffer_changed!
end
font() click to toggle source

returns a data structure representing the current font used by write.

# File lib/peter_pan.rb, line 172
def font
  @font ||= YAML.load(File.new("#{Gem.loaded_specs['peter_pan'].full_gem_path}/fonts/#{@font_name}.yml").read)
end
pan_viewport(x1, y1, x2, y2) click to toggle source

Move the viewport over the buffer from x1/y1 to x2/y2. Returns an array of strings. Each string is a frame of the pan path of the kind returned by show_viewport.

# File lib/peter_pan.rb, line 102
def pan_viewport(x1, y1, x2, y2)
  calculate_integral_points(x1, y1, x2, y2).map do |px, py|
    show_viewport(px, py)
  end
end
path_viewport(*coordinates) click to toggle source

Like pan_viewport, but multiple pairs of coordinates can be passed. The first pair will be used as the start and the viewport will be panned from coordinate-pair to coordinate-pair. It expects to be passed an array-like list of coordinate pairs. It returns an array of string representing the frames of the pathing.

# File lib/peter_pan.rb, line 118
def path_viewport(*coordinates)
  coordinates.flatten!
  start_x = coordinates.shift
  start_y = coordinates.shift
  coordinates.flatten.each_slice(2).map do |x,y|
    pan = pan_viewport(start_x, start_y, x, y)
    start_x = x
    start_y = y
    pan
  end.flatten
end
plot(x, y, value='*') click to toggle source

Draw a point in the virtual buffer. The virtual buffer will be enlarged automatically.

# File lib/peter_pan.rb, line 40
def plot(x, y, value='*')
  1.upto(y+1) do |i|
    @buffer[i-1] ||= []
    1.upto(x+1) do |ii|
      @buffer[i-1][ii-1] ||= @empty_point_character
    end
  end

  @buffer[y][x] = value.to_s.slice(0,1)

  buffer_changed!
end
plot_sprite(sprite, x, y) click to toggle source

Draw a text sprint to the buffer at given coordinates.

  • sprite is an ARRAY of string representing the image.

# File lib/peter_pan.rb, line 137
def plot_sprite(sprite, x, y)
  sprite.each_with_index do |line, line_y|
    line.split('').each_with_index do |c, char_x|
      plot(char_x + x, line_y + y, c)
    end
  end
end
pretty_pan_viewport(x1, y1, x2, y2) click to toggle source

Same as pan_viewport, but with an ascii-art border around each frame.

# File lib/peter_pan.rb, line 109
def pretty_pan_viewport(x1, y1, x2, y2)
  pan_viewport(x1, y1, x2, y2).map{|vp| wrap_frame_with_border(vp) }
end
pretty_path_viewport(*coordinates) click to toggle source

Same as path_viewport, but with an ascii-art border around each frame.

# File lib/peter_pan.rb, line 131
def pretty_path_viewport(*coordinates)
  path_viewport(coordinates).map{|vp| wrap_frame_with_border(vp) }
end
pretty_print_buffer() click to toggle source

Same as show_buffer but with an ascii-art border around it.

# File lib/peter_pan.rb, line 54
def pretty_print_buffer
  wrap_frame_with_border(show_buffer)
end
pretty_print_viewport(x,y,x2=@viewport_width,y2=@viewport_height) click to toggle source

Same as show_viewort, but with an ascii-art border around it.

# File lib/peter_pan.rb, line 95
def pretty_print_viewport(x,y,x2=@viewport_width,y2=@viewport_height)
  wrap_frame_with_border(show_viewport(x,y,x2,y2))
end
show_buffer() click to toggle source

Return the current buffer as a string delimited by “n” characters

# File lib/peter_pan.rb, line 59
def show_buffer
  normalize_buffer_width

  @buffer.map{|bx| "#{bx.join}\n" }.join
end
show_viewport(x,y,x2=@viewport_width,y2=@viewport_height) click to toggle source

Show a viewport area of the larger buffer. width and height of the viewport can be set in the object initialization for defaults, or manually here. Returns a string delimited by “n” characters.

# File lib/peter_pan.rb, line 85
def show_viewport(x,y,x2=@viewport_width,y2=@viewport_height)
  normalize_buffer_width

  y.upto((y2-1)+y).map do |i|
    buffer_row = @buffer[i] || @viewport_width.times.map{@empty_point_character}
    sprintf("%-#{x2}s", buffer_row[x..((x2-1)+x)].join) + "\n"
  end.join
end
write(letter_x, letter_y, message) click to toggle source

Write a string to the buffer at the given coordinates.

# File lib/peter_pan.rb, line 146
def write(letter_x, letter_y, message)
  message.split('').each do |c|
    char = font_character(c)
    plot_sprite(char, letter_x, letter_y)
    letter_x = letter_x + font['width'] + 1
  end
end

Private Instance Methods

buffer_changed!(val = true) click to toggle source
# File lib/peter_pan.rb, line 184
def buffer_changed!(val = true)
  @buffer_changed = val
end
buffer_changed?() click to toggle source
# File lib/peter_pan.rb, line 188
def buffer_changed?
  !!@buffer_changed
end
calculate_integral_points(x1, y1, x2, y2) click to toggle source

Why yes, actually, I did fail Jr. High math. Why do you ask?

# File lib/peter_pan.rb, line 217
def calculate_integral_points(x1, y1, x2, y2)
  x_integrals = calculate_integrals(x1, x2)
  y_integrals = calculate_integrals(y1, y2)

  (x_integrals, y_integrals) = standardize_integral_lengths(x_integrals, y_integrals)

  x_integrals.zip(y_integrals)
end
calculate_integrals(starting, ending) click to toggle source
# File lib/peter_pan.rb, line 238
def calculate_integrals(starting, ending)
  integrals = []
  if starting < ending
    starting.upto(ending) do |i|
      integrals << i
    end
  else
    starting.downto(ending) do |i|
      integrals << i
    end
  end
  integrals
end
font_character(char) click to toggle source

return the font character for a given character. If no character exists, return ‘?’ instead.

# File lib/peter_pan.rb, line 180
def font_character(char)
  (font['characters'][char] || font['characters']['?']).map{|l|l.gsub('.', @empty_point_character)}
end
normalize_buffer_width() click to toggle source
# File lib/peter_pan.rb, line 192
def normalize_buffer_width
  return unless buffer_changed?

  @buffer.each do |by|
    if by.size < buffer_width
      (by.size-1).upto(buffer_width-1) do |i|
        by[i] = @empty_point_character
      end
    end
  end

  buffer_changed!
end
standardize_integral_lengths(one, two) click to toggle source
# File lib/peter_pan.rb, line 226
def standardize_integral_lengths(one, two)
  while one.length < two.length
    one.unshift(one.first)
  end

  while two.length < one.length
    two.unshift(two.first)
  end

  [one, two]
end
wrap_frame_with_border(content) click to toggle source
# File lib/peter_pan.rb, line 207
def wrap_frame_with_border(content)
  content_width = content.index("\n")
  str = "+#{'-' * content_width}+\n"
  vp = content
  str << vp.gsub(/^/, '|').gsub(/$/, '|').gsub(/^\|$/, '')
  str << "+#{'-' * content_width}+\n"
  str
end