gemini 1.0.0

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 (114) hide show
  1. data/bin/gemini +18 -0
  2. data/build_configuration.rb +24 -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-raw.dll +0 -0
  13. data/lib/native_files/libjinput-linux.so +0 -0
  14. data/lib/native_files/libjinput-linux64.so +0 -0
  15. data/lib/native_files/libjinput-osx.jnilib +0 -0
  16. data/lib/native_files/liblwjgl.jnilib +0 -0
  17. data/lib/native_files/liblwjgl.so +0 -0
  18. data/lib/native_files/liblwjgl64.so +0 -0
  19. data/lib/native_files/libopenal.so +0 -0
  20. data/lib/native_files/lwjgl.dll +0 -0
  21. data/lib/native_files/openal.dylib +0 -0
  22. data/lib/natives-linux.jar +0 -0
  23. data/lib/natives-mac.jar +0 -0
  24. data/lib/natives-win32.jar +0 -0
  25. data/lib/phys2d.jar +0 -0
  26. data/lib/slick.jar +0 -0
  27. data/package/jar/gemini.jar +0 -0
  28. data/src/base_state.rb +112 -0
  29. data/src/behavior.rb +230 -0
  30. data/src/behavior_event.rb +23 -0
  31. data/src/behaviors.txt +5 -0
  32. data/src/behaviors/animated_sprite.rb +51 -0
  33. data/src/behaviors/audible.rb +11 -0
  34. data/src/behaviors/axis_stateful.rb +33 -0
  35. data/src/behaviors/big_sprite.rb +56 -0
  36. data/src/behaviors/bounding_box_collidable.rb +25 -0
  37. data/src/behaviors/camera_anchored_drawable.rb +20 -0
  38. data/src/behaviors/cardinal_movable.rb +114 -0
  39. data/src/behaviors/clickable.rb +18 -0
  40. data/src/behaviors/countable.rb +31 -0
  41. data/src/behaviors/debug_physical.rb +31 -0
  42. data/src/behaviors/debug_tangible.rb +30 -0
  43. data/src/behaviors/drawable.rb +6 -0
  44. data/src/behaviors/drawable_shape.rb +43 -0
  45. data/src/behaviors/fading_image_trail_emittable.rb +28 -0
  46. data/src/behaviors/game_object_emittable.rb +12 -0
  47. data/src/behaviors/gravity_source.rb +21 -0
  48. data/src/behaviors/inertial.rb +11 -0
  49. data/src/behaviors/movable2d.rb +9 -0
  50. data/src/behaviors/multi_animated_sprite.rb +22 -0
  51. data/src/behaviors/physical.rb +348 -0
  52. data/src/behaviors/physical_cardinal_movable.rb +110 -0
  53. data/src/behaviors/physical_sprite.rb +29 -0
  54. data/src/behaviors/platformer_controllable.rb +144 -0
  55. data/src/behaviors/pointer.rb +28 -0
  56. data/src/behaviors/pressable.rb +13 -0
  57. data/src/behaviors/receives_events.rb +21 -0
  58. data/src/behaviors/regional.rb +71 -0
  59. data/src/behaviors/rotates_to_point.rb +18 -0
  60. data/src/behaviors/spatial.rb +41 -0
  61. data/src/behaviors/spline_stretchable_sprite.rb +45 -0
  62. data/src/behaviors/sprite.rb +99 -0
  63. data/src/behaviors/stateful.rb +31 -0
  64. data/src/behaviors/taggable.rb +27 -0
  65. data/src/behaviors/tangible.rb +51 -0
  66. data/src/behaviors/timeable.rb +79 -0
  67. data/src/behaviors/top_down_vehicle.rb +41 -0
  68. data/src/behaviors/triangle_trail_emittable.rb +41 -0
  69. data/src/behaviors/updates.rb +10 -0
  70. data/src/behaviors/updates_at_consistant_rate.rb +27 -0
  71. data/src/behaviors/vectored_movement.rb +47 -0
  72. data/src/behaviors/world_collidable.rb +8 -0
  73. data/src/color.rb +70 -0
  74. data/src/game_object.rb +174 -0
  75. data/src/game_objects/background.rb +9 -0
  76. data/src/game_objects/fading_image.rb +23 -0
  77. data/src/game_objects/icon_strip_counter_display.rb +58 -0
  78. data/src/game_objects/static_sprite.rb +18 -0
  79. data/src/game_objects/tangible_object.rb +4 -0
  80. data/src/game_objects/text.rb +59 -0
  81. data/src/game_objects/triangle_trail.rb +85 -0
  82. data/src/gemini.rb +110 -0
  83. data/src/gemini_version.rb +3 -0
  84. data/src/inflector.rb +68 -0
  85. data/src/input_helpers/joystick_dead_zone_filter.rb +9 -0
  86. data/src/listenable_mixin.rb +15 -0
  87. data/src/managers/basic_game_object_manager.rb +81 -0
  88. data/src/managers/basic_physics_manager.rb +97 -0
  89. data/src/managers/basic_render_manager.rb +48 -0
  90. data/src/managers/basic_tangible_manager.rb +33 -0
  91. data/src/managers/basic_update_manager.rb +27 -0
  92. data/src/managers/diagnostic/diagnostic_input_manager.rb +0 -0
  93. data/src/managers/input_manager.rb +229 -0
  94. data/src/managers/input_support/input_mapping.rb +126 -0
  95. data/src/managers/input_support/input_message.rb +5 -0
  96. data/src/managers/input_support/slick_input_listener.rb +19 -0
  97. data/src/managers/input_support/slick_input_message.rb +11 -0
  98. data/src/managers/input_support/slick_input_translator.rb +15 -0
  99. data/src/managers/message_queue.rb +54 -0
  100. data/src/managers/scrolling_render_manager.rb +44 -0
  101. data/src/managers/sound_manager.rb +60 -0
  102. data/src/managers/tag_manager.rb +43 -0
  103. data/src/math.rb +13 -0
  104. data/src/music.rb +14 -0
  105. data/src/org/rubyforge/rawr/Main.java +67 -0
  106. data/src/platform.rb +28 -0
  107. data/src/proc_enhancement.rb +5 -0
  108. data/src/project_generator.rb +122 -0
  109. data/src/skeleton.txt +10 -0
  110. data/src/spline.rb +13 -0
  111. data/src/states/input_diagnostic_state.rb +53 -0
  112. data/src/vector.rb +99 -0
  113. data/test/test_state.rb +3 -0
  114. metadata +181 -0
@@ -0,0 +1,47 @@
1
+ class VectoredMovement < Gemini::Behavior
2
+ attr_accessor :forward_speed, :reverse_speed, :rotation_speed
3
+ alias_method :set_forward_speed, :forward_speed=
4
+ alias_method :set_reverse_speed, :reverse_speed=
5
+ alias_method :set_rotation_speed, :rotation_speed=
6
+
7
+ depends_on :Physical
8
+ depends_on :ReceivesEvents
9
+
10
+ def load
11
+ @target.set_damping 0.0
12
+ @target.set_angular_damping 0.0
13
+
14
+ @forward_speed = 0
15
+ @reverse_speed = 0
16
+ @rotation_speed = 0
17
+
18
+ @intended_velocity = 0
19
+ @angular_velocity = 0
20
+ @movement_vector = Vector.new(0,0)
21
+
22
+ @target.on_update do
23
+ @target.set_angular_velocity(@angular_velocity)
24
+ @target.add_velocity(Vector.from_polar_vector(@intended_velocity, @target.rotation))
25
+ end
26
+ end
27
+
28
+ def begin_acceleration(message)
29
+ @intended_velocity = :forward == message.value ? @forward_speed : @reverse_speed
30
+ end
31
+
32
+ def end_acceleration(message)
33
+ @intended_velocity = 0
34
+ end
35
+
36
+ def begin_turn(message)
37
+ if :clockwise == message.value
38
+ @angular_velocity = @rotation_speed
39
+ else
40
+ @angular_velocity = -@rotation_speed
41
+ end
42
+ end
43
+
44
+ def end_turn(message)
45
+ @angular_velocity = 0
46
+ end
47
+ end
@@ -0,0 +1,8 @@
1
+ class WorldCollidable < Gemini::Behavior
2
+ depends_on :BoundingBoxCollidable
3
+ depends_on_kind_of :CollisionPoolAlgorithm
4
+
5
+ def world_collision_check
6
+ get_collision_candidates.each {|candidate| collision_check candidate}
7
+ end
8
+ end
@@ -0,0 +1,70 @@
1
+ class Color
2
+ attr_reader :native_color
3
+
4
+ def initialize(red_or_other, blue = 0.0, green = 0.0, alpha = 1.0)
5
+ if red_or_other.kind_of? Numeric
6
+ @native_color = new_native_color(red_or_other, blue, green, alpha)
7
+ else
8
+ # create from predefined Slick colors
9
+ fixed_color = Java::org::newdawn::slick::Color.send(red_or_other.to_s.downcase)
10
+ # we don't want to change the original, so we copy it
11
+ @native_color = new_native_color(fixed_color.r, fixed_color.g, fixed_color.b, fixed_color.a)
12
+ end
13
+ end
14
+
15
+ def red
16
+ @native_color.r
17
+ end
18
+
19
+ def blue
20
+ @native_color.b
21
+ end
22
+
23
+ def green
24
+ @native_color.g
25
+ end
26
+
27
+ def alpha
28
+ @native_color.a
29
+ end
30
+
31
+ def transparency
32
+ 1.0 - alpha
33
+ end
34
+
35
+ def red=(new_red)
36
+ @native_color.r = new_red
37
+ end
38
+
39
+ def green=(new_green)
40
+ @native_color.g = new_green
41
+ end
42
+
43
+ def blue=(new_blue)
44
+ @native_color.b = new_blue
45
+ end
46
+
47
+ def alpha=(new_alpha)
48
+ @native_color.a = new_alpha
49
+ end
50
+
51
+ def transparency=(new_transparency)
52
+ self.alpha = 1.0 - new_transparency
53
+ end
54
+
55
+ def darken_by(amount)
56
+ @native_color.darken amount
57
+ end
58
+
59
+ def darken_by!(amount)
60
+ @native_color = @native_color.darken amount
61
+ end
62
+
63
+ def fade_by(amount)
64
+ self.alpha = alpha * (1.0 - amount)
65
+ end
66
+ private
67
+ def new_native_color(red, blue, green, alpha)
68
+ Java::org::newdawn::slick::Color.new(red, blue, green, alpha)
69
+ end
70
+ end
@@ -0,0 +1,174 @@
1
+ require 'behavior'
2
+ require 'listenable_mixin'
3
+
4
+ module Gemini
5
+ class GameObject
6
+ include ListenableMixin
7
+ attr_reader :game_state
8
+
9
+ @@declared_behaviors = Hash.new{|h,k| h[k] = []}
10
+ def self.has_behavior(behavior)
11
+ require "behaviors/#{behavior.underscore}"
12
+ @@declared_behaviors[self] << behavior
13
+ end
14
+
15
+ def initialize(state, *args)
16
+ @game_state = state
17
+ @callbacks = Hash.new {|h,k| h[k] = []}
18
+ @__behaviors = {}
19
+ enable_listeners_for :before_remove, :after_remove
20
+ declared_behaviors.each do |behavior|
21
+ add_behavior(behavior)
22
+ end
23
+ validate_dependant_behaviors
24
+ load(*args)
25
+ end
26
+
27
+ def has_behavior?(behavior_name)
28
+ @__behaviors.has_key? behavior_name
29
+ end
30
+
31
+ def add_behavior(behavior_name)
32
+ klass = nil
33
+ retried = false
34
+ begin
35
+ klass = behavior_name.camelize.constantize
36
+ rescue NameError
37
+ raise if retried
38
+ require "behaviors/#{behavior_name.underscore}"
39
+ retried = true
40
+ retry
41
+ end
42
+ @__behaviors[behavior_name] = klass.new(self) if @__behaviors[behavior_name].nil?
43
+ validate_dependant_behaviors
44
+ rescue NameError => e
45
+ raise "Unable to load behavior #{behavior_name}, #{e.message}\n#{e.backtrace.join("\n")}"
46
+ end
47
+
48
+ def __destroy
49
+ notify :before_remove, self
50
+ #TODO: Perhaps expose this as a method on Behavior
51
+ #Gemini::Behavior.send(:class_variable_get, :@@depended_on_by).delete self
52
+ __remove_listeners
53
+ @__behaviors.each do |name, behavior|
54
+ #the list is being modified as we go through it, so check before use.
55
+ next if behavior.nil?
56
+ behavior.send(:delete)
57
+ end
58
+ notify :after_remove, self
59
+ end
60
+
61
+ def unload; end
62
+
63
+ def remove_behavior(behavior)
64
+ @__behaviors.delete(behavior).send(:delete) unless @__behaviors[behavior].nil?
65
+ end
66
+
67
+ # Takes a method and adds a corresponding listener registration method. Given
68
+ # the method foo, enable_listeners_for would generate the method on_foo and when
69
+ # notify was called with an event name of :foo, all callback blocks registered
70
+ # with the on_foo method would be called.
71
+ def enable_listeners_for(*methods)
72
+ methods.each do |method|
73
+ code = <<-ENDL
74
+ def on_#{method}(callback_method_name = nil, &callback)
75
+ register_listener(:#{method} , callback_method_name, callback)
76
+ end
77
+
78
+ def remove_#{method}(object, callback_or_callback_method=nil)
79
+ remove_registered_listener(:#{method}, object, callback_or_callback_method)
80
+ end
81
+ ENDL
82
+
83
+ self.instance_eval code, __FILE__, __LINE__
84
+ end
85
+ end
86
+
87
+ def register_listener(listener_method_name, callback_method_name, callback)
88
+ if callback_method_name
89
+ __added_listener_for(self, listener_method_name, callback_method_name)
90
+ @callbacks[listener_method_name] << callback_method_name
91
+ else
92
+ origin = callback.source
93
+ origin.extend Gemini::ListenableMixin unless origin.kind_of? Gemini::ListenableMixin
94
+ origin.__added_listener_for(self, "#{listener_method_name}", callback)
95
+ @callbacks[listener_method_name] << callback
96
+ end
97
+ end
98
+
99
+ def remove_registered_listener(listener_method_name, object, callback_or_callback_method)
100
+ if callback_or_callback_method.nil? || callback_or_callback_method.kind_of?(Symbol)
101
+ @callbacks[listener_method_name].delete callback_or_callback_method
102
+ else
103
+ @callbacks[listener_method_name].delete_if {|callback| callback.source == object }
104
+ end
105
+ end
106
+
107
+ def notify(event_name, event = nil, callback_status = nil)
108
+ @callbacks[event_name.to_sym].each do |callback|
109
+ if event
110
+ if callback_status
111
+ if callback.kind_of? Symbol
112
+ send(callback, event, callback_status)
113
+ else
114
+ callback.call(event, callback_status)
115
+ end
116
+ break unless callback_status.nil? or callback_status.continue?
117
+ else
118
+ if callback.kind_of? Symbol
119
+ send(callback, event)
120
+ else
121
+ callback.call(event)
122
+ end
123
+ end
124
+ else
125
+ if callback.kind_of? Symbol
126
+ send(callback)
127
+ else
128
+ callback.call
129
+ end
130
+ end
131
+ end
132
+ end
133
+
134
+ def listen_for(message, target=self, &block)
135
+ target.send("on_#{message}", &block)
136
+ end
137
+
138
+ def kind_of?(klass)
139
+ super || @__behaviors.values.inject(false){|result, behavior| result || behavior.class == klass}
140
+ end
141
+ alias_method :is_a?, :kind_of?
142
+
143
+ def load(*args)
144
+ args.each do |behavior_name|
145
+ add_behavior behavior_name
146
+ end
147
+ end
148
+
149
+ private
150
+ def behavior_event_alias(behavior_class, aliases, &block)
151
+ if behavior = @__behaviors[behavior_class]
152
+ behavior.set_event_aliases(aliases, block)
153
+ else
154
+ raise "No behavior #{behavior_class} for game object #{self}"
155
+ end
156
+ end
157
+
158
+ def validate_dependant_behaviors
159
+ declared_behaviors.each do |behavior|
160
+ behavior.constantize.kind_of_dependencies.each do |dependant_behavior|
161
+ dependency = dependant_behavior.constantize
162
+ #TODO: This code cannot work until the game object has a list of behavior objects (behaviors returns names)
163
+ #next if behaviors.find {|behavior| p behavior; behavior.last.kind_of?(dependency)}
164
+ next
165
+ raise "Dependant behavior '#{dependant_behavior}' was not found on class #{self.class}"
166
+ end
167
+ end
168
+ end
169
+
170
+ def declared_behaviors
171
+ @@declared_behaviors[self.class]
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,9 @@
1
+ class Background < Gemini::GameObject
2
+ has_behavior :BigSprite
3
+
4
+ def load(file)
5
+ set_image file
6
+ move @game_state.screen_width / 2, @game_state.screen_height / 2
7
+ end
8
+ end
9
+
@@ -0,0 +1,23 @@
1
+ class FadingImage < Gemini::GameObject
2
+ has_behavior :Sprite
3
+ has_behavior :Spatial
4
+ has_behavior :Timeable
5
+
6
+ def load(sprite, color, seconds_to_fade_away)
7
+ self.image = sprite
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,58 @@
1
+ class IconStripCounterDisplay < Gemini::GameObject
2
+ TOP_LEFT_TO_BOTTOM_RIGHT_LAYOUT_MODE = :top_left_to_bottom_right
3
+ BOTTOM_RIGHT_TO_TOP_LEFT_LAYOUT_MODE = :bottom_right_to_top_left
4
+
5
+ has_behavior :Countable
6
+ has_behavior :Spatial
7
+ #has_behavior :CameraAnchoredDrawable
8
+ attr_accessor :icon, :background, :rows, :columns, :layout_mode
9
+
10
+ def load
11
+ @rows = 0
12
+ @columns = nil
13
+ @icons = []
14
+ @old_x = 0
15
+ @old_y = 0
16
+ @layout_mode = TOP_LEFT_TO_BOTTOM_RIGHT_LAYOUT_MODE
17
+ self.x = 0
18
+ self.y = 0
19
+ on_after_count_changes do
20
+ puts "count changed #{count}"
21
+ icon_count = count < 0 ? 0 : count
22
+ diff = @icons.size - icon_count
23
+ if diff > 0
24
+ 1.upto diff do
25
+ last_icon = @icons.pop
26
+ @game_state.remove_game_object last_icon
27
+ end
28
+ elsif diff < 0
29
+ 1.upto diff.abs do
30
+ sprite = @game_state.create_game_object :GameObject
31
+ sprite.add_behavior :Sprite
32
+ sprite.add_behavior :CameraAnchoredDrawable
33
+ sprite.image = @icon
34
+ position_sprite(x, y, @icons.size, sprite)
35
+ @icons << sprite
36
+ end
37
+ end
38
+ end
39
+ on_after_move do
40
+ @icons.each_with_index do |sprite, index|
41
+ position_sprite(x, y, index, sprite)
42
+ end
43
+ end
44
+ end
45
+
46
+ def position_sprite(offset_x, offset_y, sprite_index, sprite)
47
+ row_number = @rows.nil? ? sprite_index : (sprite_index % @rows)
48
+ column_number = @columns.nil? ? sprite_index : (sprite_index % @columns)
49
+ if TOP_LEFT_TO_BOTTOM_RIGHT_LAYOUT_MODE == @layout_mode
50
+ sprite_x = offset_x + (@icon.width * column_number)
51
+ sprite_y = offset_y + (@icon.height * row_number)
52
+ elsif BOTTOM_RIGHT_TO_TOP_LEFT_LAYOUT_MODE == @layout_mode
53
+ sprite_x = offset_x - (@icon.width * column_number)
54
+ sprite_y = offset_y - (@icon.height * row_number)
55
+ end
56
+ sprite.move(sprite_x, sprite_y)
57
+ end
58
+ end
@@ -0,0 +1,18 @@
1
+ class StaticSprite < Gemini::GameObject
2
+ has_behavior :TangibleSprite
3
+ def load(sprite_name_or_image, x=nil, y=nil, width=nil, height=nil, *tags)
4
+ set_image sprite_name_or_image
5
+ if width.nil? || height.nil?
6
+ set_shape :Box, image_size.x, image_size.y
7
+ else
8
+ set_shape :Box, width, height
9
+ end
10
+ set_mass Tangible::INFINITE_MASS
11
+ set_static_body
12
+ set_restitution 1.0
13
+ set_friction 0.0
14
+ unless x.nil? || y.nil?
15
+ move(x, y)
16
+ end
17
+ end
18
+ 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 < Gemini::GameObject
3
+ has_behavior :Tangible
4
+ end
@@ -0,0 +1,59 @@
1
+ include_class "org.newdawn.slick.TrueTypeFont"
2
+ include_class "java.awt.Font"
3
+ require 'behaviors/drawable'
4
+
5
+ class Text < Gemini::GameObject
6
+ has_behavior :Spatial
7
+ PLAIN = Font::PLAIN
8
+ ITALIC = Font::ITALIC
9
+ BOLD = Font::BOLD
10
+
11
+ attr_accessor :text, :size, :style, :font_name
12
+
13
+ def load(x = 0, y = 0, text = "")
14
+ move(x, y)
15
+ @font_name = "Arial"
16
+ @size = 12
17
+ @text = text
18
+ @style = PLAIN
19
+ load_font
20
+ end
21
+
22
+ def text_width
23
+ @font.get_width(@text)
24
+ end
25
+
26
+ def text_height
27
+ @font.get_height(@text)
28
+ end
29
+
30
+ def draw(graphics)
31
+ half_width = @font.get_width(@text) / 2
32
+ half_height = @font.get_height(@text) / 2
33
+ @font.draw_string(x - half_width , y - half_height, @text)
34
+ end
35
+
36
+ def font_name=(name)
37
+ @font_name = name
38
+ load_font
39
+ end
40
+ alias_method :set_font_name, :font_name=
41
+
42
+ def size=(size)
43
+ @size = size
44
+ load_font
45
+ end
46
+ alias_method :set_size, :size=
47
+
48
+ def style=(style)
49
+ raise "Invalid font style, must be PLAIN, ITALIC or BOLD" unless [PLAIN, ITALIC, BOLD].member? style
50
+ @style = style
51
+ load_font
52
+ end
53
+ alias_method :set_style, :style=
54
+
55
+ private
56
+ def load_font
57
+ @font = TrueTypeFont.new(Font.new(@font_name, @style, @size), true)
58
+ end
59
+ end