Class: RichEngine::Canvas

Inherits:
Object
  • Object
show all
Defined in:
lib/rich_engine/canvas.rb,
lib/rich_engine/canvas/slot.rb

Overview

A 2D character grid that you draw to each frame, with colored text and shapes. Cells are stored row-major in a flat array.

Direct Known Subclasses

Slot

Defined Under Namespace

Classes: Slot

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(width, height, bg: " ") ⇒ Canvas

Returns a new instance of Canvas.

Parameters:

  • width (Integer)

    the canvas width in characters

  • height (Integer)

    the canvas height in characters

  • bg (String) (defaults to: " ")

    the background fill character



21
22
23
24
25
26
# File 'lib/rich_engine/canvas.rb', line 21

def initialize(width, height, bg: " ")
  @width = width
  @height = height
  @bg = bg
  clear
end

Instance Attribute Details

#bgArray<String>, ...

Returns:

  • (Array<String>)

    the flat, row-major array of cell contents

  • (String)

    the background fill character

  • (Integer)

    the canvas width in characters

  • (Integer)

    the canvas height in characters



16
17
18
# File 'lib/rich_engine/canvas.rb', line 16

def bg
  @bg
end

#canvasArray<String>, ... (readonly)

Returns:

  • (Array<String>)

    the flat, row-major array of cell contents

  • (String)

    the background fill character

  • (Integer)

    the canvas width in characters

  • (Integer)

    the canvas height in characters



16
17
18
# File 'lib/rich_engine/canvas.rb', line 16

def canvas
  @canvas
end

#heightArray<String>, ... (readonly)

Returns:

  • (Array<String>)

    the flat, row-major array of cell contents

  • (String)

    the background fill character

  • (Integer)

    the canvas width in characters

  • (Integer)

    the canvas height in characters



16
17
18
# File 'lib/rich_engine/canvas.rb', line 16

def height
  @height
end

#widthArray<String>, ... (readonly)

Returns:

  • (Array<String>)

    the flat, row-major array of cell contents

  • (String)

    the background fill character

  • (Integer)

    the canvas width in characters

  • (Integer)

    the canvas height in characters



16
17
18
# File 'lib/rich_engine/canvas.rb', line 16

def width
  @width
end

Instance Method Details

#[](x, y) ⇒ String?

Read the cell at (x, y). Coordinates are rounded to integers.

Parameters:

  • x (Integer)

    the column

  • y (Integer)

    the row

Returns:

  • (String, nil)

    the cell contents



170
171
172
173
174
175
# File 'lib/rich_engine/canvas.rb', line 170

def [](x, y)
  x = x.round
  y = y.round

  @canvas[at(x, y)]
end

#[]=(x, y, value) ⇒ void

This method returns an undefined value.

Write a cell at (x, y), ignoring out-of-bounds writes. Coordinates are rounded to integers.

Parameters:

  • x (Integer)

    the column

  • y (Integer)

    the row

  • value (String)

    the cell contents to write



184
185
186
187
188
189
190
# File 'lib/rich_engine/canvas.rb', line 184

def []=(x, y, value)
  x = x.round
  y = y.round
  return if out_of_bounds?(x, y)

  @canvas[at(x, y)] = value
end

#clearvoid

This method returns an undefined value.

Clear the entire canvas, resetting every cell to the background fill.



195
196
197
# File 'lib/rich_engine/canvas.rb', line 195

def clear
  @canvas = create_blank_canvas
end

#dimensionsArray(Integer, Integer)

The canvas dimensions as a [width, height] pair.

Returns:

  • (Array(Integer, Integer))

    the width and height



31
32
33
# File 'lib/rich_engine/canvas.rb', line 31

def dimensions
  [@width, @height]
end

#draw_circle(x:, y:, radius:, char: "█", color: :white) ⇒ void

This method returns an undefined value.

Draw a filled circle centered on (x, y). The center is rounded to integers.

Parameters:

  • x (Integer)

    the center column

  • y (Integer)

    the center row

  • radius (Integer)

    the circle radius

  • char (String) (defaults to: "█")

    the character to fill with

  • color (Symbol, String, Array<Integer>, Integer) (defaults to: :white)

    the fill color



138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/rich_engine/canvas.rb', line 138

def draw_circle(x:, y:, radius:, char: "", color: :white)
  x = x.round
  y = y.round

  (x - radius..x + radius).each do |x_pos|
    (y - radius..y + radius).each do |y_pos|
      next if (x_pos - x)**2 + (y_pos - y)**2 > radius**2

      self[x_pos, y_pos] = char.fg(color)
    end
  end
end

#draw_rect(x:, y:, width:, height:, char: "█", color: :white) ⇒ void

This method returns an undefined value.

Draw a filled rectangle. Coordinates and sizes are rounded to integers.

Parameters:

  • x (Integer)

    the left column

  • y (Integer)

    the top row

  • width (Integer)

    the rectangle width

  • height (Integer)

    the rectangle height

  • char (String) (defaults to: "█")

    the character to fill with

  • color (Symbol, String, Array<Integer>, Integer) (defaults to: :white)

    the fill color



116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/rich_engine/canvas.rb', line 116

def draw_rect(x:, y:, width:, height:, char: "", color: :white)
  x = x.round
  y = y.round
  width = width.round
  height = height.round

  (x..(x + width - 1)).each do |x_pos|
    (y..(y + height - 1)).each do |y_pos|
      self[x_pos, y_pos] = char.fg(color)
    end
  end
end

#draw_sprite(sprite, x: 0, y: 0, fg: :white, bg: :transparent) ⇒ void

This method returns an undefined value.

Draw a multi-line string as a sprite; spaces are treated as transparent and left untouched.

Parameters:

  • sprite (String)

    the multi-line sprite to draw

  • x (Integer) (defaults to: 0)

    the left column to start drawing at

  • y (Integer) (defaults to: 0)

    the top row to start drawing at

  • fg (Symbol, String, Array<Integer>, Integer) (defaults to: :white)

    the foreground color

  • bg (Symbol, String, Array<Integer>, Integer) (defaults to: :transparent)

    the background color



64
65
66
67
68
69
70
71
72
# File 'lib/rich_engine/canvas.rb', line 64

def draw_sprite(sprite, x: 0, y: 0, fg: :white, bg: :transparent)
  sprite.split("\n").each.with_index do |line, i|
    line.each_char.with_index do |char, j|
      next if char == " "

      self[x + j, y + i] = char.fg(fg).bg(bg)
    end
  end
end

#each_coord {|x, y| ... } ⇒ void

This method returns an undefined value.

Yield every (x, y) coordinate in the canvas.

Yield Parameters:

  • x (Integer)

    the column

  • y (Integer)

    the row



40
41
42
43
44
45
46
# File 'lib/rich_engine/canvas.rb', line 40

def each_coord(&block)
  (0...@width).each do |x|
    (0...@height).each do |y|
      block.call(x, y)
    end
  end
end

#out_of_bounds?(x, y) ⇒ Boolean

Whether the given coordinate falls outside the canvas.

Parameters:

  • x (Integer)

    the column

  • y (Integer)

    the row

Returns:

  • (Boolean)

    true if (x, y) is outside the canvas bounds



156
157
158
159
160
161
162
163
# File 'lib/rich_engine/canvas.rb', line 156

def out_of_bounds?(x, y)
  return true if x < 0
  return true if x >= @width
  return true if y < 0
  return true if y >= @height

  false
end

#rowsEnumerator

Enumerate the canvas one row at a time.

Returns:

  • (Enumerator)

    an enumerator of rows, each an array of cells



51
52
53
# File 'lib/rich_engine/canvas.rb', line 51

def rows
  @canvas.each_slice(@width)
end

#slot(x:, y:, width:, height:, bg: nil) ⇒ RichEngine::Canvas::Slot

Define a logical sub-region of this canvas that translates local coordinates into the parent canvas space and clips drawing to the region.

Examples:

log = canvas.slot(x: 80, y: 0, width: 20, height: 10)
log.write_string("Hello", x: 1, y: 1)  # => writes at (81, 1)

Parameters:

  • x (Integer)

    the region's left column on the parent canvas

  • y (Integer)

    the region's top row on the parent canvas

  • width (Integer)

    the region width

  • height (Integer)

    the region height

  • bg (String, nil) (defaults to: nil)

    the slot's background fill, or nil to inherit the parent's

Returns:



221
222
223
# File 'lib/rich_engine/canvas.rb', line 221

def slot(x:, y:, width:, height:, bg: nil)
  Slot.new(self, x, y, width, height, bg: bg)
end

#write_string(str, x: 0, y: 0, fg: :white, bg: :transparent) ⇒ void

This method returns an undefined value.

Write colored text at a position. Pass :center for x or y to center the text along that axis. A single color applies to every character; an array of colors cycles per character.

Examples:

Cycle foreground colors per character

canvas.write_string("Hello", x: :center, y: 1, fg: [:red, :green, :blue])

Parameters:

  • str (String)

    the text to write

  • x (Integer, Symbol) (defaults to: 0)

    the left column, or :center to horizontally center the text

  • y (Integer, Symbol) (defaults to: 0)

    the row, or :center to vertically center the text

  • fg (Symbol, String, Array<Integer>, Integer, Array) (defaults to: :white)

    the foreground color, or an array of color specs to cycle per character

  • bg (Symbol, String, Array<Integer>, Integer, Array) (defaults to: :transparent)

    the background color, or an array of color specs to cycle per character



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/rich_engine/canvas.rb', line 90

def write_string(str, x: 0, y: 0, fg: :white, bg: :transparent)
  if x == :center
    x = (@width - str.length) / 2
  end

  if y == :center
    y = (@height - 1) / 2
  end

  fg = Array(fg).cycle
  bg = Array(bg).cycle

  str.to_s.each_char.with_index do |char, i|
    self[x + i, y] = char.fg(fg.next).bg(bg.next)
  end
end