felflame 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/.byebug_history +20 -0
  3. data/.gitignore +17 -0
  4. data/.inch.yml +11 -0
  5. data/.rspec +1 -0
  6. data/.rubocop.yml +13 -0
  7. data/.yardopts +13 -0
  8. data/CHANGELOG.md +5 -0
  9. data/Gemfile +11 -0
  10. data/Gemfile.lock +87 -0
  11. data/LICENSE +21 -0
  12. data/LICENSE.txt +21 -0
  13. data/README.mdown +410 -0
  14. data/Rakefile +45 -0
  15. data/bin/console +15 -0
  16. data/bin/setup +8 -0
  17. data/codeclimate/export-coverage.rb +16 -0
  18. data/deprecated/components/00_renderable.rb +19 -0
  19. data/deprecated/components/01_sprite.rb +57 -0
  20. data/deprecated/components/02_label.rb +32 -0
  21. data/deprecated/components/03_player_control.rb +26 -0
  22. data/deprecated/components/04_map.rb +21 -0
  23. data/deprecated/components/05_interactable.rb +16 -0
  24. data/deprecated/components/06_collidable.rb +22 -0
  25. data/deprecated/components/07_battle.rb +4 -0
  26. data/deprecated/components/07_indoor.rb +4 -0
  27. data/deprecated/components/07_overworld.rb +16 -0
  28. data/deprecated/components/debug_singleton.rb +13 -0
  29. data/deprecated/helpers/00_tileset.rb +56 -0
  30. data/deprecated/helpers/01_component.rb +74 -0
  31. data/deprecated/systems/00_update_levels.rb +34 -0
  32. data/deprecated/systems/10_player.rb +41 -0
  33. data/deprecated/systems/99_render.rb +37 -0
  34. data/docs/CNAME +1 -0
  35. data/docs/FelFlame.html +317 -0
  36. data/docs/FelFlame/ComponentManager.html +1627 -0
  37. data/docs/FelFlame/Components.html +423 -0
  38. data/docs/FelFlame/Entities.html +1054 -0
  39. data/docs/FelFlame/Helper.html +142 -0
  40. data/docs/FelFlame/Helper/ComponentManager.html +1627 -0
  41. data/docs/FelFlame/Scenes.html +761 -0
  42. data/docs/FelFlame/Stage.html +598 -0
  43. data/docs/FelFlame/Systems.html +1541 -0
  44. data/docs/_index.html +173 -0
  45. data/docs/class_list.html +51 -0
  46. data/docs/css/common.css +1 -0
  47. data/docs/css/full_list.css +58 -0
  48. data/docs/css/style.css +497 -0
  49. data/docs/file.README.html +498 -0
  50. data/docs/file_list.html +56 -0
  51. data/docs/frames.html +17 -0
  52. data/docs/index.html +498 -0
  53. data/docs/js/app.js +314 -0
  54. data/docs/js/full_list.js +216 -0
  55. data/docs/js/jquery.js +4 -0
  56. data/docs/method_list.html +475 -0
  57. data/docs/top-level-namespace.html +137 -0
  58. data/felflame.gemspec +45 -0
  59. data/lib/felflame.rb +59 -0
  60. data/lib/felflame/component_manager.rb +245 -0
  61. data/lib/felflame/entity_manager.rb +135 -0
  62. data/lib/felflame/scene_manager.rb +58 -0
  63. data/lib/felflame/stage_manager.rb +70 -0
  64. data/lib/felflame/system_manager.rb +213 -0
  65. data/lib/felflame/version.rb +5 -0
  66. data/logos/felflame-logo-text.png +0 -0
  67. data/logos/felflame-logo-text.svg +172 -0
  68. data/logos/felflame-logo.png +0 -0
  69. data/logos/felflame-logo.svg +97 -0
  70. metadata +239 -0
@@ -0,0 +1,135 @@
1
+ class FelFlame
2
+ class Entities
3
+ # Holds the unique ID of this entity
4
+ # @return [Integer]
5
+ attr_reader :id
6
+
7
+ # A seperate attr_writer was made for documentation readability reasons.
8
+ # Yard will list attr_reader is readonly which is my intention.
9
+ # This value needs to be changable as it is set by other functions.
10
+ # @!visibility private
11
+ attr_writer :id
12
+
13
+ # Creating a new Entity
14
+ # @param components [Components] Can be any number of components, identical duplicates will be automatically purged however different components from the same component manager are allowed.
15
+ # @return [Entity]
16
+ def initialize(*components)
17
+ # Assign new unique ID
18
+ new_id = self.class.data.find_index(&:nil?)
19
+ new_id = self.class.data.size if new_id.nil?
20
+ self.id = new_id
21
+
22
+ # Add each component
23
+ add(*components)
24
+
25
+ self.class.data[id] = self
26
+ end
27
+
28
+ # A hash that uses component manager constant names as keys, and where the values of those keys are arrays that contain the {FelFlame::ComponentManager#id IDs} of the components attached to this entity.
29
+ # @return [Hash<Component_Manager, Array<Integer>>]
30
+ def components
31
+ @components ||= {}
32
+ end
33
+
34
+ # An alias for the {#id ID reader}
35
+ # @return [Integer]
36
+ def to_i
37
+ id
38
+ end
39
+
40
+ # Removes this Entity from the list and purges all references to this Entity from other Components, as well as its {id ID} and data.
41
+ # @return [Boolean] +true+
42
+ def delete
43
+ components.each do |component_manager, component_array|
44
+ component_array.each do |component_id|
45
+ component_manager[component_id].entities.delete(id)
46
+ #self.remove FelFlame::Components.const_get(component_manager.name)[component_id]
47
+ end
48
+ end
49
+ FelFlame::Entities.data[id] = nil
50
+ @components = {}
51
+ @id = nil
52
+ true
53
+ end
54
+
55
+ # Add any number components to the Entity.
56
+ # @param components_to_add [Component] Any number of components created from any component manager
57
+ # @return [Boolean] +true+
58
+ def add(*components_to_add)
59
+ components_to_add.each do |component|
60
+ if components[component.class].nil?
61
+ components[component.class] = [component.id]
62
+ component.entities.push id
63
+ check_systems component, :addition_triggers
64
+ elsif !components[component.class].include? component.id
65
+ components[component.class].push component.id
66
+ component.entities.push id
67
+ check_systems component, :addition_triggers
68
+ end
69
+ end
70
+ true
71
+ end
72
+
73
+ # triggers every system associated with this component's trigger
74
+ # @return [Boolean] +true+
75
+ # @!visibility private
76
+ def check_systems(component, trigger_type)
77
+ component_calls = component.class.send(trigger_type)
78
+ component.send(trigger_type).each do |system|
79
+ component_calls |= [system]
80
+ end
81
+ component_calls.sort_by(&:priority).reverse.each(&:call)
82
+ true
83
+ end
84
+
85
+ # Remove a component from the Entity
86
+ # @param components_to_remove [Component] A component created from any component manager
87
+ # @return [Boolean] +true+
88
+ def remove(*components_to_remove)
89
+ components_to_remove.each do |component|
90
+ check_systems component, :removal_triggers if component.entities.include? id
91
+ component.entities.delete id
92
+ components[component.class].delete component.id
93
+ end
94
+ true
95
+ end
96
+
97
+ # Export all data into a JSON String which can then be saved into a file
98
+ # TODO: This function is not yet complete
99
+ # @return [String] A JSON formatted String
100
+ #def to_json() end
101
+
102
+ class <<self
103
+ include Enumerable
104
+ # @return [Array<Entity>] Array of all Entities that exist
105
+ # @!visibility private
106
+ def data
107
+ @data ||= []
108
+ end
109
+
110
+ # Gets an Entity from the given {id unique ID}. Usage is simular to how an Array lookup works
111
+ #
112
+ # @example
113
+ # # This gets the Entity with ID 7
114
+ # FelFlame::Entities[7]
115
+ # @param entity_id [Integer]
116
+ # @return [Entity] returns the Entity that uses the given unique ID, nil if there is no Entity associated with the given ID
117
+ def [](entity_id)
118
+ data[entity_id]
119
+ end
120
+
121
+ # Iterates over all entities. The data is compacted so that means index does not correlate to ID.
122
+ # You also call other enumerable methods instead of each, such as +each_with_index+ or +select+
123
+ # @return [Enumerator]
124
+ def each(&block)
125
+ data.compact.each(&block)
126
+ end
127
+
128
+ # Creates a new entity using the data from a JSON string
129
+ # TODO: This function is not yet complete
130
+ # @param json_string [String] A string that was exported originally using the {FelFlame::Entities#to_json to_json} function
131
+ # @param opts [Keywords] What values(its {FelFlame::Entities#id ID} or the {FelFlame::ComponentManager#id component IDs}) should be overwritten TODO: this might change
132
+ #def from_json(json_string, **opts) end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,58 @@
1
+ class FelFlame
2
+ class Scenes
3
+ # The Constant name assigned to this Scene
4
+ attr_reader :const_name
5
+
6
+ # Allows overwriting the storage of systems, such as for clearing.
7
+ # This method should generally only need to be used internally and
8
+ # not by a game developer/
9
+ # @!visibility private
10
+ attr_writer :systems
11
+
12
+ # Create a new Scene using the name given
13
+ # @param name [String] String format must follow requirements of a constant
14
+ def initialize(name)
15
+ FelFlame::Scenes.const_set(name, self)
16
+ @const_name = name
17
+ end
18
+
19
+ # The list of Systems this Scene contains
20
+ # @return [Array<System>]
21
+ def systems
22
+ @systems ||= []
23
+ end
24
+
25
+ # Execute all systems in this Scene, in the order of their priority
26
+ # @return [Boolean] +true+
27
+ def call
28
+ systems.each(&:call)
29
+ true
30
+ end
31
+
32
+ # Adds any number of Systems to this Scene
33
+ # @return [Boolean] +true+
34
+ def add(*systems_to_add)
35
+ self.systems |= systems_to_add
36
+ systems.sort_by!(&:priority)
37
+ FelFlame::Stage.update_systems_list if FelFlame::Stage.scenes.include? self
38
+ true
39
+ end
40
+
41
+ # Removes any number of SystemS from this Scene
42
+ # @return [Boolean] +true+
43
+ def remove(*systems_to_remove)
44
+ self.systems -= systems_to_remove
45
+ systems.sort_by!(&:priority)
46
+ FelFlame::Stage.update_systems_list if FelFlame::Stage.scenes.include? self
47
+ true
48
+ end
49
+
50
+ # Removes all Systems from this Scene
51
+ # @return [Boolean] +true+
52
+ def clear
53
+ systems.clear
54
+ FelFlame::Stage.update_systems_list if FelFlame::Stage.scenes.include? self
55
+ true
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,70 @@
1
+ class FelFlame
2
+ class Stage
3
+ class <<self
4
+ # Allows clearing of scenes and systems.
5
+ # Used internally by FelFlame and shouldn't need to be ever used by developers
6
+ # @!visibility private
7
+ attr_writer :scenes, :systems
8
+
9
+ # Add any number of Scenes to the Stage
10
+ # @return [Boolean] +true+
11
+ def add(*scenes_to_add)
12
+ self.scenes |= scenes_to_add
13
+ scenes_to_add.each do |scene|
14
+ self.systems |= scene.systems
15
+ end
16
+ systems.sort_by!(&:priority)
17
+ true
18
+ end
19
+
20
+ # Remove any number of Scenes from the Stage
21
+ # @return [Boolean] +true+
22
+ def remove(*scenes_to_remove)
23
+ self.scenes -= scenes_to_remove
24
+ update_systems_list
25
+ true
26
+ end
27
+
28
+ # Updates the list of systems from the Scenes added to the Stage and make sure they are ordered correctly
29
+ # This is used internally by FelFlame and shouldn't need to be ever used by developers
30
+ # @return [Boolean] +true+
31
+ # @!visibility private
32
+ def update_systems_list
33
+ systems.clear
34
+ scenes.each do |scene|
35
+ self.systems |= scene.systems
36
+ end
37
+ systems.sort_by!(&:priority)
38
+ true
39
+ end
40
+
41
+ # Clears all Scenes that were added to the Stage
42
+ # @return [Boolean] +true+
43
+ def clear
44
+ systems.clear
45
+ scenes.clear
46
+ true
47
+ end
48
+
49
+ # Executes one frame of the game. This executes all the Systems in the Scenes added to the Stage. Systems that exist in two or more different Scenes will still only get executed once.
50
+ # @return [Boolean] +true+
51
+ def call
52
+ systems.each(&:call)
53
+ true
54
+ end
55
+
56
+ # Contains all the Scenes added to the Stage
57
+ # @return [Array<Scene>]
58
+ def scenes
59
+ @scenes ||= []
60
+ end
61
+
62
+ # Stores systems in the order the stage manager needs to call them
63
+ # This method should generally only need to be used internally and not by a game developer
64
+ # @!visibility private
65
+ def systems
66
+ @systems ||= []
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,213 @@
1
+ class FelFlame
2
+ class Systems
3
+ # How early this System should be executed in a list of Systems
4
+ attr_accessor :priority
5
+
6
+ # The Constant name assigned to this System
7
+ attr_reader :const_name
8
+
9
+ # Allows overwriting the storage of triggers, such as for clearing.
10
+ # This method should generally only need to be used internally and
11
+ # not by a game developer.
12
+ # @!visibility private
13
+ attr_writer :addition_triggers, :removal_triggers, :attr_triggers
14
+
15
+ def priority=(priority)
16
+ @priority = priority
17
+ FelFlame::Stage.systems.sort_by!(&:priority)
18
+ end
19
+ # Stores references to components or their managers that trigger
20
+ # this component when a component or component from that manager
21
+ # is added to an entity.
22
+ # Do not edit this hash as it is managed by FelFlame automatically.
23
+ # @return [Array<Component>]
24
+ def addition_triggers
25
+ @addition_triggers ||= []
26
+ end
27
+
28
+ # Stores references to components or their managers that trigger
29
+ # this component when a component or component from that manager
30
+ # is removed from an entity.
31
+ # Do not edit this hash as it is managed by FelFlame automatically.
32
+ # @return [Array<Component>]
33
+ def removal_triggers
34
+ @removal_triggers ||= []
35
+ end
36
+
37
+
38
+ # Stores references to systems that should be triggered when an
39
+ # attribute from this manager is changed
40
+ # Do not edit this hash as it is managed by FelFlame automatically.
41
+ # @return [Hash<Symbol, Array<Symbol>>]
42
+ def attr_triggers
43
+ @attr_triggers ||= {}
44
+ end
45
+
46
+ class <<self
47
+ include Enumerable
48
+
49
+ # Iterate over all Systems, sorted by their priority. You also call other enumerable methods instead of each, such as +each_with_index+ or +select+
50
+ # @return [Enumerator]
51
+ def each(&block)
52
+ constants.map { |sym| const_get(sym) }.sort_by(&:priority).reverse.each(&block)
53
+ end
54
+ end
55
+
56
+ # Creates a new System which can be accessed as a constant under the namespace {FelFlame::Systems}.
57
+ # The name given is what constant the system is assigned to
58
+ #
59
+ # @example
60
+ # FelFlame::Systems.new('PassiveHeal', priority: -2) do
61
+ # FelFlame::Components::Health.each do |component|
62
+ # component.hp += 5
63
+ # end
64
+ # end
65
+ # # Give it a low priority so other systems such as a
66
+ # # Poison system would kill the player first
67
+ #
68
+ # @param name [String] The name this system will use. Needs to to be in the Ruby Constant format.
69
+ # @param priority [Integer] Which priority order this system should be executed in relative to other systems. Higher means executed earlier.
70
+ # @param block [Proc] The code you wish to be executed when the system is triggered. Can be defined by using a +do end+ block or using +{ }+ braces.
71
+ def initialize(name, priority: 0, &block)
72
+ FelFlame::Systems.const_set(name, self)
73
+ @const_name = name
74
+ @priority = priority
75
+ @block = block
76
+ end
77
+
78
+ # Manually execute the system a single time
79
+ def call
80
+ @block.call
81
+ end
82
+ # Redefine what code is executed by this System when it is called upon.
83
+ # @param block [Proc] The code you wish to be executed when the system is triggered. Can be defined by using a +do end+ block or using +{ }+ braces.
84
+ def redefine(&block)
85
+ @block = block
86
+ end
87
+
88
+ # Removes triggers from this system. This function is fairly flexible so it can accept a few different inputs
89
+ # For addition and removal triggers, you can optionally pass in a component, or a manager to clear specifically
90
+ # the relevant triggers for that one component or manager. If you do not pass a component or manager then it will
91
+ # clear triggers for all components and managers.
92
+ # For attr_triggers
93
+ # @example
94
+ # # To clear all triggers that execute this system when a component is added:
95
+ # FelFlame::Systems::ExampleSystem.clear_triggers :addition_triggers
96
+ # # Same as above but for when a component is removed instead
97
+ # FelFlame::Systems::ExampleSystem.clear_triggers :removal_triggers
98
+ # # Same as above but for when a component has a certain attribute changed
99
+ # FelFlame::Systems::ExampleSystem.clear_triggers :attr_triggers
100
+ #
101
+ # # Clear a trigger from a specific component
102
+ # FelFlame::Systems::ExampleSystem.clear_triggers :addition_triggers, FelFlame::Component::ExampleComponent[0]
103
+ # # Clear a trigger from a specific component manager
104
+ # FelFlame::Systems::ExampleSystem.clear_triggers :addition_triggers, FelFlame::Component::ExampleComponent
105
+ #
106
+ # # Clear the trigger that executes a system when the ':example_attr' is changes
107
+ # FelFlame::Systems::ExampleSystem.clear_triggers :attr_triggers, :example_attr
108
+ # @param trigger_types [:Symbols] One or more of the following trigger types: +:addition_triggers+, +:removal_triggers+, or +:attr_triggers+. If attr_triggers is used then you may pass attributes you wish to be cleared as symbols in this parameter as well
109
+ # @param component_or_manager [Component or ComponentManager] The object to clear triggers from. Use Nil to clear triggers from all components associated with this system.
110
+ # @return [Boolean] +true+
111
+ def clear_triggers(*trigger_types, component_or_manager: nil)
112
+ trigger_types = [:addition_triggers, :removal_triggers, :attr_triggers] if trigger_types.empty?
113
+
114
+ if trigger_types.include? :attr_triggers
115
+ if (trigger_types - [:addition_triggers,
116
+ :removal_triggers,
117
+ :attr_triggers]).empty?
118
+
119
+ if component_or_manager.nil?
120
+ #remove all attrs
121
+ self.attr_triggers.each do |cmp_or_mgr, attrs|
122
+ attrs.each do |attr|
123
+ next if cmp_or_mgr.attr_triggers[attr].nil?
124
+
125
+ cmp_or_mgr.attr_triggers[attr].delete self
126
+ end
127
+ self.attr_triggers = {}
128
+ end
129
+ else
130
+ #remove attrs relevant to comp_or_man
131
+ unless self.attr_triggers[component_or_manager].nil?
132
+ self.attr_triggers[component_or_manager].each do |attr|
133
+ component_or_manager.attr_triggers[attr].delete self
134
+ end
135
+ self.attr_triggers[component_or_manager] = []
136
+ end
137
+ end
138
+
139
+ else
140
+
141
+ if component_or_manager.nil?
142
+ (trigger_types - [:addition_triggers, :removal_triggers, :attr_triggers]).each do |attr|
143
+ #remove attr
144
+ self.attr_triggers.each do |cmp_or_mgr, attrs|
145
+ cmp_or_mgr.attr_triggers[attr].delete self
146
+ end
147
+ end
148
+ self.attr_triggers.delete (trigger_types - [:addition_triggers,
149
+ :removal_triggers,
150
+ :attr_triggers])
151
+ else
152
+ #remove attr from component_or_manager
153
+ (trigger_types - [:addition_triggers, :removal_triggers, :attr_triggers]).each do |attr|
154
+ next if component_or_manager.attr_triggers[attr].nil?
155
+ component_or_manager.attr_triggers[attr].delete self
156
+ end
157
+ self.attr_triggers[component_or_manager] -= trigger_types unless self.attr_triggers[component_or_manager].nil?
158
+ end
159
+
160
+ end
161
+ end
162
+
163
+ (trigger_types & [:removal_triggers, :addition_triggers] - [:attr_triggers]).each do |trigger_type|
164
+ if component_or_manager.nil?
165
+ #remove all removal triggers
166
+ self.send(trigger_type).each do |trigger|
167
+ trigger.send(trigger_type).delete self
168
+ end
169
+ self.send("#{trigger_type.to_s}=", [])
170
+ else
171
+ #remove removal trigger relevant to comp/man
172
+ self.send(trigger_type).delete component_or_manager
173
+ component_or_manager.send(trigger_type).delete self
174
+ end
175
+ end
176
+ true
177
+ end
178
+
179
+ # Add a component or component manager so that it triggers this system when the component or a component from the component manager is added to an entity
180
+ # @param component_or_manager [Component or ComponentManager] The component or component manager to trigger this system when added
181
+ # @return [Boolean] +true+
182
+ def trigger_when_added(component_or_manager)
183
+ self.addition_triggers |= [component_or_manager]
184
+ component_or_manager.addition_triggers |= [self]
185
+ true
186
+ end
187
+
188
+ # Add a component or component manager so that it triggers this system when the component or a component from the component manager is removed from an entity
189
+ # @param component_or_manager [Component or ComponentManager] The component or component manager to trigger this system when removed
190
+ # @return [Boolean] +true+
191
+ def trigger_when_removed(component_or_manager)
192
+ self.removal_triggers |= [component_or_manager]
193
+ component_or_manager.removal_triggers |= [self]
194
+ true
195
+ end
196
+
197
+ # Add a component or component manager so that it triggers this system when a component's attribute is changed.
198
+ # @return [Boolean] +true+
199
+ def trigger_when_is_changed(component_or_manager, attr)
200
+ if component_or_manager.attr_triggers[attr].nil?
201
+ component_or_manager.attr_triggers[attr] = [self]
202
+ else
203
+ component_or_manager.attr_triggers[attr] |= [self]
204
+ end
205
+ if self.attr_triggers[component_or_manager].nil?
206
+ self.attr_triggers[component_or_manager] = [attr]
207
+ else
208
+ self.attr_triggers[component_or_manager] |= [attr]
209
+ end
210
+ true
211
+ end
212
+ end
213
+ end