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,45 @@
1
+ class SplineStretchableSprite < Gemini::Behavior
2
+ INDEPENDENT_MODE = :independent
3
+ MERGED_MODE = :merged
4
+ depends_on_kind_of :Sprite
5
+ depends_on :UpdatesAtConsistantRate #TODO: Make Updates coexist with this behavior
6
+
7
+ def load
8
+ @original_image = @target.image
9
+ @target.on_update do
10
+ # @target.width = @original_width
11
+ # @target.height = @original_height
12
+ old_width = @target.width
13
+ old_height = @target.height
14
+ @target.image = @original_image
15
+ if INDEPENDENT_MODE == @mode
16
+ @target.image_scaling(@spline_x.succ, @spline_y.succ)
17
+ else
18
+ @target.image_scaling(@spline.succ)
19
+ end
20
+
21
+ new_width = @target.width
22
+ new_height = @target.height
23
+ #recenter_position(old_width, old_height, new_width, new_height) unless @target.kind_of? TangibleSprite
24
+ end
25
+ end
26
+
27
+ def set_stretch_splines(spline_x, spline_y = nil)
28
+ @original_image = @target.image
29
+ unless spline_y.nil?
30
+ @spline_x = spline_x
31
+ @spline_y = spline_y
32
+ @mode = INDEPENDENT_MODE
33
+ else
34
+ @spline = spline_x
35
+ @mode = MERGED_MODE
36
+ end
37
+ end
38
+ alias_method :set_stretch_spline, :set_stretch_splines
39
+
40
+ private
41
+ def recenter_position(old_width, old_height, new_width, new_height)
42
+ @target.x = @target.x + (old_width - new_width) / 2
43
+ @target.y = @target.y + (old_height - new_height) / 2
44
+ end
45
+ end
@@ -0,0 +1,99 @@
1
+ require 'behaviors/drawable'
2
+
3
+ # WARNING: Using Slick's image for rotation can cause some odd quirks with it
4
+ # not quite rotating correctly (especially noticable around 180 degress).
5
+ # @rotation stands alone for this reason, instead of using Slick's rotation
6
+ class Sprite < Drawable
7
+ include_class 'org.newdawn.slick.Image'
8
+ depends_on :Spatial
9
+ attr_accessor :image, :color, :texture_coords, :image_size
10
+ alias_method :set_image_size, :image_size=
11
+ wrap_with_callbacks :draw
12
+
13
+ def load
14
+ @color = Color.new(1.0, 1.0, 1.0, 1.0)
15
+ @texture_coords = [Vector.new(0.0, 0.0), Vector.new(1.0, 1.0)]
16
+ @rotation = 0.0
17
+ end
18
+
19
+ def image=(sprite_name)
20
+ if sprite_name.kind_of? Image
21
+ @image = sprite_name
22
+ else
23
+ @image = Image.new("data/#{sprite_name}")
24
+ end
25
+ set_image_size(Vector.new(@image.width, @image.height))
26
+ end
27
+ alias_method :set_image, :image=
28
+
29
+ def color=(color)
30
+ @color = color
31
+ end
32
+ alias_method :set_color, :color=
33
+
34
+ #TODO: Take vectors for first args as well
35
+ def image_scaling(x_scale, y_scale = nil)
36
+ y_scale = x_scale if y_scale.nil?
37
+ set_image @image.get_scaled_copy(x_scale.to_f * image_size.x, y_scale.to_f * image_size.y)
38
+ end
39
+
40
+ #TODO: Take vectors for first args as well
41
+ def scale_image_from_original(x_scale, y_scale = nil)
42
+ y_scale = x_scale if y_scale.nil?
43
+ @original_image = @image.copy if @original_image.nil?
44
+ set_image @original_image.get_scaled_copy(x_scale.to_f * @original_image.width, y_scale.to_f * @original_image.height)
45
+ end
46
+
47
+ def image_rotation
48
+ @rotation
49
+ end
50
+
51
+ def image_rotation=(rotation)
52
+ @rotation = rotation
53
+ rescue => e
54
+ puts "rotation error for: #{@target}"
55
+ end
56
+ alias_method :set_image_rotation, :image_rotation=
57
+
58
+ def add_rotation(rotation)
59
+ @rotation += rotation
60
+ end
61
+
62
+ def flip_horizontally
63
+ @texture_coords[1].x, @texture_coords[0].x = @texture_coords[0].x, @texture_coords[1].x
64
+ end
65
+
66
+ def flip_vertically
67
+ @texture_coords[1].y, @texture_coords[0].y = @texture_coords[0].y, @texture_coords[1].y
68
+ end
69
+
70
+ def top_left_position
71
+ #Vector.new(center_position.x - image_size.x / 2.0, center_position.y - image_size.y / 2.0)
72
+ Vector.new(@target.x - image_size.x / 2.0, @target.y - image_size.y / 2.0)
73
+ end
74
+
75
+ def move_by_top_left(move_x_or_vector, move_y = nil)
76
+ half_width = image_size.x / 2.0
77
+ half_height = image_size.y / 2.0
78
+ if move_y.nil?
79
+ @target.move(move_x_or_vector.x + half_width, move_x_or_vector.y + half_height)
80
+ else
81
+ @target.move(move_x_or_vector + half_width, move_y + half_height)
82
+ end
83
+ end
84
+
85
+ def draw(graphics)
86
+ return if @image.nil? || @image_size.nil?
87
+ half_width = image_size.x / 2.0
88
+ half_height = image_size.y / 2.0
89
+ center_x = @target.x - half_width
90
+ center_y = @target.y - half_height
91
+ unless 0 == @rotation
92
+ graphics.rotate @target.x, @target.y, @rotation
93
+ end
94
+ @image.draw(center_x, center_y, @target.x + half_width, @target.y + half_height,
95
+ @texture_coords[0].x * image_size.x, @texture_coords[0].y * image_size.y, @texture_coords[1].x * image_size.x, @texture_coords[1].y * image_size.y,
96
+ @color.native_color)
97
+ graphics.reset_transform
98
+ end
99
+ end
@@ -0,0 +1,31 @@
1
+ # Notes from Logan:
2
+ # I started on this behavior, and realized what I needed was multiple axises of states for my behavior
3
+ # that I wanted to use Stateful in. This behavior is simple, and seems like it would be useful for some cases.
4
+ # Thus, the behavior remains, but it is not tested or used at the time of this comment.
5
+ class Stateful < Gemini::Behavior
6
+ class StateTransferEvent
7
+ attr_accessor :before_state, :after_state
8
+ def initialize(before_state, after_state)
9
+ @before_state = before_state
10
+ @after_state = after_state
11
+ end
12
+ end
13
+ attr_accessor :default_state, :current_state
14
+ wrap_with_callbacks :transfer_state
15
+
16
+ def load
17
+ @state_transitions = {}
18
+ @target.enable_listeners_for :state_transfer_accepted
19
+ @target.enable_listeners_for :state_transfer_rejected
20
+ end
21
+
22
+ def transfer_state(state)
23
+ event = StateTransferEvent.new(@current_state, state)
24
+ if @state_transitions[@current_state].include? state
25
+ @current_state = state
26
+ notify :state_transfer_accepted, event
27
+ else
28
+ notify :state_transfer_rejected, event
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,27 @@
1
+ class Taggable < Gemini::Behavior
2
+
3
+ def load
4
+ @tags = []
5
+ @target.enable_listeners_for :tag_added, :tag_removed
6
+ end
7
+
8
+ def add_tag(*tags)
9
+ new_tags = tags - @tags
10
+ @tags.concat new_tags
11
+ new_tags.each { |tag| @target.notify :tag_added, tag }
12
+ end
13
+
14
+ def remove_tag(*tags)
15
+ tags_to_remove = @tags & tags
16
+ @tags -= tags_to_remove
17
+ tags_to_remove.each {|tag| @target.notify :tag_removed, tag}
18
+ end
19
+
20
+ def has_tag?(*tags)
21
+ tags.any? {|tag| @tags.member?(tag) }
22
+ end
23
+
24
+ def tags
25
+ @tags.clone
26
+ end
27
+ end
@@ -0,0 +1,51 @@
1
+ class TangibleBox
2
+ attr_accessor :size
3
+ def get_points(top_left_position, rotation)
4
+ top_left = top_left_position
5
+ top_right = Vector.new(top_left_position.x + size.x, top_left_position.y)
6
+ bottom_left = Vector.new(top_left_position.x, top_left_position.y + size.y)
7
+ bottom_right = Vector.new(top_left_position.x + size.x, top_left_position.y + size.y)
8
+ [top_left, top_right, bottom_right, bottom_left]
9
+ end
10
+ end
11
+
12
+ class Tangible < Gemini::Behavior
13
+ depends_on :Spatial
14
+ attr_reader :tangible_shape
15
+
16
+ def load
17
+ @target.enable_listeners_for :tangible_collision
18
+ end
19
+
20
+ def tangible_debug_mode=(mode)
21
+ if mode
22
+ @target.add_behavior :DebugTangible
23
+ else
24
+ @target.remove_behavior :DebugTangible
25
+ end
26
+ end
27
+ alias_method :set_tangible_debug_mode, :tangible_debug_mode=
28
+
29
+ def set_tangible_shape(name, *args)
30
+ @tangible_shape = case name
31
+ when :Box
32
+ box = TangibleBox.new
33
+ if args.size == 1
34
+ box.size = args[0]
35
+ else
36
+ box.size = Vector.new(args[0], args[1])
37
+ end
38
+ box
39
+ end
40
+ end
41
+
42
+ def tangibly_collides_with?(other_tangible)
43
+ #TODO: top_left isn't on spatial...
44
+ other_shape = other_tangible.tangible_shape
45
+
46
+ ((@target.x <= other_tangible.x && (@target.x + @tangible_shape.size.x) >= other_tangible.x) ||
47
+ (@target.x >= other_tangible.x && @target.x <= (other_tangible.x + other_shape.size.x))) &&
48
+ ((@target.y <= other_tangible.y && (@target.y + @tangible_shape.size.y) >= other_tangible.y) ||
49
+ (@target.y >= other_tangible.y && @target.y <= (other_tangible.y + other_shape.size.y)))
50
+ end
51
+ end
@@ -0,0 +1,79 @@
1
+ class Timeable < Gemini::Behavior
2
+ depends_on :Updates
3
+
4
+ def load
5
+ @target.enable_listeners_for :timer_tick, :countdown_complete
6
+ @timers = {}
7
+ @target.on_update do |delta|
8
+ update_timers delta
9
+ end
10
+ end
11
+
12
+ def add_countdown(name, seconds, notify_frequency = nil)
13
+ @timers[name] = Timer.new(name, Timer::COUNTDOWN, seconds, notify_frequency) {|timer| @target.notify :timer_tick, timer }
14
+ end
15
+
16
+ def add_countup(name, seconds, notify_frequency = nil)
17
+ @timers[name] = Timer.new(name, Timer::COUNTUP, seconds, notify_frequency) {|timer| @target.notify :timer_tick, timer }
18
+ end
19
+
20
+ private
21
+ def update_timers(delta)
22
+ @timers.each do |name, timer|
23
+ timer.apply_delta delta
24
+ if timer.countdown_complete?
25
+ @target.notify :countdown_complete, name
26
+ end
27
+ end
28
+ # in order to keep from mutating the array while we iterate, handle separately.
29
+ @timers.delete_if {|name, timer| timer.countdown_complete? }
30
+ end
31
+ end
32
+
33
+ class Timer
34
+ COUNTDOWN = :countdown
35
+ COUNTUP = :countup
36
+ def initialize(name, direction, seconds, notify_frequency, &notify_callback)
37
+ @name = name
38
+ @direction = direction
39
+ @milliseconds = seconds * 1000.0
40
+ @notify_frequency = notify_frequency * 1000.0 if notify_frequency
41
+ @notify_callback = notify_callback unless notify_frequency.nil?
42
+ @current_milliseconds = 0
43
+ @milliseconds_since_last_notify = 0
44
+ end
45
+
46
+ def apply_delta(delta_in_milliseconds)
47
+ return if @countdown_complete
48
+
49
+ @current_milliseconds += delta_in_milliseconds
50
+ @milliseconds_since_last_notify += delta_in_milliseconds
51
+
52
+ if @notify_callback && @notify_frequency && (@milliseconds_since_last_notify >= @notify_frequency)
53
+ @notify_callback.call(self)
54
+ @milliseconds_since_last_notify = 0
55
+ end
56
+ @countdown_complete = true if (COUNTDOWN == @direction) && (@current_milliseconds >= @milliseconds)
57
+ end
58
+
59
+ def reset
60
+ @current_milliseconds = 0
61
+ @countdown_complete = false
62
+ end
63
+
64
+ def ticks_elapsed
65
+ (@current_milliseconds / (@notify_frequency)).round
66
+ end
67
+
68
+ def ticks_left
69
+ ((@milliseconds - @current_milliseconds) / (@notify_frequency)).round
70
+ end
71
+
72
+ def percent_complete
73
+ @current_milliseconds / @milliseconds
74
+ end
75
+
76
+ def countdown_complete?
77
+ @countdown_complete
78
+ end
79
+ end
@@ -0,0 +1,41 @@
1
+ class TopDownVehicle < Gemini::Behavior
2
+ attr_accessor :minimum_speed_to_turn
3
+ alias_method :set_minimum_speed_to_turn, :minimum_speed_to_turn=
4
+
5
+ depends_on :VectoredMovement
6
+
7
+ def load
8
+ @vm_behavior = @target.send(:instance_variable_get, :@__behaviors)[:VectoredMovement]
9
+ @target.set_damping 0.1
10
+ @target.set_angular_damping 0.1
11
+ @minimum_speed_to_turn = 2.5
12
+ @vectored_movement_turning = false
13
+
14
+ #TODO: Replace this with a spline method that determines how far to turn based on the spline
15
+ @target.on_update do
16
+ if @turning && !@vectored_movement_turning && (@target.velocity.x.abs + @target.velocity.y.abs) > @minimum_speed_to_turn
17
+ @at_beginning_of_turn.call
18
+ @vectored_movement_turning = true
19
+ end
20
+ end
21
+ end
22
+
23
+ def begin_acceleration(message)
24
+ @vm_behavior.begin_acceleration(message)
25
+ end
26
+
27
+ def end_acceleration(message)
28
+ @vm_behavior.end_acceleration(message)
29
+ end
30
+
31
+ def begin_turn(message)
32
+ @turning = true
33
+ @at_beginning_of_turn = Proc.new { @vm_behavior.begin_turn(message) }
34
+ end
35
+
36
+ def end_turn(message)
37
+ @turning = false
38
+ @vm_behavior.end_turn(message)
39
+ @vectored_movement_turning = false
40
+ end
41
+ end
@@ -0,0 +1,41 @@
1
+ require 'behaviors/drawable'
2
+
3
+ class TriangleTrailEmittable < Gemini::Behavior
4
+ #depends_on :Movable2d
5
+ depends_on :Updates
6
+ depends_on_kind_of :Spatial
7
+
8
+ def load
9
+ @emitter = @target.game_state.create :TriangleTrail
10
+ @emitter_offset = [0,0]
11
+
12
+
13
+ @target.on_update do
14
+ @emitter.move(@emitter_offset[0] + @target.x, @emitter_offset[1] + @target.y)
15
+ end
16
+ end
17
+
18
+ def unload
19
+ @target.game_state.remove @emitter
20
+ end
21
+
22
+ def alpha
23
+ @emitter.alpha
24
+ end
25
+
26
+ def alpha=(alpha)
27
+ @emitter.alpha = alpha
28
+ end
29
+
30
+ def emit_triangle_trail_from_offset(offset)
31
+ @emitter_offset = offset
32
+ end
33
+
34
+ def emit_triangle_trail_with_radius(radius)
35
+ @emitter.radius = radius
36
+ end
37
+
38
+ def layer=(layer_name)
39
+ @target.game_state.manager(:game_object).move_game_object_to_layer(@emitter, layer_name)
40
+ end
41
+ end
@@ -0,0 +1,10 @@
1
+ class Updates < Gemini::Behavior
2
+
3
+ def load
4
+ @target.enable_listeners_for :update
5
+ end
6
+
7
+ def update(delta)
8
+ @target.notify :update, delta
9
+ end
10
+ end
@@ -0,0 +1,27 @@
1
+ class UpdatesAtConsistantRate < Gemini::Behavior
2
+ attr_accessor :updates_per_second
3
+
4
+ def load
5
+ @update_delay = 0
6
+ @time_since_last_update = 0
7
+ @target.enable_listeners_for :update
8
+ self.updates_per_second = 30
9
+ end
10
+
11
+ def updates_per_second=(count)
12
+ if 0 == count
13
+ @update_delay = 0
14
+ else
15
+ @update_delay = 1000 / count
16
+ end
17
+ @updates_per_second = count
18
+ end
19
+
20
+ def update(delta_in_milliseconds)
21
+ @time_since_last_update += delta_in_milliseconds
22
+ if @time_since_last_update > @update_delay
23
+ @time_since_last_update -= @update_delay
24
+ notify :update
25
+ end
26
+ end
27
+ end