Class: RGame::Core::UiAtlas

Inherits:
Object
  • Object
show all
Defined in:
lib/rgame/core/ui_atlas.rb

Overview

One sheet of UI chrome, cut into named nine-slices.

atlas = RGame::Core::UiAtlas.load(app, 'media/ui.json')
renderer.register_ui_atlas(atlas)
renderer.nine_slice(:button_idle, x, y, width, height)

A button has four states, a panel has one, a scrollbar has three pieces — all of them small, and all of them cheaper as sub-rectangles of a single texture than as a dozen separate files. This is that texture plus a descriptor naming what is where.

The descriptor

{
"image": "buttons.png",
"scale": 3,
"nine_slices": {
  "button_idle":  { "x": 11, "y": 59, "w": 26, "h": 28, "border": 7 },
  "button_focus": { "x": 43, "y": 59, "w": 26, "h": 28, "border": 7 },
  "panel":        { "x": 0,  "y": 0,  "w": 32, "h": 32,
                    "border": { "left": 4, "right": 4, "top": 8, "bottom": 4 },
                    "scale": 2 }
}
}

image is resolved next to the descriptor. Each entry is a source rectangle plus a border — a uniform integer or one value per side — and an optional scale overriding the sheet default. See RGame::Core::NineSlice for what those mean when it is drawn.

Element names, not filenames

nine_slices is keyed by whatever the descriptor calls each element, and those names are what a widget asks for. That is why nine-slices are the one asset the renderer resolves by registration only: :button_focus is not a file and never can be. Renderer#register_ui_atlas registers every element in one call.

Parsing happens once, at load. Nothing here is touched again per frame.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(image, data) ⇒ UiAtlas

data is the parsed descriptor; image an already-loaded sheet.



64
65
66
67
68
69
70
# File 'lib/rgame/core/ui_atlas.rb', line 64

def initialize(image, data)
  sheet_scale = data[:scale] || 1

  @nine_slices = (data[:nine_slices] || {}).to_h do |id, spec|
    [id, build(image, id, spec, sheet_scale)]
  end
end

Instance Attribute Details

#nine_slicesObject (readonly)

The elements, by name. Values are NineSlices.



51
52
53
# File 'lib/rgame/core/ui_atlas.rb', line 51

def nine_slices
  @nine_slices
end

Class Method Details

.load(app, atlas_path) ⇒ Object

Loads a descriptor and the sheet beside it.

The AssetManager uses .new instead, with an image it has already cached, so the sheet is shared with any other use of the same file.



57
58
59
60
61
# File 'lib/rgame/core/ui_atlas.rb', line 57

def self.load(app, atlas_path)
  data = JSON.parse(File.read(atlas_path), symbolize_names: true)
  directory = File.dirname(File.expand_path(atlas_path))
  new(Image.new(app, File.join(directory, data[:image])), data)
end