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,5 @@
1
+ Behaviors can't inherit from other behaviors (Drawable, Sprite, DrawableShape)
2
+ Behavior should provide an override ability for other behaviors (how else to handle draw, perhaps it needs to be smarter?)
3
+ Behaviors shouldn't use declared_methods. Instead they should use public methods.
4
+ Fix method collision (DrawableShape#set_shape, Physical#set_shape)
5
+ Behaviors should be able to call private data on other behaviors
@@ -0,0 +1,51 @@
1
+ class AnimatedSprite < Gemini::Behavior
2
+ include_class 'org.newdawn.slick.Image'
3
+ include_class 'org.newdawn.slick.Animation'
4
+ depends_on :Sprite
5
+ attr_accessor :animation
6
+
7
+ def load
8
+ @fps = 1
9
+ @animation = Animation.new
10
+ @target.game_state.manager(:update).on_before_update do |delta|
11
+ unless @animation.nil?
12
+ @animation.update(delta)
13
+ begin
14
+ @target.set_image @animation.current_frame
15
+ rescue; end #deliberately swallow
16
+ end
17
+ end
18
+ @mode = :normal
19
+ end
20
+
21
+ def sprites(*sprite_names)
22
+ sprite_names.each do |sprite_name|
23
+ if sprite_name.kind_of? Image
24
+ @animation.add_frame(sprite_name, 1000)
25
+ else
26
+ @animation.add_frame(Image.new("data/#{sprite_name}"), 1000)
27
+ end
28
+ end
29
+ @target.set_image @animation.current_frame
30
+ end
31
+ alias_method :set_sprites, :sprites
32
+
33
+ def animation_fps(fps)
34
+ @fps = fps
35
+ (0...@animation.frame_count).each {|i| @animation.set_duration(i, 1000.0/@fps)}
36
+ end
37
+
38
+ def animation_mode(mode)
39
+ case mode
40
+ when :normal
41
+ @animation.looping = false
42
+ @animation.ping_pong = false
43
+ when :looping
44
+ @animation.looping = true
45
+ @animation.ping_pong = false
46
+ when :ping_pong
47
+ @animation.looping = true
48
+ @animation.ping_pong = true
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,11 @@
1
+ class Audible < Gemini::Behavior
2
+
3
+ def load_sound(reference, path)
4
+ @target.game_state.manager(:sound).add_sound(reference, path)
5
+ end
6
+
7
+ def emit_sound(reference, volume = 1.0, pitch = 1.0)
8
+ @target.game_state.manager(:sound).play_sound(reference, volume, pitch)
9
+ end
10
+
11
+ end
@@ -0,0 +1,33 @@
1
+ class AxisStateful < Gemini::Behavior
2
+ class AxialStateTransferEvent
3
+ attr_accessor :before_state, :after_state, :axis
4
+ def initialize(axis, before_state, after_state)
5
+ @axis = axis
6
+ @before_state = before_state
7
+ @after_state = after_state
8
+ end
9
+ end
10
+
11
+ attr_accessor :default_state_on_axis, :current_state_on_axis
12
+ wrap_with_callbacks :transfer_state_on_axis
13
+
14
+ def load
15
+ @state_transitions = {}
16
+ @target.enable_listeners_for :axis_state_transfer_accepted
17
+ @target.enable_listeners_for :axis_state_transfer_rejected
18
+ end
19
+
20
+ def set_state_transisions_on_axis(axis, transitions)
21
+ @state_transitisions[axis] = transitions
22
+ end
23
+
24
+ def transfer_state_on_axis(axis, state)
25
+ event = AxialStateTransferEvent.new(axis, @current_state[axis], state)
26
+ if @state_transitions[axis][@current_state[axis]].include? state
27
+ @current_state = state
28
+ notify :axis_state_transfer_accepted, event
29
+ else
30
+ notify :axis_state_transfer_rejected, event
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,56 @@
1
+ # Simplistic implementation of a big image to be used as a background image
2
+ require 'behaviors/drawable'
3
+
4
+ class BigSprite < Drawable
5
+ include_class 'org.newdawn.slick.BigImage'
6
+ attr_accessor :image
7
+ depends_on :Spatial
8
+ attr_accessor :image, :color, :texture_coords, :image_size
9
+ alias_method :set_image_size, :image_size=
10
+
11
+ def load
12
+ @color = Color.new(1.0, 1.0, 1.0, 1.0)
13
+ @texture_coords = [Vector.new(0.0, 0.0), Vector.new(1.0, 1.0)]
14
+ end
15
+
16
+ def draw(graphics)
17
+ half_width = @image.width / 2
18
+ half_height = @image.height / 2
19
+ center_x = @target.x - half_width
20
+ center_y = @target.y - half_height
21
+ #puts "drawing with rotation: #{@image.rotation}"
22
+ unless 0 == @image.rotation
23
+ graphics.rotate @target.x, @target.y, @image.rotation
24
+ end
25
+ @image.draw(center_x, center_y, @target.x + half_width, @target.y + half_height,
26
+ @texture_coords[0].x * @image.width, @texture_coords[0].y * @image.height, @texture_coords[1].x * @image.width, @texture_coords[1].y * @image.height,
27
+ @color.native_color)
28
+ graphics.reset_transform
29
+ end
30
+
31
+ def move_by_top_left(move_x_or_vector, move_y = nil)
32
+ half_width = @target.image_size.x / 2
33
+ half_height = @target.image_size.y / 2
34
+ if move_y.nil?
35
+ @target.move(move_x_or_vector.x + half_width, move_x_or_vector.y + half_height)
36
+ else
37
+ @target.move(move_x_or_vector + half_width, move_y + half_height)
38
+ end
39
+ end
40
+
41
+ def image=(sprite_name)
42
+ if sprite_name.kind_of? BigImage
43
+ @image = sprite_name
44
+ else
45
+ begin
46
+ @image = BigImage.new("data/#{sprite_name}")
47
+ rescue java.lang.RuntimeException
48
+ @image = BigImage.new("../data/#{sprite_name}")
49
+ end
50
+ puts @image.width
51
+ puts @image.height
52
+ end
53
+ set_image_size(Vector.new(@image.width, @image.height))
54
+ end
55
+ alias_method :set_image, :image=
56
+ end
@@ -0,0 +1,25 @@
1
+ require 'behavior_event'
2
+ include_class 'org.newdawn.slick.geom.Rectangle'
3
+
4
+ class BoundingBoxCollidable < Gemini::Behavior
5
+ depends_on :Spatial2d
6
+
7
+ def load
8
+ @target.enable_listeners_for :collided
9
+ end
10
+
11
+ def collision_check(collidable)
12
+ return if self == collidable || @target == collidable
13
+
14
+ notify :collided, BoundingBoxCollisionEvent.new(@target, collidable) if bounds.intersects(collidable.bounds)
15
+ end
16
+ end
17
+
18
+ class BoundingBoxCollisionEvent < Gemini::BehaviorEvent
19
+ attr_accessor :colliding_object, :collided_object
20
+
21
+ def load(source, other)
22
+ @colliding_object = source
23
+ @collided_object = other
24
+ end
25
+ end
@@ -0,0 +1,20 @@
1
+ # These are sprites that deliberately ignore the scrolling of the render manager.
2
+ class CameraAnchoredDrawable < Gemini::Behavior
3
+ #TODO: Change this to Drawable when the engine supports overriding declared methods (such as draw)
4
+ depends_on :Sprite
5
+
6
+ def load
7
+ @target.on_before_draw do
8
+ @render_manager = @target.game_state.manager(:render)
9
+ return unless @render_manager.kind_of? ScrollingRenderManager
10
+ @camera_position = @render_manager.camera_position
11
+ @render_manager.renderer.gl_translatef(-@camera_position.x, -@camera_position.y, 0.0)
12
+ end
13
+
14
+ @target.on_after_draw do
15
+ return unless @render_manager
16
+ @render_manager.renderer.gl_translatef(@camera_position.x, @camera_position.y, 0.0)
17
+ @camera_position = nil
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,114 @@
1
+ # A CardinalMovable can move north, east, south and west.
2
+ # Movement along certain axis can be constrained, for example, pong has horizonal (north/east)
3
+ # movement constrained
4
+ # TODO: Allow disabling of diaganol easily
5
+ # TODO: Allow disabling of directions
6
+ # TODO: Allow speed limit per axis
7
+ # TODO: Allow speed limit per direction
8
+ class CardinalMovable < Gemini::Behavior
9
+ NORTH = :north
10
+ EAST = :east
11
+ SOUTH = :south
12
+ WEST = :west
13
+ NORTH_EAST = :north_east
14
+ SOUTH_EAST = :south_east
15
+ SOUTH_WEST = :south_west
16
+ NORTH_WEST = :north_west
17
+ DIAGONOL_DIRECTIONS = [NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST]
18
+ CARDINAL_DIRECTIONS = [NORTH, EAST, SOUTH, WEST] + DIAGONOL_DIRECTIONS
19
+ DIRECTION_TRANSLATION_IN_DEGREES = []
20
+
21
+ depends_on :Tangible
22
+ depends_on :ReceivesEvents
23
+ attr_accessor :facing_direction
24
+ #TODO: Rename to cardinal facing direction
25
+ wrap_with_callbacks :facing_direction=, :set_facing_drection
26
+
27
+ def load
28
+ @facing_direction = NORTH
29
+ @allowed_directions = CARDINAL_DIRECTIONS.dup
30
+ # @cardinal_speed = 25
31
+ end
32
+
33
+ # direct input events here to keep "pushing".
34
+ # TODO: After the update, clear the directions.
35
+ def set_cardinal_movement_for_update(directions)
36
+
37
+ end
38
+
39
+ def facing_direction=(direction)
40
+ if @allowed_directions.include? direction
41
+ if @moving && orthogonal_directions?(@facing_direction, direction)
42
+ diagonol_direction = begin
43
+ "#{self.class}::#{@facing_direction.to_s.upcase}_#{direction.to_s.upcase}".constantize
44
+ rescue
45
+ "#{self.class}::#{direction.to_s.upcase}_#{@facing_direction.to_s.upcase}".constantize
46
+ end
47
+ @facing_direction = diagonol_direction
48
+ else
49
+ @facing_direction = direction
50
+ end
51
+ end
52
+ end
53
+ alias_method :set_facing_direction, :facing_direction=
54
+
55
+ def constrain_direction(directions)
56
+ directions = [directions] unless directions.kind_of? Array
57
+ directions.each
58
+ directions.each { |direction| @allowed_directions.delete direction }
59
+ end
60
+
61
+ def begin_cardinal_movement(message)
62
+ direction = message.value
63
+ return unless @allowed_directions.include? direction
64
+ set_facing_direction direction
65
+ @moving = true
66
+ @cardinal_velocity = direction_to_polar_vector(@facing_direction)
67
+ end
68
+
69
+ def end_cardinal_movement(message)
70
+ direction = message.value
71
+ @facing_direction = other_direction(@facing_direction, direction) if diagonol_direction? @facing_direction
72
+ if @facing_direction == direction
73
+ @cardinal_velocity = Vector.new(0,0)
74
+ @moving = false
75
+ else
76
+ @cardinal_velocity = direction_to_polar_vector(@facing_direction)
77
+ end
78
+ end
79
+
80
+ def direction_to_polar_vector(direction)
81
+ angle = case direction
82
+ when NORTH
83
+ 0
84
+ when NORTH_EAST
85
+ 45
86
+ when EAST
87
+ 90
88
+ when SOUTH_EAST
89
+ 135
90
+ when SOUTH
91
+ 180
92
+ when SOUTH_WEST
93
+ 225
94
+ when WEST
95
+ 270
96
+ when NORTH_WEST
97
+ 315
98
+ end
99
+ Vector.from_polar_vector(@cardinal_speed, angle)
100
+ end
101
+
102
+ def diagonol_direction?(direction)
103
+ DIAGONOL_DIRECTIONS.include? direction
104
+ end
105
+
106
+ def other_direction(diagonol_direction, direction)
107
+ diagonol_direction.to_s.sub(direction.to_s, '').sub('_', '').to_sym
108
+ end
109
+
110
+ def orthogonal_directions?(direction_a, direction_b)
111
+ ([NORTH, SOUTH].include?(direction_a) && [EAST, WEST].include?(direction_b)) ||
112
+ ([NORTH, SOUTH].include?(direction_b) && [EAST, WEST].include?(direction_a))
113
+ end
114
+ end
@@ -0,0 +1,18 @@
1
+ class Clickable < Gemini::Behavior
2
+ depends_on :ReceivesEvents
3
+ depends_on :Regional
4
+ wrap_with_callbacks :pressed, :released
5
+
6
+ def load
7
+ @target.handle_event :mouse_button1_pressed do |mouse_event|
8
+ pressed if @target.within_region? mouse_event.value.location
9
+ end
10
+
11
+ @target.handle_event :mouse_button1_released do |mouse_event|
12
+ released if @target.within_region? mouse_event.value.location
13
+ end
14
+ end
15
+
16
+ def pressed; end
17
+ def released; end
18
+ end
@@ -0,0 +1,31 @@
1
+ class Countable < Gemini::Behavior
2
+ attr_accessor :count
3
+ wrap_with_callbacks :count=
4
+
5
+ def load
6
+ @count = 0
7
+ @target.enable_listeners_for :incremented
8
+ @target.enable_listeners_for :decremented
9
+ end
10
+
11
+ def count=(count)
12
+ comparison = @count <=> count
13
+ @count = count
14
+ case comparison
15
+ when -1
16
+ @target.notify :decremented
17
+ when 0
18
+ # do nothing
19
+ when 1
20
+ @target.notify :incremented
21
+ end
22
+ end
23
+
24
+ def decrement
25
+ self.count = count - 1
26
+ end
27
+
28
+ def increment
29
+ self.count = count + 1
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ class DebugPhysical < Gemini::Behavior #Drawable
2
+ #declared_methods :draw
3
+ PhysVector = Java::net::phys2d::math::Vector2f
4
+ SlickVector = Java::org::newdawn::slick::geom::Vector2f
5
+
6
+ def load
7
+ @target.game_state.manager(:render).on_after_render do |graphics|
8
+ draw(graphics)
9
+ end
10
+ end
11
+
12
+ def unload
13
+ # Remove listener for after render
14
+ end
15
+
16
+ def draw(graphics)
17
+ #TODO: Support joints and composite bodies(?)
18
+ body = @target.instance_variable_get(:@__behaviors)[:Physical].instance_variable_get(:@body)
19
+ physics_shape = body.shape
20
+ graphics_shape = if physics_shape.kind_of?(Java::net::phys2d::raw::shapes::Box)
21
+ Java::org.newdawn.slick.geom.Polygon.new(physics_shape.get_points(body.position, body.rotation).map{|point| [point.x, point.y]}.flatten.to_java(:float))
22
+ elsif physics_shape.kind_of?(Java::net.phys2d.raw.shapes.Polygon)
23
+ Java::org.newdawn.slick.geom.Polygon.new(physics_shape.get_vertices(body.position, body.rotation).map{|point| [point.x, point.y]}.flatten.to_java(:float))
24
+ elsif physics_shape.kind_of? Java::net.phys2d.raw.shapes.Circle
25
+ Java::org.newdawn.slick.geom.Circle.new(body.position.x, body.position.y, physics_shape.radius)
26
+ else
27
+ raise "#{self.class} does not know how to draw the shape #{physics_shape.class}"
28
+ end
29
+ graphics.draw(graphics_shape)
30
+ end
31
+ end
@@ -0,0 +1,30 @@
1
+ class DebugTangible < Gemini::Behavior #Drawable
2
+ #declared_methods :draw
3
+ PhysVector = Java::net::phys2d::math::Vector2f
4
+ SlickVector = Java::org::newdawn::slick::geom::Vector2f
5
+
6
+ def load
7
+ @target.game_state.manager(:render).on_after_render do |graphics|
8
+ draw(graphics)
9
+ end
10
+ end
11
+
12
+ def unload
13
+ # Remove listener for after render
14
+ end
15
+
16
+ def draw(graphics)
17
+ #TODO: Support joints and composite bodies(?)
18
+ tangible_shape = @target.instance_variable_get(:@__behaviors)[:Tangible].instance_variable_get(:@tangible_shape)
19
+ graphics_shape = if tangible_shape.kind_of? TangibleBox
20
+ Java::org.newdawn.slick.geom.Polygon.new(tangible_shape.get_points(@target.top_left_position, 0).map{|point| [point.x, point.y]}.flatten.to_java(:float))
21
+ # elsif tangible_shape.kind_of?(Java::net.phys2d.raw.shapes.Polygon)
22
+ # Java::org.newdawn.slick.geom.Polygon.new(tangible_shape.get_vertices(body.position, body.rotation).map{|point| [point.x, point.y]}.flatten.to_java(:float))
23
+ # elsif tangible_shape.kind_of? Java::net.phys2d.raw.shapes.Circle
24
+ # Java::org.newdawn.slick.geom.Circle.new(body.position.x, body.position.y, tangible_shape.radius)
25
+ else
26
+ raise "#{self.class} does not know how to draw the shape #{tangible_shape.class}"
27
+ end
28
+ graphics.draw(graphics_shape)
29
+ end
30
+ end
@@ -0,0 +1,6 @@
1
+ class Drawable < Gemini::Behavior
2
+ depends_on_kind_of :Spatial
3
+ wrap_with_callbacks :draw
4
+
5
+ def draw(graphics); end
6
+ end