smash_and_grab 0.0.3alpha → 0.0.5alpha
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.
- data/Gemfile.lock +1 -1
- data/README.md +31 -16
- data/config/gui/schema.yml +3 -2
- data/config/map/entities.yml +36 -12
- data/lib/smash_and_grab/abilities/ability.rb +5 -0
- data/lib/smash_and_grab/abilities/melee.rb +11 -5
- data/lib/smash_and_grab/abilities/ranged.rb +20 -0
- data/lib/smash_and_grab/abilities/sprint.rb +4 -0
- data/lib/smash_and_grab/abilities.rb +3 -1
- data/lib/smash_and_grab/fidgit_ext/event.rb +77 -0
- data/lib/smash_and_grab/gui/editor_selector.rb +54 -73
- data/lib/smash_and_grab/gui/entity_panel.rb +110 -0
- data/lib/smash_and_grab/gui/entity_summary.rb +9 -8
- data/lib/smash_and_grab/gui/game_log.rb +44 -0
- data/lib/smash_and_grab/gui/info_panel.rb +39 -95
- data/lib/smash_and_grab/gui/object_panel.rb +37 -0
- data/lib/smash_and_grab/gui/scenario_panel.rb +21 -0
- data/lib/smash_and_grab/history/editor_actions/place_object.rb +1 -1
- data/lib/smash_and_grab/main.rb +11 -16
- data/lib/smash_and_grab/map/map.rb +1 -0
- data/lib/smash_and_grab/map/tile.rb +6 -3
- data/lib/smash_and_grab/map/wall.rb +4 -2
- data/lib/smash_and_grab/mouse_selection.rb +103 -46
- data/lib/smash_and_grab/objects/entity.rb +219 -30
- data/lib/smash_and_grab/objects/static.rb +7 -5
- data/lib/smash_and_grab/objects/vehicle.rb +7 -5
- data/lib/smash_and_grab/objects/world_object.rb +13 -3
- data/lib/smash_and_grab/path.rb +13 -7
- data/lib/smash_and_grab/players/player.rb +15 -10
- data/lib/smash_and_grab/states/edit_level.rb +17 -0
- data/lib/smash_and_grab/states/play_level.rb +20 -10
- data/lib/smash_and_grab/version.rb +1 -1
- data/lib/smash_and_grab.rb +18 -14
- data/test/smash_and_grab/abilities/melee_test.rb +37 -39
- data/test/teststrap.rb +3 -3
- metadata +21 -16
@@ -0,0 +1,110 @@
|
|
1
|
+
module SmashAndGrab
|
2
|
+
module Gui
|
3
|
+
class EntityPanel < Fidgit::Horizontal
|
4
|
+
event :info_toggled
|
5
|
+
|
6
|
+
def initialize(entity, info_shown, options = {})
|
7
|
+
options = {
|
8
|
+
padding: 0,
|
9
|
+
spacing: 8,
|
10
|
+
}.merge! options
|
11
|
+
|
12
|
+
super options
|
13
|
+
|
14
|
+
@entity = entity
|
15
|
+
@info_shown = info_shown
|
16
|
+
|
17
|
+
vertical padding: 0 do
|
18
|
+
# TODO: Clicking on portrait should center.
|
19
|
+
@portrait = image_frame @entity.image, padding: 0, background_color: Color::GRAY
|
20
|
+
@info_toggle = toggle_button "Bio", value: @info_shown, tip: "Show/hide biography",
|
21
|
+
font_height: 14, align_h: :center do |_, value|
|
22
|
+
@info_shown = value
|
23
|
+
publish :info_toggled, value
|
24
|
+
switch_sub_panel
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
vertical padding: 0, spacing: 4 do
|
29
|
+
@name = label @entity.name
|
30
|
+
@sub_panel_container = vertical spacing: 0, padding: 0
|
31
|
+
end
|
32
|
+
|
33
|
+
create_details_sub_panel
|
34
|
+
create_info_sub_panel
|
35
|
+
switch_sub_panel
|
36
|
+
|
37
|
+
update_details @entity
|
38
|
+
|
39
|
+
@entity.subscribe :changed, method(:update_details)
|
40
|
+
end
|
41
|
+
|
42
|
+
def switch_sub_panel
|
43
|
+
@sub_panel_container.clear
|
44
|
+
@sub_panel_container.add @info_shown ? @info_sub_panel : @details_sub_panel
|
45
|
+
end
|
46
|
+
|
47
|
+
def create_info_sub_panel
|
48
|
+
@info_sub_panel = Fidgit::Vertical.new padding: 0, spacing: 0 do
|
49
|
+
text = nil
|
50
|
+
scroll = scroll_window width: 350, height: 72 do
|
51
|
+
text = text_area text: "#{@entity.name} once ate a pomegranate, but it took all day and all night... " * 5,
|
52
|
+
width: 330, font_height: 14, enabled: false
|
53
|
+
end
|
54
|
+
scroll.background_color = text.background_color
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def create_details_sub_panel
|
59
|
+
@details_sub_panel = Fidgit::Horizontal.new padding: 0, spacing: 0 do
|
60
|
+
vertical padding: 0, spacing: 1, width: 160 do
|
61
|
+
@health = label "", font_height: 20
|
62
|
+
@movement_points = label "", font_height: 20
|
63
|
+
@action_points = label "", font_height: 20
|
64
|
+
end
|
65
|
+
|
66
|
+
grid num_columns: 4, spacing: 4, padding: 0 do
|
67
|
+
button_options = { font_height: 20, width: 28, height: 28, padding: 0, padding_left: 8 }
|
68
|
+
|
69
|
+
@ability_buttons = {}
|
70
|
+
|
71
|
+
label_options = button_options.merge border_thickness: 2, border_color: Color.rgba(255, 255, 255, 100)
|
72
|
+
|
73
|
+
[:melee, :ranged, :sprint].each do |ability_name|
|
74
|
+
if @entity.has_ability? ability_name
|
75
|
+
ability = @entity.ability ability_name
|
76
|
+
@ability_buttons[ability_name] = button("#{ability_name.to_s[0].upcase}#{ability.skill}",
|
77
|
+
button_options.merge(tip: ability.tip)) do
|
78
|
+
|
79
|
+
@entity.use_ability :sprint if ability_name == :sprint
|
80
|
+
end
|
81
|
+
else
|
82
|
+
label "", label_options
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
5.times do |i|
|
87
|
+
label "", label_options
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def update_details(entity)
|
94
|
+
@health.text = "HP: #{entity.health} / #{entity.max_health}"
|
95
|
+
@movement_points.text = "MP: #{entity.mp} / #{entity.max_mp}"
|
96
|
+
@action_points.text = "AP: #{entity.ap} / #{entity.max_ap}"
|
97
|
+
|
98
|
+
if entity.has_ability? :sprint
|
99
|
+
@movement_points.text += " + #{entity.ability(:sprint).movement_bonus}"
|
100
|
+
end
|
101
|
+
|
102
|
+
@ability_buttons.each do |ability, button|
|
103
|
+
button.enabled = (entity.active? and (entity.has_ability?(ability) and entity.action_points >= entity.ability(ability).action_cost))
|
104
|
+
end
|
105
|
+
|
106
|
+
@portrait.image = entity.image
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -22,8 +22,8 @@ class EntitySummary < Fidgit::Vertical
|
|
22
22
|
|
23
23
|
vertical padding: 0, spacing: 0 do
|
24
24
|
@health = label "", font_height: 15
|
25
|
-
@movement_points = label "", font_height: 15
|
26
25
|
@action_points = label "", font_height: 15
|
26
|
+
@movement_points = label "", font_height: 15
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -31,10 +31,11 @@ class EntitySummary < Fidgit::Vertical
|
|
31
31
|
end
|
32
32
|
|
33
33
|
public
|
34
|
-
def
|
35
|
-
@health.text = "HP: #{
|
36
|
-
@movement_points.text = "MP: #{
|
37
|
-
@action_points.text = "AP: #{
|
34
|
+
def update_details(entity)
|
35
|
+
@health.text = "HP: #{entity.health}"
|
36
|
+
@movement_points.text = "MP: #{entity.mp}"
|
37
|
+
@action_points.text = "AP: #{entity.ap}"
|
38
|
+
@portrait.image = entity.portrait
|
38
39
|
end
|
39
40
|
|
40
41
|
public
|
@@ -46,10 +47,10 @@ class EntitySummary < Fidgit::Vertical
|
|
46
47
|
def entity=(entity)
|
47
48
|
@entity = entity
|
48
49
|
|
49
|
-
@name.text = " " + entity.name[0...13]
|
50
|
-
@
|
50
|
+
@name.text = " " + @entity.name[0...13]
|
51
|
+
@entity.subscribe :changed, &method(:update_details)
|
51
52
|
|
52
|
-
|
53
|
+
update_details @entity
|
53
54
|
|
54
55
|
entity
|
55
56
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module SmashAndGrab
|
2
|
+
module Gui
|
3
|
+
class GameLog < Fidgit::Composite
|
4
|
+
include Log
|
5
|
+
|
6
|
+
MAX_ITEMS = 100
|
7
|
+
|
8
|
+
def initialize(state, options = {})
|
9
|
+
options = {
|
10
|
+
padding: 0,
|
11
|
+
}.merge! options
|
12
|
+
|
13
|
+
super options
|
14
|
+
|
15
|
+
@items = []
|
16
|
+
|
17
|
+
@scroll_window = scroll_window width: 420, height: 72, padding: 0 do
|
18
|
+
# TODO: Text-area "editable(?)" seem broken. They don't prevent editing while also allowing copy/pasting.
|
19
|
+
@text = text_area width: 400, font_height: 14, enabled: false
|
20
|
+
end
|
21
|
+
|
22
|
+
@scroll_window.background_color = @text.background_color
|
23
|
+
|
24
|
+
state.subscribe :game_info do |_, text|
|
25
|
+
append text
|
26
|
+
log.info { "game_info: #{text}" }
|
27
|
+
end
|
28
|
+
|
29
|
+
state.subscribe :game_heading do |_, text|
|
30
|
+
append "<c=AAAADD> { #{text} }</c>"
|
31
|
+
log.info { "game_heading: #{text}" }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def append(text)
|
36
|
+
@items.shift until @items.size < MAX_ITEMS
|
37
|
+
@items << text
|
38
|
+
@text.text = @items.join "\n"
|
39
|
+
|
40
|
+
@scroll_window.offset_y = Float::INFINITY # Scroll to bottom.
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -1,105 +1,49 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
def initialize(options = {})
|
5
|
-
options = {
|
6
|
-
padding: 4,
|
7
|
-
background_color: Color::BLACK,
|
8
|
-
}.merge! options
|
9
|
-
super options
|
10
|
-
|
11
|
-
@frame = horizontal padding: 4, spacing: 8, background_color: Color.rgb(0, 0, 150), width: 440, height: 112 do
|
12
|
-
@portrait = image_frame Objects::Entity.sprites[0, 0], padding: 0, background_color: Color::GRAY
|
1
|
+
require_relative "entity_panel"
|
2
|
+
require_relative "object_panel"
|
3
|
+
require_relative "scenario_panel"
|
13
4
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
5
|
+
module SmashAndGrab
|
6
|
+
module Gui
|
7
|
+
# The info panel contains scenario/entity/object panels based what is selected.
|
8
|
+
class InfoPanel < Fidgit::Vertical
|
9
|
+
attr_reader :object
|
10
|
+
|
11
|
+
def initialize(state, options = {})
|
12
|
+
options = {
|
13
|
+
padding: 4,
|
14
|
+
background_color: Color::BLACK,
|
15
|
+
}.merge! options
|
16
|
+
super options
|
17
|
+
|
18
|
+
@object = nil
|
19
|
+
@show_info = false
|
20
|
+
@scenario_panel = ScenarioPanel.new state
|
21
|
+
@frame = vertical padding: 4, background_color: Color.rgb(0, 0, 150), width: 440, height: 112
|
22
|
+
|
23
|
+
self.x, self.y = ($window.width - width) / 2, $window.height - height
|
24
|
+
end
|
23
25
|
|
24
|
-
|
25
|
-
|
26
|
+
def object=(object)
|
27
|
+
return if @object == object
|
28
|
+
@scenario_panel.parent = nil
|
26
29
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
30
|
+
@frame.clear
|
31
|
+
case object
|
32
|
+
when Objects::Entity
|
33
|
+
panel = EntityPanel.new(object, @show_info, parent: @frame)
|
34
|
+
panel.subscribe :info_toggled do |_, shown|
|
35
|
+
@show_info = shown
|
32
36
|
end
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
@
|
37
|
-
|
38
|
-
|
39
|
-
@ability_buttons[:e] = button "P4", button_options.merge(tip: "power4")
|
40
|
-
end
|
37
|
+
when Objects::Static, Objects::Vehicle
|
38
|
+
ObjectPanel.new(object, parent: @frame)
|
39
|
+
when nil
|
40
|
+
@frame.add @scenario_panel
|
41
|
+
else
|
42
|
+
raise object.inspect
|
41
43
|
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
recalc
|
46
|
-
|
47
|
-
self.x, self.y = ($window.width - width) / 2, $window.height - height
|
48
|
-
end
|
49
|
-
|
50
|
-
public
|
51
|
-
def update
|
52
|
-
return unless @entity
|
53
|
-
|
54
|
-
@health.text = "HP: #{@entity.health} / #{@entity.max_health}"
|
55
|
-
@movement_points.text = "MP: #{@entity.mp} / #{@entity.max_mp}"
|
56
|
-
@action_points.text = "AP: #{@entity.ap} / #{@entity.max_ap}"
|
57
|
-
|
58
|
-
if @entity.has_ability? :sprint
|
59
|
-
@movement_points.text += " +#{@entity.ability(:sprint).movement_bonus}"
|
60
|
-
end
|
61
|
-
|
62
|
-
@ability_buttons.each do |ability, button|
|
63
|
-
button.enabled = (@entity.has_ability?(ability) and @entity.action_points >= @entity.ability(ability).action_cost)
|
64
|
-
end
|
65
|
-
end
|
66
44
|
|
67
|
-
|
68
|
-
def entity=(entity)
|
69
|
-
@entity = entity
|
70
|
-
|
71
|
-
@frame.shown = (not entity.nil?)
|
72
|
-
|
73
|
-
if entity
|
74
|
-
@portrait.image = @entity.image
|
75
|
-
@name.text = @entity.name
|
76
|
-
|
77
|
-
if @entity.has_ability? :melee
|
78
|
-
melee = @entity.ability(:melee)
|
79
|
-
@ability_buttons[:melee].tip = "Melee[#{melee.skill}] - attack in hand-to-hand combat"
|
80
|
-
else
|
81
|
-
@ability_buttons[:melee].tip = "Melee[n/a]"
|
45
|
+
@object = object
|
82
46
|
end
|
83
|
-
|
84
|
-
if @entity.has_ability? :ranged
|
85
|
-
ranged = @entity.ability(:ranged)
|
86
|
-
@ability_buttons[:ranged].tip = "Ranged[#{ranged.skill}] - attack in ranged combat"
|
87
|
-
else
|
88
|
-
@ability_buttons[:ranged].tip = "Ranged[n/a]"
|
89
|
-
end
|
90
|
-
|
91
|
-
if @entity.has_ability? :sprint
|
92
|
-
sprint = @entity.ability(:sprint)
|
93
|
-
@ability_buttons[:sprint].tip = "Sprint[#{sprint.skill}] - gain #{sprint.movement_bonus} movement points"
|
94
|
-
else
|
95
|
-
@ability_buttons[:sprint].tip = "Sprint[n/a]"
|
96
|
-
end
|
97
|
-
|
98
|
-
update
|
99
47
|
end
|
100
|
-
|
101
|
-
entity
|
102
48
|
end
|
103
49
|
end
|
104
|
-
end
|
105
|
-
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module SmashAndGrab
|
2
|
+
module Gui
|
3
|
+
class ObjectPanel < Fidgit::Horizontal
|
4
|
+
def initialize(object, options = {})
|
5
|
+
options = {
|
6
|
+
padding: 0,
|
7
|
+
spacing: 8,
|
8
|
+
}.merge! options
|
9
|
+
|
10
|
+
super options
|
11
|
+
|
12
|
+
@object = object
|
13
|
+
|
14
|
+
vertical padding: 0 do
|
15
|
+
# TODO: Clicking on portrait should center.
|
16
|
+
@portrait = image_frame @object.image, padding: 0, background_color: Color::GRAY,
|
17
|
+
factor: (@object.is_a?(Objects::Vehicle) ? 0.25 : 1)
|
18
|
+
|
19
|
+
@object.subscribe :changed do
|
20
|
+
@portrait.image = @object.image
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
vertical padding: 0, spacing: 4 do
|
25
|
+
@name = label @object.name
|
26
|
+
|
27
|
+
Fidgit::Vertical.new padding: 0, spacing: 0 do
|
28
|
+
scroll_window width: 350, height: 72 do
|
29
|
+
text_area text: "#{@object.name} once was a pomegranate, but it got better... " * 10,
|
30
|
+
background_color: Color::NONE, width: 330, font_height: 14
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative "game_log"
|
2
|
+
|
3
|
+
module SmashAndGrab
|
4
|
+
module Gui
|
5
|
+
class ScenarioPanel < Fidgit::Vertical
|
6
|
+
def initialize(state, options = {})
|
7
|
+
options = {
|
8
|
+
padding: 0,
|
9
|
+
spacing: 8,
|
10
|
+
}.merge! options
|
11
|
+
super options
|
12
|
+
|
13
|
+
label "Scenario: Bank raid"
|
14
|
+
|
15
|
+
horizontal padding_h: 4, padding_v: 0 do
|
16
|
+
@game_log = GameLog.new(state, parent: self)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/smash_and_grab/main.rb
CHANGED
@@ -11,13 +11,7 @@ def require_folder(path, files)
|
|
11
11
|
end
|
12
12
|
|
13
13
|
module SmashAndGrab
|
14
|
-
|
15
|
-
File.join(ENV['APPDATA'].gsub("\\", "/"), "Smash And Grab")
|
16
|
-
else
|
17
|
-
File.expand_path("~/.smash_and_grab")
|
18
|
-
end
|
19
|
-
|
20
|
-
SAVE_PATH = File.join(USER_PATH, "saves")
|
14
|
+
SAVE_PATH = File.join(USER_DATA_PATH, "saves")
|
21
15
|
end
|
22
16
|
|
23
17
|
require_relative "log"
|
@@ -26,13 +20,11 @@ SmashAndGrab::Log.log.info { "Smash and Grab loading; please wait.." }
|
|
26
20
|
t = Time.now
|
27
21
|
|
28
22
|
begin
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
begin
|
35
|
-
require 'bundler/setup' unless defined?(OSX_EXECUTABLE) or ENV['OCRA_EXECUTABLE']
|
23
|
+
# Running as an executable makes bundler irrelevant; from a gem means someone else decides about whether to use Bundler.
|
24
|
+
unless RUNNING_FROM_EXECUTABLE or Gem.loaded_specs.has_key? APP_NAME
|
25
|
+
require 'bundler'
|
26
|
+
Bundler.setup :default
|
27
|
+
end
|
36
28
|
|
37
29
|
rescue LoadError
|
38
30
|
$stderr.puts "Bundler gem not installed. To install:\n gem install bundler"
|
@@ -51,7 +43,7 @@ require 'chingu'
|
|
51
43
|
|
52
44
|
require 'fidgit'
|
53
45
|
Fidgit::Element.schema.merge_schema! YAML.load(File.read(File.expand_path('config/gui/schema.yml', EXTRACT_PATH)))
|
54
|
-
require_folder("fidgit_ext", %w[element container cursor])
|
46
|
+
require_folder("fidgit_ext", %w[event element container cursor])
|
55
47
|
|
56
48
|
require 'texplay'
|
57
49
|
require_folder('texplay_ext', %w[color image window])
|
@@ -76,9 +68,9 @@ require_folder "std_ext", %w[array hash]
|
|
76
68
|
|
77
69
|
# Include other files.
|
78
70
|
require_folder("", %w[version sprite_sheet z_order z_order_recorder game_window mouse_selection])
|
79
|
-
require_folder("gui", %w[minimap editor_selector entity_summary info_panel])
|
80
71
|
require_folder("map", %w[tile wall map])
|
81
72
|
require_folder("objects", %w[static entity vehicle])
|
73
|
+
require_folder("gui", %w[minimap editor_selector entity_summary info_panel])
|
82
74
|
require_folder("states", %w[edit_level play_level main_menu])
|
83
75
|
require_folder("players", %w[player])
|
84
76
|
require_folder("history", %w[editor_action_history game_action_history])
|
@@ -90,5 +82,8 @@ SmashAndGrab::GameWindow.new
|
|
90
82
|
SmashAndGrab::Log.log.debug { "Window created in #{"%.3f" % (Time.now - t)} s" }
|
91
83
|
|
92
84
|
unless defined? Ocra or defined? Bacon
|
85
|
+
SmashAndGrab::Log.log.info { "Game window opened" }
|
93
86
|
$window.show
|
87
|
+
|
88
|
+
SmashAndGrab::Log.log.info { "Game window closed" }
|
94
89
|
end
|
@@ -42,6 +42,7 @@ class Map
|
|
42
42
|
|
43
43
|
def add_effect(effect); @effects << effect; end
|
44
44
|
def remove_effect(effect); @effects.delete effect; end
|
45
|
+
def busy?; factions.any? {|f| f.entities.any?(&:busy?) }; end
|
45
46
|
|
46
47
|
# tile_classes: Nested arrays of Tile class names (Tile::Grass is represented as "Grass")
|
47
48
|
def initialize(data)
|
@@ -25,11 +25,14 @@ class Tile < GameObject
|
|
25
25
|
def position; [@x, @y]; end
|
26
26
|
def needs_to_be_seen?; (@temp_occlusions > 0) or @object; end # Causes walls to become transparent.
|
27
27
|
def blocks_sight?; @type == 'none' or (@object and @object.blocks_sight?); end
|
28
|
+
def zoc?(faction); entities_exerting_zoc(faction).any?; end
|
28
29
|
|
29
30
|
# Blank white tile, useful for colourising tiles.
|
30
|
-
|
31
|
-
|
32
|
-
|
31
|
+
class << self
|
32
|
+
def blank; @sprites[0]; end
|
33
|
+
def config; @config ||= YAML.load_file(File.expand_path("config/map/tiles.yml", EXTRACT_PATH)); end
|
34
|
+
def sprites; @sprites ||= SpriteSheet.new("floor_tiles.png", WIDTH, HEIGHT, 4); end
|
35
|
+
end
|
33
36
|
|
34
37
|
attr_reader :entities_exerting_zoc
|
35
38
|
|
@@ -32,8 +32,10 @@ class Wall < GameObject
|
|
32
32
|
|
33
33
|
def blocks_sight?; @blocks_sight; end
|
34
34
|
|
35
|
-
|
36
|
-
|
35
|
+
class << self
|
36
|
+
def config; @config ||= YAML.load_file(File.expand_path("config/map/walls.yml", EXTRACT_PATH)); end
|
37
|
+
def sprites; @sprites ||= SpriteSheet.new("walls.png", SPRITE_WIDTH, SPRITE_HEIGHT, 8); end
|
38
|
+
end
|
37
39
|
|
38
40
|
def initialize(map, data)
|
39
41
|
options = {
|