red_bird 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +23 -0
- data/LICENSE.txt +21 -0
- data/README.md +47 -0
- data/Rakefile +10 -0
- data/bin/setup +8 -0
- data/ext/red_bird/bird.c +15 -0
- data/ext/red_bird/bird.h +10 -0
- data/ext/red_bird/color.c +95 -0
- data/ext/red_bird/color.h +27 -0
- data/ext/red_bird/dynamic_sprite.c +163 -0
- data/ext/red_bird/dynamic_sprite.h +30 -0
- data/ext/red_bird/engine.c +354 -0
- data/ext/red_bird/engine.h +40 -0
- data/ext/red_bird/extconf.rb +9 -0
- data/ext/red_bird/font.c +94 -0
- data/ext/red_bird/font.h +26 -0
- data/ext/red_bird/input_device.c +100 -0
- data/ext/red_bird/input_device.h +15 -0
- data/ext/red_bird/keycode.c +42 -0
- data/ext/red_bird/keycode.h +12 -0
- data/ext/red_bird/loader.c +154 -0
- data/ext/red_bird/loader.h +54 -0
- data/ext/red_bird/main.c +38 -0
- data/ext/red_bird/main.h +12 -0
- data/ext/red_bird/palette.c +132 -0
- data/ext/red_bird/palette.h +23 -0
- data/ext/red_bird/rect.c +257 -0
- data/ext/red_bird/rect.h +20 -0
- data/ext/red_bird/render.c +130 -0
- data/ext/red_bird/render.h +25 -0
- data/ext/red_bird/sprite.c +130 -0
- data/ext/red_bird/sprite.h +27 -0
- data/ext/red_bird/text.c +212 -0
- data/ext/red_bird/text.h +31 -0
- data/ext/red_bird/texture.c +157 -0
- data/ext/red_bird/texture.h +33 -0
- data/ext/red_bird/texture_imp.cpp +49 -0
- data/ext/red_bird/texture_imp.hpp +29 -0
- data/ext/red_bird/timer.c +134 -0
- data/ext/red_bird/timer.h +25 -0
- data/lib/red_bird.rb +15 -0
- data/lib/red_bird/animation.rb +133 -0
- data/lib/red_bird/camera.rb +61 -0
- data/lib/red_bird/controller.rb +44 -0
- data/lib/red_bird/dynamic_sprite.rb +38 -0
- data/lib/red_bird/engine.rb +81 -0
- data/lib/red_bird/entity.rb +74 -0
- data/lib/red_bird/entity_collision.rb +31 -0
- data/lib/red_bird/input_device.rb +86 -0
- data/lib/red_bird/palette.rb +23 -0
- data/lib/red_bird/relative_entity.rb +95 -0
- data/lib/red_bird/sprite.rb +40 -0
- data/lib/red_bird/stage.rb +60 -0
- data/lib/red_bird/tile_map.rb +118 -0
- data/lib/red_bird/tile_set.rb +56 -0
- data/lib/red_bird/uibox.rb +143 -0
- data/lib/red_bird/version.rb +3 -0
- data/lib/red_bird/vertical_menu.rb +110 -0
- data/red_bird.gemspec +37 -0
- metadata +149 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
2
|
+
module RedBird
|
3
|
+
# A rectangular part of a texture. It allows you to print only a portion of
|
4
|
+
# the image instead of it all. This will, for example, enable you to insert
|
5
|
+
# several animation frames into the same texture instead of having to load
|
6
|
+
# several small files.
|
7
|
+
# @author Frederico Linhares
|
8
|
+
class Sprite
|
9
|
+
# Create an array of sprites and return it. The array has homogeneous
|
10
|
+
# sprites that do not overlap and have no gaps between them.
|
11
|
+
#
|
12
|
+
# To create a grid starting from the position x 20, y 20, containing three
|
13
|
+
# columns and two rows, each sprite, having 100x80 pixels:
|
14
|
+
#
|
15
|
+
# RedBird::Texture.grid sprite, 20, 20, 3, 2, 100, 80
|
16
|
+
#
|
17
|
+
# @param texture [RedBird::Texture] a texture that will be used as the
|
18
|
+
# source for all sprites.
|
19
|
+
# @param init_x [Integer] initial x coordinate for the grid.
|
20
|
+
# @param init_y [Integer] initial y coordinate for the grid.
|
21
|
+
# @param num_hor_sprites [Integer] number of columns the grid will have.
|
22
|
+
# @param num_ver_sprites [Integer] number of rows the grid will have.
|
23
|
+
# @param width [Integer] width of every sprite.
|
24
|
+
# @param height [Integer] height of every sprite.
|
25
|
+
# @return [Array]
|
26
|
+
# @author Frederico Linhares
|
27
|
+
def self.grid(texture, init_x, init_y, num_hor_sprites, num_ver_sprites,
|
28
|
+
width, height)
|
29
|
+
sprites = []
|
30
|
+
num_ver_sprites.times do |v|
|
31
|
+
num_hor_sprites.times do |h|
|
32
|
+
sprites << Sprite.new(
|
33
|
+
texture, init_x + h * width, init_y + v * height, width, height)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
return sprites
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
2
|
+
module RedBird
|
3
|
+
# A game built with RedBird consists of a succession of Stages. A game has
|
4
|
+
# only a single Stage running at a time. Each Stage must have an
|
5
|
+
# {RedBird::InputDevice} instance and an Array of {RedBird::Entity}
|
6
|
+
# instances.
|
7
|
+
#
|
8
|
+
# This class contains a basic set of functionalities that every stage of a
|
9
|
+
# game needs.
|
10
|
+
#
|
11
|
+
# @!attribute [r] input_device
|
12
|
+
# @return [RedBird::InputDevice] the class that inherits from Stage must
|
13
|
+
# defines an variable +@input_device+ containing and instance of
|
14
|
+
# {RedBird::InputDevice}.
|
15
|
+
# @!attribute [r] entities
|
16
|
+
# @return [Array<RedBird::Entity>]
|
17
|
+
# @author Frederico Linhares
|
18
|
+
class Stage
|
19
|
+
attr_accessor :input_device, :entities
|
20
|
+
|
21
|
+
# @param global_data [Object] use this to share common data among different
|
22
|
+
# stages.
|
23
|
+
# @author Frederico Linhares
|
24
|
+
def initialize(global_data)
|
25
|
+
@global_data = global_data
|
26
|
+
@entities = []
|
27
|
+
end
|
28
|
+
|
29
|
+
# Add a new entity to this stage. This method organizes the entities as
|
30
|
+
# expected by some methods in {RedBird::Engine}.
|
31
|
+
#
|
32
|
+
# @param entities [Entity, Array<Entity>]
|
33
|
+
# @author Frederico Linhares
|
34
|
+
def add_entities(entities)
|
35
|
+
if entities.is_a? Array then
|
36
|
+
@entities.concat entities
|
37
|
+
else
|
38
|
+
@entities << entities
|
39
|
+
end
|
40
|
+
|
41
|
+
@entities.sort! { |a, b| a.priority <=> b.priority }
|
42
|
+
end
|
43
|
+
|
44
|
+
# {RedBird::Engine} calls this method before it ticks entities. Overwrite
|
45
|
+
# this to add routines that must run before entities tick.
|
46
|
+
#
|
47
|
+
# @author Frederico Linhares
|
48
|
+
def pre_tick
|
49
|
+
# By default do nothing.
|
50
|
+
end
|
51
|
+
|
52
|
+
# {RedBird::Engine} calls this method after it ticks entities. Overwrite
|
53
|
+
# this to add routines that must run after entities tick.
|
54
|
+
#
|
55
|
+
# @author Frederico Linhares
|
56
|
+
def post_tick
|
57
|
+
# By default do nothing.
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
2
|
+
require_relative "tile_set"
|
3
|
+
|
4
|
+
module RedBird
|
5
|
+
# A TileMap is a grid of {RedBird::Sprite}s; it works as a scenario. It has
|
6
|
+
# scrolling functionalities to control which portion of it is on the screen.
|
7
|
+
#
|
8
|
+
# @!attribute [rw] hor_offset
|
9
|
+
# @return [Integer] how much the tilemap scrolled from the left corner.
|
10
|
+
# @!attribute [rw] ver_offset
|
11
|
+
# @return [Integer] how much the tilemap scrolled from the top.
|
12
|
+
# @!attribute [r] tiles
|
13
|
+
# @return [Array<Integer>] tiles indexes.
|
14
|
+
# @!attribute [r] tile_set
|
15
|
+
# @return [RedBird::TileSet] tile set in use by this class.
|
16
|
+
# @!attribute [r] total_width
|
17
|
+
# @return [Integer] width of the entire tilemap (not only what is displayed
|
18
|
+
# in the screen).
|
19
|
+
# @!attribute [r] total_height
|
20
|
+
# @return [Integer] height of the entire tilemap (not only what is
|
21
|
+
# displayed in the screen).
|
22
|
+
# @author Frederico Linhares
|
23
|
+
class TileMap < Entity
|
24
|
+
attr_accessor :hor_offset, :ver_offset
|
25
|
+
attr_reader :tiles, :tile_set, :total_width, :total_height
|
26
|
+
|
27
|
+
# @param tile_set [RedBird::TileSet]
|
28
|
+
# @param pos_x [Integer] horizontal position of this map in the screen.
|
29
|
+
# @param pos_y [Integer] vertical position of this map in the screen.
|
30
|
+
# @param width [Integer] width of the region displayed in the screen.
|
31
|
+
# @param height [Integer] height of the region displayed in the screen.
|
32
|
+
# @param num_hor_tiles [Integer] total width in number of tiles.
|
33
|
+
# @param num_ver_tiles [Integer] total height in number of tiles.
|
34
|
+
# @param tiles [Array<Integer>] code of every tile to display, must be an
|
35
|
+
# one dimension array.
|
36
|
+
# @author Frederico Linhares
|
37
|
+
def initialize(tile_set, pos_x, pos_y, width, height, num_hor_tiles,
|
38
|
+
num_ver_tiles, tiles)
|
39
|
+
@tile_set = tile_set
|
40
|
+
@pos_x = pos_x
|
41
|
+
@pos_y = pos_y
|
42
|
+
|
43
|
+
@width = width
|
44
|
+
@height = height
|
45
|
+
|
46
|
+
@ver_offset = 0
|
47
|
+
@hor_offset = 0
|
48
|
+
|
49
|
+
@priority = -1
|
50
|
+
|
51
|
+
@tiles = tiles
|
52
|
+
|
53
|
+
# Number of tiles that are going to be rendered to screen.
|
54
|
+
@render_hor_tiles = @width / @tile_set.tile_width + 1
|
55
|
+
@render_ver_tiles = @height / @tile_set.tile_height + 1
|
56
|
+
|
57
|
+
@total_hor_tiles = num_hor_tiles
|
58
|
+
@total_ver_tiles = num_ver_tiles
|
59
|
+
|
60
|
+
@total_width = @total_hor_tiles * @tile_set.tile_width
|
61
|
+
@total_height = @total_ver_tiles * @tile_set.tile_height
|
62
|
+
end
|
63
|
+
|
64
|
+
# Load information from a yaml file and uses it create an instance of this
|
65
|
+
# class.
|
66
|
+
#
|
67
|
+
# @param data_dir [String] path to the directory containing the yaml and
|
68
|
+
# other files referenced in the yaml.
|
69
|
+
# @param map_file [String] path to the yaml file.
|
70
|
+
# @return [RedBird::TileMap]
|
71
|
+
# @author Frederico Linhares
|
72
|
+
def self.from_yml(data_dir, map_file, tile_set, pos_x, pos_y, width,
|
73
|
+
height)
|
74
|
+
yaml_file = data_dir + map_file
|
75
|
+
|
76
|
+
data = YAML.load_file(yaml_file)
|
77
|
+
num_hor_tiles = data["num_hor_tiles"]
|
78
|
+
num_ver_tiles = data["num_ver_tiles"]
|
79
|
+
tiles = data["tiles"].unpack("S*")
|
80
|
+
|
81
|
+
return self.new(
|
82
|
+
tile_set, pos_x, pos_y, width, height, num_hor_tiles,
|
83
|
+
num_ver_tiles, tiles)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Gets the {RedBird::Sprite} at position x, y.
|
87
|
+
#
|
88
|
+
# @param x [Integer]
|
89
|
+
# @param y [Integer]
|
90
|
+
# @author Frederico Linhares
|
91
|
+
def tile_xy(x, y)
|
92
|
+
return @tile_set.tiles[@tiles[y_to_tile(y) + x]][:type]
|
93
|
+
end
|
94
|
+
|
95
|
+
# Renders this tilemap to the screen.
|
96
|
+
#
|
97
|
+
# @author Frederico Linhares
|
98
|
+
def render
|
99
|
+
first_hor_tile = @hor_offset / @tile_set.tile_width
|
100
|
+
first_ver_tile = @ver_offset / @tile_set.tile_height
|
101
|
+
|
102
|
+
(first_ver_tile..(first_ver_tile + @render_ver_tiles)).each do |y|
|
103
|
+
(first_hor_tile..(first_hor_tile + @render_hor_tiles)).each do |x|
|
104
|
+
unless @tiles[y_to_tile(y) + x].nil? then
|
105
|
+
@tile_set.tiles[@tiles[y_to_tile(y) + x]].render_to_screen(
|
106
|
+
x * @tile_set.tile_width - @hor_offset + @pos_x,
|
107
|
+
y * @tile_set.tile_height - @ver_offset + @pos_y)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
def y_to_tile(y)
|
115
|
+
return y * @total_hor_tiles
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module RedBird
|
5
|
+
# A TileSet is a set of {RedBird::Sprite}s. It allows you to reuse the same
|
6
|
+
# {RedBird::Sprite} several times in the creation of a game scenario, making
|
7
|
+
# the level design more straightforward.
|
8
|
+
#
|
9
|
+
# @!attribute [r] tiles
|
10
|
+
# @return [Array<RedBird::TileSet::Sprite>]
|
11
|
+
# @!attribute [r] tile_width
|
12
|
+
# @return [Integer] width of each tile.
|
13
|
+
# @!attribute [r] tile_height
|
14
|
+
# @return [Integer] height of each tile.
|
15
|
+
# @author Frederico Linhares
|
16
|
+
class TileSet
|
17
|
+
attr_reader :tiles, :tile_width, :tile_height
|
18
|
+
|
19
|
+
# @param texture_file [String] this method uses the path as argument to
|
20
|
+
# create a {RedBird::Texture}.
|
21
|
+
# @param tile_width [Integer] width of each tile.
|
22
|
+
# @param tile_height [Integer] height of each tile.
|
23
|
+
# @author Frederico Linhares
|
24
|
+
def initialize(texture_file, texture_palette, tile_width, tile_height)
|
25
|
+
@texture = RedBird::Texture.new(texture_file, texture_palette)
|
26
|
+
|
27
|
+
@tile_width = tile_width
|
28
|
+
@tile_height = tile_height
|
29
|
+
|
30
|
+
horizontal_tiles = @texture.width / @tile_width
|
31
|
+
vertical_tiles = @texture.height / @tile_height
|
32
|
+
|
33
|
+
@tiles = Sprite.grid(
|
34
|
+
@texture, 0, 0, horizontal_tiles, vertical_tiles, @tile_width,
|
35
|
+
@tile_height)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Load information from a yaml file and uses it create an instance of this
|
39
|
+
# class.
|
40
|
+
#
|
41
|
+
# @param data_dir [String] path to the directory containing the yaml and
|
42
|
+
# other files referenced in the yaml.
|
43
|
+
# @param tile_file [String] path to the yaml file.
|
44
|
+
# @return [RedBird::TileSet]
|
45
|
+
# @author Frederico Linhares
|
46
|
+
def self.from_yml(data_dir, tile_file, palette)
|
47
|
+
yaml_file = data_dir + tile_file
|
48
|
+
|
49
|
+
data = YAML.load_file(yaml_file)
|
50
|
+
texture_path = data_dir + data["texture"]
|
51
|
+
|
52
|
+
return self.new(texture_path, palette, data["width"], data["height"])
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
2
|
+
module RedBird
|
3
|
+
# User Interface Box works as a visual background for texts, menus, or
|
4
|
+
# anything else.
|
5
|
+
#
|
6
|
+
# @author Frederico Linhares
|
7
|
+
class UIBox < Entity
|
8
|
+
# A style defines the visual appearance of a Box.
|
9
|
+
#
|
10
|
+
# @author Frederico Linhares
|
11
|
+
class Style
|
12
|
+
# @!attribute [r] texture
|
13
|
+
# @return [RedBird::Texture]
|
14
|
+
# @!attribute [r] bg_color
|
15
|
+
# @return [RedBird::Color]
|
16
|
+
# @!attribute [r] sprites
|
17
|
+
# @return [Array<RedBird::Sprite>]
|
18
|
+
# @!attribute [r] sprite_width
|
19
|
+
# @return [Integer]
|
20
|
+
# @!attribute [r] sprite_height
|
21
|
+
# @return [Integer]
|
22
|
+
attr_reader :texture, :bg_color, :sprites, :sprite_width, :sprite_height
|
23
|
+
|
24
|
+
# @param texture_file [String] path to a image file in the format
|
25
|
+
# required by this class.
|
26
|
+
# @param bg_color [RedBird::Color] color used to fill the background of
|
27
|
+
# the box.
|
28
|
+
# @param sprite_width [Integer] width of each sprite in the
|
29
|
+
# +texture_file+.
|
30
|
+
# @param sprite_height [Integer] height of each sprite in the
|
31
|
+
# +texture_file+.
|
32
|
+
# @author Frederico Linhares
|
33
|
+
def initialize(texture_file, texture_palette, bg_color, sprite_width,
|
34
|
+
sprite_height)
|
35
|
+
@texture = Texture.new(texture_file, texture_palette)
|
36
|
+
@bg_color = bg_color
|
37
|
+
@sprite_width = sprite_width
|
38
|
+
@sprite_height = sprite_height
|
39
|
+
|
40
|
+
@sprites = {}
|
41
|
+
@sprites[:arrow_select] = Sprite.new(
|
42
|
+
@texture, 1 * @sprite_width, 1 * @sprite_height,
|
43
|
+
@sprite_width, @sprite_height)
|
44
|
+
@sprites[:box_top_left] = Sprite.new(
|
45
|
+
@texture, 0, 0, @sprite_width, @sprite_height)
|
46
|
+
@sprites[:box_top] = Sprite.new(
|
47
|
+
@texture, 1 * @sprite_width, 0,
|
48
|
+
@sprite_width, @sprite_height)
|
49
|
+
@sprites[:box_top_right] = Sprite.new(
|
50
|
+
@texture, 2 * @sprite_height, 0,
|
51
|
+
@sprite_width, @sprite_height)
|
52
|
+
@sprites[:box_left] = Sprite.new(
|
53
|
+
@texture, 0, 1 * @sprite_height,
|
54
|
+
@sprite_width, @sprite_height)
|
55
|
+
@sprites[:box_right] = Sprite.new(
|
56
|
+
@texture, 2 * @sprite_width, 1 * @sprite_height,
|
57
|
+
@sprite_width, @sprite_height)
|
58
|
+
@sprites[:box_bottom_left] = Sprite.new(
|
59
|
+
@texture, 0, 2 * @sprite_height,
|
60
|
+
@sprite_width, @sprite_height)
|
61
|
+
@sprites[:box_bottom] = Sprite.new(
|
62
|
+
@texture, 1 * @sprite_width, 2 * @sprite_height,
|
63
|
+
@sprite_width, @sprite_height)
|
64
|
+
@sprites[:box_bottom_right] = Sprite.new(
|
65
|
+
@texture, 2 * @sprite_width, 2 * @sprite_height,
|
66
|
+
@sprite_width, @sprite_height)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# @param style [RedBird::Style]
|
71
|
+
# @param pos_x [Integer]
|
72
|
+
# @param pos_y [Integer]
|
73
|
+
# @param num_vertical_sprites [Integer] number of sprites rows.
|
74
|
+
# @param num_horizontal_sprites [Integer] number of sprites columns.
|
75
|
+
# @author Frederico Linhares
|
76
|
+
def initialize(style, pos_x, pos_y, num_vertical_sprites,
|
77
|
+
num_horizontal_sprites)
|
78
|
+
@style = style
|
79
|
+
@pos_x = pos_x
|
80
|
+
@pos_y = pos_y
|
81
|
+
@num_vertical_sprites = num_vertical_sprites
|
82
|
+
@num_horizontal_sprites = num_horizontal_sprites
|
83
|
+
end
|
84
|
+
|
85
|
+
# The height is defined by +num_horizontal_sprites+ plus two (the borders).
|
86
|
+
# The width of each sprite is defined by the style used.
|
87
|
+
#
|
88
|
+
# @return [Integer]
|
89
|
+
# @author Frederico Linhares
|
90
|
+
def width
|
91
|
+
@style.sprite_width * (@num_horizontal_sprites + 2)
|
92
|
+
end
|
93
|
+
|
94
|
+
# The height is defined by +num_vertical_sprites+ plus two (the borders).
|
95
|
+
# The height of each sprite is defined by the style used.
|
96
|
+
#
|
97
|
+
# @return [Integer]
|
98
|
+
# @author Frederico Linhares
|
99
|
+
def height
|
100
|
+
@style.sprite_height * (@num_vertical_sprites + 2)
|
101
|
+
end
|
102
|
+
|
103
|
+
# Renders to the screen.
|
104
|
+
#
|
105
|
+
# @author Frederico Linhares
|
106
|
+
def render
|
107
|
+
Render.set_color(@style.bg_color)
|
108
|
+
Render.fill_rect(@pos_x, @pos_y, self.width, self.height)
|
109
|
+
|
110
|
+
# Draw the corners.
|
111
|
+
@style.sprites[:box_top_left].render_to_screen(@pos_x, @pos_y)
|
112
|
+
@style.sprites[:box_top_right].render_to_screen(
|
113
|
+
@style.sprite_width * (@num_horizontal_sprites + 1) + @pos_x,
|
114
|
+
@pos_y)
|
115
|
+
@style.sprites[:box_bottom_left].render_to_screen(
|
116
|
+
@pos_x,
|
117
|
+
@style.sprite_height * (@num_vertical_sprites + 1) + @pos_y)
|
118
|
+
@style.sprites[:box_bottom_right].render_to_screen(
|
119
|
+
@style.sprite_width * (@num_horizontal_sprites + 1) + @pos_x,
|
120
|
+
@style.sprite_height * (@num_vertical_sprites + 1) + @pos_y)
|
121
|
+
|
122
|
+
# Draw the edges.
|
123
|
+
@num_horizontal_sprites.times do |i|
|
124
|
+
# Top
|
125
|
+
@style.sprites[:box_top].render_to_screen(
|
126
|
+
@style.sprite_width * (i + 1) + @pos_x, @pos_y)
|
127
|
+
# Bottom
|
128
|
+
@style.sprites[:box_bottom].render_to_screen(
|
129
|
+
@style.sprite_width * (i + 1) + @pos_x,
|
130
|
+
@style.sprite_height * (@num_vertical_sprites + 1) + @pos_y)
|
131
|
+
end
|
132
|
+
@num_vertical_sprites.times do |i|
|
133
|
+
# Left
|
134
|
+
@style.sprites[:box_left].render_to_screen(
|
135
|
+
@pos_x, @style.sprite_height * (i + 1) + @pos_y)
|
136
|
+
# Right
|
137
|
+
@style.sprites[:box_right].render_to_screen(
|
138
|
+
@style.sprite_width * (@num_horizontal_sprites + 1) + @pos_x,
|
139
|
+
@style.sprite_height * (i + 1) + @pos_y)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
2
|
+
require_relative "uibox"
|
3
|
+
|
4
|
+
module RedBird
|
5
|
+
# VerticalMenu is an interactive menu that receives input from players. It
|
6
|
+
# consists of a vertical list of {RedBird::VerticalMenu::Option}.
|
7
|
+
#
|
8
|
+
# @author Frederico Linhares
|
9
|
+
class VerticalMenu < Entity
|
10
|
+
|
11
|
+
# An option to be used in {RedBird::VerticalMenu}.
|
12
|
+
#
|
13
|
+
# @!attribute [r] action
|
14
|
+
# @return [Proc] code for option selection
|
15
|
+
# @!attribute [r] text
|
16
|
+
# @return [String] option name
|
17
|
+
# @author Frederico Linhares
|
18
|
+
class Option
|
19
|
+
attr_accessor :action, :text
|
20
|
+
|
21
|
+
# @param text [String] option name
|
22
|
+
# @param action [Proc] code to use when this option is selected
|
23
|
+
# @author Frederico Linhares
|
24
|
+
def initialize(text, &action)
|
25
|
+
@text = text
|
26
|
+
@action = action
|
27
|
+
@priority = 100
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# @param style [RedBird::UIBox::Style]
|
32
|
+
# @param pos_x [Integer]
|
33
|
+
# @param pos_y [Integer]
|
34
|
+
# @param options [Array<RedBird::VerticalMenu::Option>]
|
35
|
+
# @author Frederico Linhares
|
36
|
+
def initialize(style, pos_x, pos_y, options)
|
37
|
+
@style = style
|
38
|
+
@pos_x = pos_x
|
39
|
+
@pos_y = pos_y
|
40
|
+
|
41
|
+
@options = options
|
42
|
+
@current_option = 0
|
43
|
+
@option_max_width = 0
|
44
|
+
@option_max_height = 0
|
45
|
+
|
46
|
+
@options.each do |i|
|
47
|
+
if @option_max_width < i.text.width then
|
48
|
+
@option_max_width = i.text.width
|
49
|
+
end
|
50
|
+
if @option_max_height < i.text.height then
|
51
|
+
@option_max_height = i.text.height
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# @return [Integer]
|
57
|
+
# @author Frederico Linhares
|
58
|
+
def width
|
59
|
+
@option_max_width
|
60
|
+
end
|
61
|
+
|
62
|
+
# @return [Integer]
|
63
|
+
# @author Frederico Linhares
|
64
|
+
def height
|
65
|
+
@option_max_height * @options.size
|
66
|
+
end
|
67
|
+
|
68
|
+
# Executes the action in the selected option.
|
69
|
+
#
|
70
|
+
# @author Frederico Linhares
|
71
|
+
def activate
|
72
|
+
@options[@current_option].action.call
|
73
|
+
end
|
74
|
+
|
75
|
+
# Changes the selected {RedBird::VerticalMenu::Option} to the next one.
|
76
|
+
#
|
77
|
+
# @author Frederico Linhares
|
78
|
+
def next_opt
|
79
|
+
@current_option += 1
|
80
|
+
@current_option = 0 if @current_option >= @options.size
|
81
|
+
end
|
82
|
+
|
83
|
+
# Changes the selected {RedBird::VerticalMenu::Option} to the previous one.
|
84
|
+
#
|
85
|
+
# @author Frederico Linhares
|
86
|
+
def pred_opt
|
87
|
+
if @current_option <= 0 then
|
88
|
+
@current_option = @options.size - 1
|
89
|
+
else
|
90
|
+
@current_option -= 1
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Renders to the screen.
|
95
|
+
#
|
96
|
+
# @author Frederico Linhares
|
97
|
+
def render
|
98
|
+
# Render texts.
|
99
|
+
@options.each_with_index do |o, i|
|
100
|
+
o.text.render_to_screen(
|
101
|
+
@style.sprite_width * 2 + @pos_x,
|
102
|
+
@style.sprite_height * (i + 1) + @pos_y)
|
103
|
+
end
|
104
|
+
|
105
|
+
@style.sprites[:arrow_select].render_to_screen(
|
106
|
+
@style.sprite_width + @pos_x,
|
107
|
+
@style.sprite_height * (@current_option + 1) + @pos_y)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|