jemini 2009.10.27

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.
Files changed (127) hide show
  1. data/README.txt +9 -0
  2. data/bin/jemini +26 -0
  3. data/lib/ibxm.jar +0 -0
  4. data/lib/jinput.jar +0 -0
  5. data/lib/jogg-0.0.7.jar +0 -0
  6. data/lib/jorbis-0.0.15.jar +0 -0
  7. data/lib/jruby-complete.jar +0 -0
  8. data/lib/lwjgl.jar +0 -0
  9. data/lib/lwjgl_util_applet.jar +0 -0
  10. data/lib/native_files/OpenAL32.dll +0 -0
  11. data/lib/native_files/jinput-dx8.dll +0 -0
  12. data/lib/native_files/jinput-dx8_64.dll +0 -0
  13. data/lib/native_files/jinput-raw.dll +0 -0
  14. data/lib/native_files/jinput-raw_64.dll +0 -0
  15. data/lib/native_files/jinput-wintab.dll +0 -0
  16. data/lib/native_files/libjinput-linux.so +0 -0
  17. data/lib/native_files/libjinput-linux64.so +0 -0
  18. data/lib/native_files/libjinput-osx.jnilib +0 -0
  19. data/lib/native_files/liblwjgl.jnilib +0 -0
  20. data/lib/native_files/liblwjgl.so +0 -0
  21. data/lib/native_files/liblwjgl64.so +0 -0
  22. data/lib/native_files/libopenal.so +0 -0
  23. data/lib/native_files/lwjgl.dll +0 -0
  24. data/lib/native_files/openal.dylib +0 -0
  25. data/lib/natives-linux.jar +0 -0
  26. data/lib/natives-mac.jar +0 -0
  27. data/lib/natives-win32.jar +0 -0
  28. data/lib/phys2d.jar +0 -0
  29. data/lib/slick.jar +0 -0
  30. data/package/jar/jemini.jar +0 -0
  31. data/src/behavior.rb +248 -0
  32. data/src/behavior_event.rb +23 -0
  33. data/src/behaviors/animated_image.rb +88 -0
  34. data/src/behaviors/audible.rb +16 -0
  35. data/src/behaviors/axis_stateful.rb +35 -0
  36. data/src/behaviors/bounding_box_collidable.rb +27 -0
  37. data/src/behaviors/cardinal_movable.rb +121 -0
  38. data/src/behaviors/clickable.rb +19 -0
  39. data/src/behaviors/countable.rb +32 -0
  40. data/src/behaviors/debug_physical.rb +43 -0
  41. data/src/behaviors/debug_tangible.rb +31 -0
  42. data/src/behaviors/drawable.rb +7 -0
  43. data/src/behaviors/drawable_image.rb +111 -0
  44. data/src/behaviors/drawable_line.rb +32 -0
  45. data/src/behaviors/drawable_shape.rb +48 -0
  46. data/src/behaviors/fading_image_trail_emittable.rb +32 -0
  47. data/src/behaviors/game_object_emittable.rb +13 -0
  48. data/src/behaviors/grid_bound.rb +108 -0
  49. data/src/behaviors/handles_events.rb +33 -0
  50. data/src/behaviors/inertial.rb +14 -0
  51. data/src/behaviors/magnetic.rb +34 -0
  52. data/src/behaviors/metered.rb +3 -0
  53. data/src/behaviors/movable.rb +81 -0
  54. data/src/behaviors/particle_emitter.rb +27 -0
  55. data/src/behaviors/physical.rb +384 -0
  56. data/src/behaviors/physical_cardinal_movable.rb +111 -0
  57. data/src/behaviors/physical_image.rb +45 -0
  58. data/src/behaviors/pointer.rb +30 -0
  59. data/src/behaviors/pressable.rb +17 -0
  60. data/src/behaviors/regional.rb +76 -0
  61. data/src/behaviors/rotates_to_point.rb +19 -0
  62. data/src/behaviors/spatial.rb +43 -0
  63. data/src/behaviors/stateful.rb +33 -0
  64. data/src/behaviors/taggable.rb +28 -0
  65. data/src/behaviors/tangible.rb +59 -0
  66. data/src/behaviors/timeable.rb +88 -0
  67. data/src/behaviors/top_down_vehicle.rb +42 -0
  68. data/src/behaviors/triangle_trail_emittable.rb +46 -0
  69. data/src/behaviors/unique.rb +0 -0
  70. data/src/behaviors/updates.rb +8 -0
  71. data/src/behaviors/updates_at_consistant_rate.rb +28 -0
  72. data/src/behaviors/vectored_movement.rb +48 -0
  73. data/src/behaviors/world_collidable.rb +9 -0
  74. data/src/color.rb +70 -0
  75. data/src/events/grid_changed_event.rb +8 -0
  76. data/src/events/physical_message.rb +9 -0
  77. data/src/events/tangible_collision_event.rb +8 -0
  78. data/src/file_system.rb +17 -0
  79. data/src/game.rb +110 -0
  80. data/src/game_object.rb +176 -0
  81. data/src/game_objects/background.rb +10 -0
  82. data/src/game_objects/fading_image.rb +23 -0
  83. data/src/game_objects/tangible_object.rb +4 -0
  84. data/src/game_objects/text.rb +71 -0
  85. data/src/game_objects/triangle_trail.rb +85 -0
  86. data/src/game_state.rb +164 -0
  87. data/src/inflector.rb +68 -0
  88. data/src/input_helpers/joystick_dead_zone_filter.rb +9 -0
  89. data/src/jemini.rb +31 -0
  90. data/src/jemini_version.rb +4 -0
  91. data/src/listenable_mixin.rb +15 -0
  92. data/src/logger_mixin.rb +11 -0
  93. data/src/managers/basic_game_object_manager.rb +95 -0
  94. data/src/managers/basic_physics_manager.rb +95 -0
  95. data/src/managers/basic_render_manager.rb +49 -0
  96. data/src/managers/basic_tile_manager.rb +3 -0
  97. data/src/managers/basic_update_manager.rb +30 -0
  98. data/src/managers/diagnostic/diagnostic_input_manager.rb +0 -0
  99. data/src/managers/input_manager.rb +161 -0
  100. data/src/managers/input_support/input_binding.rb +77 -0
  101. data/src/managers/input_support/input_builder.rb +44 -0
  102. data/src/managers/input_support/input_listener.rb +74 -0
  103. data/src/managers/input_support/input_message.rb +5 -0
  104. data/src/managers/input_support/joystick_listener.rb +53 -0
  105. data/src/managers/input_support/key_listener.rb +27 -0
  106. data/src/managers/input_support/mouse_listener.rb +38 -0
  107. data/src/managers/input_support/slick_input_listener.rb +20 -0
  108. data/src/managers/input_support/slick_input_message.rb +11 -0
  109. data/src/managers/input_support/slick_input_translator.rb +15 -0
  110. data/src/managers/message_queue.rb +60 -0
  111. data/src/managers/network_manager.rb +41 -0
  112. data/src/managers/render_support/hardware_cursor.rb +13 -0
  113. data/src/managers/resource_manager.rb +167 -0
  114. data/src/managers/sound_manager.rb +47 -0
  115. data/src/managers/tag_manager.rb +47 -0
  116. data/src/managers/tangible_manager.rb +36 -0
  117. data/src/math.rb +23 -0
  118. data/src/org/rubyforge/rawr/Main.java +67 -0
  119. data/src/platform.rb +28 -0
  120. data/src/proc_enhancement.rb +5 -0
  121. data/src/project_generator.rb +138 -0
  122. data/src/resource.rb +31 -0
  123. data/src/spline.rb +13 -0
  124. data/src/states/input_diagnostic_state.rb +53 -0
  125. data/src/vector.rb +143 -0
  126. data/test/test_state.rb +3 -0
  127. metadata +188 -0
@@ -0,0 +1,176 @@
1
+ require 'behavior'
2
+ require 'listenable_mixin'
3
+ require 'logger_mixin'
4
+
5
+ module Jemini
6
+ class GameObject
7
+ include ListenableMixin
8
+ include LoggerMixin
9
+ attr_reader :game_state
10
+
11
+ @@declared_behaviors = Hash.new{|h,k| h[k] = []}
12
+ def self.has_behavior(behavior)
13
+ require "behaviors/#{behavior.underscore}"
14
+ @@declared_behaviors[self] << behavior
15
+ end
16
+
17
+ def initialize(state, *args)
18
+ @game_state = state
19
+ @callbacks = Hash.new {|h,k| h[k] = []}
20
+ @__behaviors = {}
21
+ enable_listeners_for :before_remove, :after_remove
22
+ declared_behaviors.each do |behavior|
23
+ add_behavior(behavior)
24
+ end
25
+ validate_dependant_behaviors
26
+ load(*args)
27
+ end
28
+
29
+ def has_behavior?(behavior_name)
30
+ @__behaviors.has_key? behavior_name
31
+ end
32
+
33
+ def add_behavior(behavior_name)
34
+ klass = nil
35
+ retried = false
36
+ begin
37
+ klass = behavior_name.camelize.constantize
38
+ rescue NameError
39
+ raise if retried
40
+ require "behaviors/#{behavior_name.underscore}"
41
+ retried = true
42
+ retry
43
+ end
44
+ @__behaviors[behavior_name] = klass.new(self) if @__behaviors[behavior_name].nil?
45
+ validate_dependant_behaviors
46
+ rescue NameError => e
47
+ raise "Unable to load behavior #{behavior_name}, #{e.message}\n#{e.backtrace.join("\n")}"
48
+ end
49
+
50
+ def __destroy
51
+ notify :before_remove, self
52
+ #TODO: Perhaps expose this as a method on Behavior
53
+ #Jemini::Behavior.send(:class_variable_get, :@@depended_on_by).delete self
54
+ __remove_listeners
55
+ @__behaviors.each do |name, behavior|
56
+ #the list is being modified as we go through it, so check before use.
57
+ next if behavior.nil?
58
+ behavior.send(:delete)
59
+ end
60
+ notify :after_remove, self
61
+ end
62
+
63
+ def unload; end
64
+
65
+ def remove_behavior(behavior)
66
+ @__behaviors.delete(behavior).send(:delete) unless @__behaviors[behavior].nil?
67
+ end
68
+
69
+ # Takes a method and adds a corresponding listener registration method. Given
70
+ # the method foo, enable_listeners_for would generate the method on_foo and when
71
+ # notify was called with an event name of :foo, all callback blocks registered
72
+ # with the on_foo method would be called.
73
+ def enable_listeners_for(*methods)
74
+ methods.each do |method|
75
+ code = <<-ENDL
76
+ def on_#{method}(callback_method_name = nil, &callback)
77
+ register_listener(:#{method} , callback_method_name, callback)
78
+ end
79
+
80
+ def remove_#{method}(object, callback_or_callback_method=nil)
81
+ remove_registered_listener(:#{method}, object, callback_or_callback_method)
82
+ end
83
+ ENDL
84
+
85
+ self.instance_eval code, __FILE__, __LINE__
86
+ end
87
+ end
88
+
89
+ def register_listener(listener_method_name, callback_method_name, callback)
90
+ if callback_method_name
91
+ __added_listener_for(self, listener_method_name, callback_method_name)
92
+ @callbacks[listener_method_name] << callback_method_name
93
+ else
94
+ origin = callback.source
95
+ origin.extend Jemini::ListenableMixin unless origin.kind_of? Jemini::ListenableMixin
96
+ origin.__added_listener_for(self, "#{listener_method_name}", callback)
97
+ @callbacks[listener_method_name] << callback
98
+ end
99
+ end
100
+
101
+ def remove_registered_listener(listener_method_name, object, callback_or_callback_method)
102
+ if callback_or_callback_method.nil? || callback_or_callback_method.kind_of?(Symbol)
103
+ @callbacks[listener_method_name].delete callback_or_callback_method
104
+ else
105
+ @callbacks[listener_method_name].delete_if {|callback| callback.source == object unless callback.kind_of?(Symbol) }
106
+ end
107
+ end
108
+
109
+ def notify(event_name, event = nil, callback_status = nil)
110
+ @callbacks[event_name.to_sym].each do |callback|
111
+ if event
112
+ if callback_status
113
+ if callback.kind_of? Symbol
114
+ send(callback, event, callback_status)
115
+ else
116
+ callback.call(event, callback_status)
117
+ end
118
+ break unless callback_status.nil? or callback_status.continue?
119
+ else
120
+ if callback.kind_of? Symbol
121
+ send(callback, event)
122
+ else
123
+ callback.call(event)
124
+ end
125
+ end
126
+ else
127
+ if callback.kind_of? Symbol
128
+ send(callback)
129
+ else
130
+ callback.call
131
+ end
132
+ end
133
+ end
134
+ end
135
+
136
+ def listen_for(message, game_object=self, &block)
137
+ game_object.send("on_#{message}", &block)
138
+ end
139
+
140
+ # def kind_of?(klass)
141
+ # super || @__behaviors.values.inject(false){|result, behavior| result || behavior.class == klass}
142
+ # end
143
+ # alias_method :is_a?, :kind_of?
144
+
145
+ def load(*args)
146
+ args.each do |behavior_name|
147
+ add_behavior behavior_name
148
+ end
149
+ end
150
+
151
+ private
152
+ def behavior_event_alias(behavior_class, aliases, &block)
153
+ if behavior = @__behaviors[behavior_class]
154
+ behavior.set_event_aliases(aliases, block)
155
+ else
156
+ raise "No behavior #{behavior_class} for game object #{self}"
157
+ end
158
+ end
159
+
160
+ def validate_dependant_behaviors
161
+ declared_behaviors.each do |behavior|
162
+ behavior.constantize.kind_of_dependencies.each do |dependant_behavior|
163
+ dependency = dependant_behavior.constantize
164
+ #TODO: This code cannot work until the game object has a list of behavior objects (behaviors returns names)
165
+ #next if behaviors.find {|behavior| p behavior; behavior.last.kind_of?(dependency)}
166
+ next
167
+ raise "Dependant behavior '#{dependant_behavior}' was not found on class #{self.class}"
168
+ end
169
+ end
170
+ end
171
+
172
+ def declared_behaviors
173
+ @@declared_behaviors[self.class]
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,10 @@
1
+ class Background < Jemini::GameObject
2
+ has_behavior :DrawableImage
3
+
4
+ #Takes a reference to an image loaded via ResourceManager.
5
+ def load(image)
6
+ set_image image
7
+ set_position Vector.new(game_state.screen_width, game_state.screen_height).half
8
+ end
9
+ end
10
+
@@ -0,0 +1,23 @@
1
+ class FadingImage < Jemini::GameObject
2
+ has_behavior :DrawableImage
3
+ has_behavior :Spatial
4
+ has_behavior :Timeable
5
+
6
+ def load(image, color, seconds_to_fade_away)
7
+ self.image = image
8
+ self.color = color
9
+ add_countdown :fade_timer, seconds_to_fade_away, 1.0 / 30.0
10
+
11
+ on_countdown_complete do
12
+ game_state.remove self
13
+ end
14
+
15
+ on_timer_tick do |timer|
16
+ fade(timer.percent_complete)
17
+ end
18
+ end
19
+
20
+ def fade(percent)
21
+ color.transparency = percent
22
+ end
23
+ end
@@ -0,0 +1,4 @@
1
+ #TODO: Remove this game object once we can detect when behaviors have been added to game objects
2
+ class TangibleObject < Jemini::GameObject
3
+ has_behavior :Tangible
4
+ end
@@ -0,0 +1,71 @@
1
+ require 'behaviors/drawable'
2
+
3
+ class Text < Jemini::GameObject
4
+ include_class "org.newdawn.slick.TrueTypeFont"
5
+ include_class "java.awt.Font"
6
+
7
+ has_behavior :Spatial
8
+ PLAIN = Font::PLAIN
9
+ ITALIC = Font::ITALIC
10
+ BOLD = Font::BOLD
11
+
12
+ attr_accessor :text, :size, :style, :font_name
13
+
14
+ def load(text, options={})
15
+ @font_name = "Arial"
16
+ @size = 12
17
+ @text = text
18
+ @style = PLAIN
19
+ load_font
20
+ orient_text(options)
21
+ end
22
+
23
+ def text_width
24
+ @font.get_width(@text)
25
+ end
26
+
27
+ def text_height
28
+ @font.get_height(@text)
29
+ end
30
+
31
+ def draw(graphics)
32
+ half_width = @font.get_width(@text) / 2
33
+ half_height = @font.get_height(@text) / 2
34
+ @font.draw_string(x - half_width , y - half_height, @text)
35
+ end
36
+
37
+ def font_name=(name)
38
+ @font_name = name
39
+ load_font
40
+ end
41
+ alias_method :set_font_name, :font_name=
42
+
43
+ def size=(size)
44
+ @size = size
45
+ load_font
46
+ end
47
+ alias_method :set_size, :size=
48
+
49
+ def style=(style)
50
+ raise "Invalid font style, must be PLAIN, ITALIC or BOLD" unless [PLAIN, ITALIC, BOLD].member? style
51
+ @style = style
52
+ load_font
53
+ end
54
+ alias_method :set_style, :style=
55
+
56
+ private
57
+ def orient_text(options)
58
+ case options[:justify]
59
+ when :top_left
60
+ self.position = options[:position] + Vector.new(text_width, text_height).half if options[:position]
61
+ when :bottom_right
62
+ self.position = options[:position] - Vector.new(text_width, text_height).half if options[:position]
63
+ when :center, nil
64
+ self.position = options[:position]
65
+ end
66
+ end
67
+
68
+ def load_font
69
+ @font = TrueTypeFont.new(Font.new(@font_name, @style, @size), true)
70
+ end
71
+ end
@@ -0,0 +1,85 @@
1
+ class TriangleTrail < Jemini::GameObject
2
+ #has_behavior :Movable2d
3
+ has_behavior :Spatial
4
+ attr_accessor :radius, :alpha
5
+
6
+ def load
7
+ @trail = []
8
+ @trail_poly_size = 10
9
+ @trail_size = 50
10
+ @radius = 10
11
+ @alpha = 0.5
12
+ @flip = false
13
+ #TODO: Remove message when the callback stuff is checked in
14
+ @first_move = true
15
+ on_after_position_changes do |message|
16
+ if @first_move
17
+ @first_move = false
18
+ next
19
+ end
20
+ @trail.pop if @trail.size >= @trail_size
21
+ @trail.unshift([x, y])
22
+ end
23
+ end
24
+
25
+ def draw(graphics)
26
+ if @trail.size > 3
27
+ gl = Java::org::newdawn::slick::opengl::renderer::Renderer.get
28
+
29
+ #Java::org::newdawn::slick::opengl::SlickCallable.new do
30
+ callable_class = Java::org::newdawn::slick::opengl::SlickCallable
31
+ callable_class.enter_safe_block
32
+ # use LWJGL's const directly, Slick's wrapper does not have the triangle strip const
33
+ triangle_strip_enum = Java::org::lwjgl::opengl::GL11::GL_TRIANGLE_STRIP
34
+ gl.gl_begin triangle_strip_enum
35
+ gl.gl_color4f(0.0, 1.0, 1.0, @alpha)
36
+
37
+ origin_x, origin_y = calculate_point_on_trail_edge(@trail[1], @trail[0], @radius, @flip)
38
+ gl.gl_vertex2f(origin_x, origin_y)
39
+
40
+ flipped_origin_x, flipped_origin_y = calculate_point_on_trail_edge(@trail[1], @trail[0], @radius, !@flip)
41
+ gl.gl_vertex2f(flipped_origin_x, flipped_origin_y)
42
+
43
+ last_trail_vector = @trail[1]
44
+ #gl.gl_color4f(0.0, 1.0, 1.0, alpha)
45
+ @trail[2..-1].each_with_index do |trail_vector, index|
46
+ next if trail_vector == last_trail_vector
47
+ actual_trail_size = (@trail.size - 1).to_f
48
+ trail_radius = (@radius) * ((actual_trail_size - (index + 2).to_f) / actual_trail_size)
49
+
50
+ rotated_x, rotated_y = calculate_point_on_trail_edge(trail_vector, last_trail_vector, trail_radius, @flip)
51
+ gl.gl_vertex2f(rotated_x, rotated_y)
52
+ rotated_x, rotated_y = calculate_point_on_trail_edge(trail_vector, last_trail_vector, trail_radius, !@flip)
53
+ gl.gl_vertex2f(rotated_x, rotated_y)
54
+
55
+ last_trail_vector = trail_vector
56
+ end
57
+ gl.gl_end
58
+ callable_class.leave_safe_block
59
+ end
60
+ end
61
+
62
+ def calculate_point_on_trail_edge(current_vector, previous_vector, trail_radius, flip)
63
+ trail_diff = [current_vector[0] - previous_vector[0], current_vector[1] - previous_vector[1]]
64
+ diff_angle = Math.atan2(trail_diff[1].to_f, trail_diff[0].to_f)
65
+
66
+ rotation_angle = (Math::PI * 1) / 2
67
+ rotation_angle = -rotation_angle if flip
68
+
69
+ sine = Math.sin(diff_angle + rotation_angle)
70
+ cosine = Math.cos(diff_angle + rotation_angle)
71
+ rotated_weight_x = cosine
72
+ rotated_weight_y = sine
73
+
74
+ rotated_x = (trail_radius * rotated_weight_x) + current_vector[0]
75
+ rotated_y = (trail_radius * rotated_weight_y) + current_vector[1]
76
+
77
+ [rotated_x, rotated_y]
78
+ end
79
+
80
+ def normalize_vector(vector)
81
+ max_value = vector.map{|value| value.abs}.max
82
+ return Array.new(vector.size, 0) if max_value.zero?
83
+ vector.map {|value| value / max_value}
84
+ end
85
+ end
@@ -0,0 +1,164 @@
1
+ require 'logger_mixin'
2
+
3
+ #All other game states should inherit from this class.
4
+ module Jemini
5
+ class GameState
6
+
7
+ include LoggerMixin
8
+
9
+ attr_reader :container
10
+
11
+ @@active_state = nil
12
+ def self.active_state
13
+ @@active_state
14
+ end
15
+
16
+ def self.active_state=(state)
17
+ @@active_state = state
18
+ end
19
+
20
+ @@inputs = Hash.new {|h,k| h[k] = []}
21
+ def self.use_input(input)
22
+ @@inputs[self] << input
23
+ end
24
+
25
+ def self.inputs
26
+ @@inputs[self]
27
+ end
28
+
29
+ def initialize(container, game)
30
+ @container = container
31
+ @game = game
32
+
33
+ # don't use a hash literal because it messes up the load order and @managers isn't available for the managers to use
34
+ @managers = {}
35
+ @managers[:game_object] = BasicGameObjectManager.new(self)
36
+ @managers[:update] = BasicUpdateManager.new(self)
37
+ @managers[:message_queue] = MessageQueue.new(self)
38
+ @managers[:resource] = ResourceManager.new(self)
39
+ @managers[:input] = InputManager.new(self, container)
40
+ @managers[:render] = BasicRenderManager.new(self)
41
+
42
+ configure_inputs
43
+ load_resources
44
+ @paused = false
45
+ end
46
+
47
+ def screen_size
48
+ @game.screen_size
49
+ end
50
+
51
+ # deprecate
52
+ def screen_width
53
+ @game.screen_width
54
+ end
55
+
56
+ #deprecate
57
+ def screen_height
58
+ @game.screen_height
59
+ end
60
+
61
+ #Creates a game object of the given type on the named layer.
62
+ #The given params will be passed to the object's constructor.
63
+ def create_on_layer(type, layer_name, *params)
64
+ game_object_type = if :game_object == type.to_sym || :GameObject == type.to_sym
65
+ Jemini::GameObject
66
+ elsif Module.const_defined?(type.camelize.to_sym)
67
+ log.debug "Creating: #{type.camelize.to_sym}"
68
+ type.constantize
69
+ else
70
+ try_require("game_objects/#{type.underscore}") or try_require("managers/#{type.underscore}")
71
+ type.camelize.constantize
72
+ end
73
+ game_object = game_object_type.new(self, *params)
74
+ add_game_object_to_layer game_object, layer_name
75
+ game_object
76
+ end
77
+
78
+ def create(type, *params)
79
+ create_on_layer(type, :default, *params)
80
+ end
81
+
82
+ def create_game_object(type, *params)
83
+ warn "create_game_object is deprecated, use create instead"
84
+ create(type, *params)
85
+ end
86
+
87
+ def manager(type)
88
+ @managers[type]
89
+ end
90
+
91
+ def add_game_object(game_object)
92
+ @managers[:game_object].add_game_object game_object
93
+ end
94
+
95
+ def add_game_object_to_layer(game_object, layer_name)
96
+ @managers[:game_object].add_game_object_to_layer game_object, layer_name
97
+ end
98
+
99
+ def remove(game_object)
100
+ @managers[:game_object].remove_game_object(game_object)
101
+ end
102
+
103
+ def remove_game_object(game_object)
104
+ warn "remove_game_object is deprecated, use remove instead"
105
+ remove(game_object)
106
+ end
107
+
108
+ def switch_state(state_name, *args)
109
+ @game.queue_state state_name, args
110
+ state_name
111
+ end
112
+
113
+ def use_input(input)
114
+ @managers[:input].use_input input
115
+ end
116
+
117
+ def load(*args); end
118
+
119
+ def quit_game
120
+ java.lang.System.exit 0
121
+ end
122
+
123
+ def name
124
+ @name ||= self.class.name.underscore.sub('_state', '')
125
+ end
126
+
127
+ def load_resources
128
+ @managers[:resource].load_resources
129
+ end
130
+
131
+ private
132
+
133
+ def configure_inputs
134
+ # global - automatic
135
+ begin
136
+ use_input :global
137
+ rescue LoadError
138
+ end
139
+
140
+ # class name - automatic
141
+ begin
142
+ use_input self.class.to_s.underscore.sub('_state', '')
143
+ rescue LoadError
144
+ end
145
+ # class declared
146
+ self.class.inputs.each {|input| use_input input}
147
+ end
148
+
149
+ def set_manager(type, manager)
150
+ @managers[type] = manager
151
+ end
152
+
153
+ def try_require(path)
154
+ begin
155
+ require path
156
+ rescue LoadError => e
157
+ log.warn "Failed to require: #{path}"
158
+ return false
159
+ end
160
+ log.debug "Successful require: #{path}"
161
+ return true
162
+ end
163
+ end
164
+ end