jemini 2009.10.27

Sign up to get free protection for your applications and to get access to all the features.
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,111 @@
1
+ # A CardinalMovable that interacts with the physics manager.
2
+ # See the API for CardinalMovable for method descriptions.
3
+ # TODO: Allow disabling of diaganol easily
4
+ # TODO: Allow disabling of directions
5
+ # TODO: Allow speed limit per axis
6
+ # TODO: Allow speed limit per direction
7
+ class PhysicalCardinalMovable < Jemini::Behavior
8
+ NORTH = :north
9
+ EAST = :east
10
+ SOUTH = :south
11
+ WEST = :west
12
+ NORTH_EAST = :north_east
13
+ SOUTH_EAST = :south_east
14
+ SOUTH_WEST = :south_west
15
+ NORTH_WEST = :north_west
16
+ DIAGONAL_DIRECTIONS = [NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST]
17
+ CARDINAL_DIRECTIONS = [NORTH, EAST, SOUTH, WEST] + DIAGONAL_DIRECTIONS
18
+ DIRECTION_TRANSLATION_IN_DEGREES = []
19
+
20
+ depends_on :Physical
21
+ depends_on :HandlesEvents
22
+ attr_accessor :facing_direction
23
+ wrap_with_callbacks :facing_direction=, :set_facing_drection
24
+
25
+ def load
26
+ @facing_direction = NORTH
27
+ @allowed_directions = CARDINAL_DIRECTIONS.dup
28
+ @cardinal_speed = 25
29
+ @game_object.on_update do
30
+ @game_object.add_velocity @cardinal_velocity if @moving
31
+ end
32
+ end
33
+
34
+ def facing_direction=(direction)
35
+ if @allowed_directions.include? direction
36
+ if @moving && orthogonal_directions?(@facing_direction, direction)
37
+ diagonal_direction = begin
38
+ "#{self.class}::#{@facing_direction.to_s.upcase}_#{direction.to_s.upcase}".constantize
39
+ rescue
40
+ "#{self.class}::#{direction.to_s.upcase}_#{@facing_direction.to_s.upcase}".constantize
41
+ end
42
+ @facing_direction = diagonal_direction
43
+ else
44
+ @facing_direction = direction
45
+ end
46
+ end
47
+ end
48
+ alias_method :set_facing_direction, :facing_direction=
49
+
50
+ def constrain_direction(directions)
51
+ directions = [directions] unless directions.kind_of? Array
52
+ directions.each
53
+ directions.each { |direction| @allowed_directions.delete direction }
54
+ end
55
+
56
+ def begin_cardinal_movement(message)
57
+ direction = message.value
58
+ return unless @allowed_directions.include? direction
59
+ set_facing_direction direction
60
+ @moving = true
61
+ @cardinal_velocity = direction_to_polar_vector(@facing_direction)
62
+ end
63
+
64
+ def end_cardinal_movement(message)
65
+ direction = message.value
66
+ @facing_direction = other_direction(@facing_direction, direction) if diagonal_direction? @facing_direction
67
+ if @facing_direction == direction
68
+ @cardinal_velocity = Vector.new(0,0)
69
+ @moving = false
70
+ else
71
+ @cardinal_velocity = direction_to_polar_vector(@facing_direction)
72
+ end
73
+ end
74
+
75
+ private
76
+
77
+ def direction_to_polar_vector(direction)
78
+ angle = case direction
79
+ when NORTH
80
+ 0
81
+ when NORTH_EAST
82
+ 45
83
+ when EAST
84
+ 90
85
+ when SOUTH_EAST
86
+ 135
87
+ when SOUTH
88
+ 180
89
+ when SOUTH_WEST
90
+ 225
91
+ when WEST
92
+ 270
93
+ when NORTH_WEST
94
+ 315
95
+ end
96
+ Vector.from_polar_vector(@cardinal_speed, angle)
97
+ end
98
+
99
+ def diagonal_direction?(direction)
100
+ DIAGONAL_DIRECTIONS.include? direction
101
+ end
102
+
103
+ def other_direction(diagonal_direction, direction)
104
+ diagonal_direction.to_s.sub(direction.to_s, '').sub('_', '').to_sym
105
+ end
106
+
107
+ def orthogonal_directions?(direction_a, direction_b)
108
+ ([NORTH, SOUTH].include?(direction_a) && [EAST, WEST].include?(direction_b)) ||
109
+ ([NORTH, SOUTH].include?(direction_b) && [EAST, WEST].include?(direction_a))
110
+ end
111
+ end
@@ -0,0 +1,45 @@
1
+ #Gives an object a bitmap that responds appropriately to the physics engine.
2
+ class PhysicalImage < Jemini::Behavior
3
+ depends_on :DrawableImage
4
+ depends_on :Physical
5
+ attr_accessor :tiled_to_bounds
6
+ alias_method :set_tiled_to_bounds, :tiled_to_bounds=
7
+
8
+ def load
9
+ @game_object.on_before_draw :draw_physical_image
10
+ @offset_position = Vector.new
11
+ @offset_rotation = 0.0
12
+ end
13
+
14
+ def bounded_image=(new_image)
15
+ @game_object.set_image new_image
16
+ @game_object.set_shape(:Box, @game_object.image_size.x, @game_object.image_size.y)
17
+ end
18
+ alias_method :set_bounded_image, :bounded_image=
19
+
20
+ def tiled_to_bounds=(state)
21
+ @tiled_to_bounds = state
22
+ @game_object.image_size = @game_object.box_size
23
+ end
24
+
25
+ def physical_image_position_offset=(offset)
26
+ @offset_position = offset.dup
27
+ end
28
+ alias_method :set_physical_image_position_offset, :physical_image_position_offset=
29
+
30
+ def physical_image_rotation_offset=(offset)
31
+ @offset_rotation = offset
32
+ end
33
+ alias_method :set_physical_image_rotation_offset, :physical_image_rotation_offset=
34
+
35
+ def draw_physical_image(graphics)
36
+ @game_object.image_rotation = @game_object.physical_rotation unless @game_object.image.nil?
37
+ #TODO: Only execute this if the shape is bound to the image.
38
+ #TODO: Call raw_move instead of x= and y=
39
+ position = @game_object.body_position
40
+
41
+ offset = Vector::ORIGIN.pivot_around_degrees(@offset_position, @game_object.physical_rotation + @offset_rotation)
42
+ @game_object.x = position.x + offset.x
43
+ @game_object.y = position.y + offset.y
44
+ end
45
+ end
@@ -0,0 +1,30 @@
1
+ #Makes an object move with the mouse.
2
+ class Pointer < Jemini::Behavior
3
+ depends_on :DrawableImage
4
+ # depends_on :Movable2d
5
+ # depends_on :CollisionPoolAlgorithmTaggable
6
+ # depends_on :WorldCollidable
7
+ depends_on :HandlesEvents
8
+
9
+
10
+ def load
11
+ # add_tag :ui, :gui, :pointer
12
+ # collides_with_tags :gui, :clickable
13
+ #
14
+ @game_object.handle_event :mouse_move do |message|
15
+ mouse_movement(message)
16
+ end
17
+ # handle_event :start_click, :start_click
18
+ # handle_event :stop_click, :stop_click
19
+
20
+ # listen_for(:collided) do |event, continue|
21
+ # event.collided_object.click if event.collided_object.respond_to? :click
22
+ # end
23
+ end
24
+
25
+ #Takes a message with a Vector indicating the x/y coordinates to move the object to.
26
+ def mouse_movement(message)
27
+ vector = message.value
28
+ @game_object.move(vector.location.x, vector.location.y)
29
+ end
30
+ end
@@ -0,0 +1,17 @@
1
+ #Makes an object change appearance when clicked.
2
+ class Pressable < Jemini::Behavior
3
+ depends_on :DrawableImage
4
+ depends_on :Clickable
5
+
6
+ def load
7
+ add_tag :button, :gui, :ui
8
+ end
9
+
10
+ #Takes a hash with the following keys and values:
11
+ #[:normal] The path for the image to display when the object is not pressed.
12
+ #[:pressed] The path for the image to display when the object is pressed.
13
+ def images=(image_path_hash)
14
+ @normal_image = image_path_hash[:normal]
15
+ @pressed_image = image_path_hash[:pressed]
16
+ end
17
+ end
@@ -0,0 +1,76 @@
1
+ require 'set'
2
+
3
+ #Indicates that the receiver has entered/exited an area.
4
+ class RegionalTransitionEvent
5
+ attr_accessor :region, :spatial
6
+ def initialize(region, spatial)
7
+ @region = region
8
+ @spatial = spatial
9
+ end
10
+ end
11
+
12
+ #Makes an object receive a RegionalTransitionEvent whenever it enters/exits a given area.
13
+ class Regional < Jemini::Behavior
14
+ depends_on :Spatial
15
+ attr_accessor :dimensions, :region_shape
16
+ alias_method :set_dimensions, :dimensions=
17
+ alias_method :set_region_shape, :region_shape=
18
+
19
+ # This is bad. We need a real collision system
20
+ def load
21
+ @game_object.enable_listeners_for :entered_region, :exited_region
22
+ @game_object.move(0,0)
23
+ @dimensions = Vector.new(1,1)
24
+ @last_spatials_within = []
25
+ @last_spatials_without = nil
26
+ @last_spatials = []
27
+ #TODO: SAVE: This should be turned on when requested.
28
+ # game_state.manager(:update).on_update do
29
+ # spatials = game_state.manager(:game_object).game_objects.select {|game_object| game_object.kind_of? Tangible}.compact
30
+ #
31
+ # spatials_within, spatials_without = spatials.partition {|spatial| within_region?(spatial)}
32
+ # (spatials_within - @last_spatials_within).each do |spatial_within|
33
+ # @game_object.notify :entered_region, RegionalTransitionEvent.new(self, spatial_within) if existed_last_update? spatial_within
34
+ # end
35
+ # @last_spatials_within = spatials_within
36
+ #
37
+ # unless @last_spatials_without.nil?
38
+ # (spatials_without - @last_spatials_without).each do |spatial_without|
39
+ # @game_object.notify :exited_region, RegionalTransitionEvent.new(self, spatial_without) if existed_last_update? spatial_without
40
+ # end
41
+ # end
42
+ # @last_spatials_without = spatials_without
43
+ # @last_spatials = spatials
44
+ # end
45
+ end
46
+
47
+ #Indicates whether the given point is within the region's boundaries.
48
+ def within_region?(spatial)
49
+ half_width = dimensions.x / 2.0
50
+ half_height = dimensions.y / 2.0
51
+ ((@game_object.x - half_width) < spatial.x) && ((@game_object.x + half_width) > spatial.x) &&
52
+ ((@game_object.y - half_height) < spatial.y) && ((@game_object.y + half_height) > spatial.y)
53
+ end
54
+
55
+ #Indicates whether the given object existed on the previous world update.
56
+ #If not, it should not be considered for collision events on this update.
57
+ def existed_last_update?(game_object)
58
+ @last_spatials.find {|previous_game_object| game_object == previous_game_object}
59
+ end
60
+
61
+ def toggle_debug_mode
62
+ @debug_mode = !@debug_mode
63
+ if @debug_mode
64
+ game_state.manager(:render).on_before_render do |graphics|
65
+ old_color = graphics.color
66
+ graphics.color = Color.new(0.0, 1.0, 0.0, 0.3).native_color
67
+ half_width = dimensions.x / 2.0
68
+ half_height = dimensions.y / 2.0
69
+ graphics.fill_rect(@game_object.x - half_width, @game_object.y - half_height, dimensions.x, dimensions.y)
70
+ graphics.color = old_color
71
+ end
72
+ else
73
+ game_state.manager(:render).remove_before_draw self
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,19 @@
1
+ # This behavior rotates to face the tracking point or game object.
2
+ class RotatesToPoint < Jemini::Behavior
3
+ #TODO: Add offset rotation
4
+ depends_on :Physical
5
+ attr_accessor :rotation_target
6
+ alias_method :set_rotation_target, :rotation_target=
7
+
8
+ def load
9
+ @game_object.on_update do
10
+ @game_object.set_rotation rotation_to_face_target if @rotation_target
11
+ end
12
+ end
13
+
14
+ #The angle that the object must turn to face the rotation_target.
15
+ def rotation_to_face_target
16
+ #TODO: Use vector
17
+ diff_angle = Jemini::Math.radians_to_degrees Math.atan2(@game_object.y - @rotation_target.y, @game_object.x - @rotation_target.x)
18
+ end
19
+ end
@@ -0,0 +1,43 @@
1
+ #Gives an object x/y coordinates.
2
+ class Spatial < Jemini::Behavior
3
+ wrap_with_callbacks :position=
4
+ attr_accessor :position
5
+
6
+ alias_method :set_position, :position=
7
+
8
+
9
+ def load
10
+ @position = Vector.new(0,0)
11
+ end
12
+
13
+ def x
14
+ @position.x
15
+ end
16
+
17
+ def y
18
+ @position.y
19
+ end
20
+
21
+ def x=(x)
22
+ @position.x = x
23
+ end
24
+
25
+ def y=(y)
26
+ @position.y = y
27
+ end
28
+
29
+ #Takes a Vector or x/y coordinates to move to.
30
+ # def move(x_or_other, y=nil)
31
+ # if y.nil?
32
+ # #TODO: Determine if Spatial should really suppor this behavior.
33
+ # # use case: Pipe a mouse move event directly to move
34
+ # if x_or_other.kind_of? Jemini::Message
35
+ # @position = Vector.new(x_or_other.value.x, x_or_other.value.y)
36
+ # else
37
+ # @position = Vector.new(x_or_other.x, x_or_other.y)
38
+ # end
39
+ # else
40
+ # @position = Vector.new(x_or_other, y)
41
+ # end
42
+ # end
43
+ end
@@ -0,0 +1,33 @@
1
+
2
+ # Makes an object transition between states.
3
+ # Notes from Logan:
4
+ # I started on this behavior, and realized what I needed was multiple axises of states for my behavior
5
+ # that I wanted to use Stateful in. This behavior is simple, and seems like it would be useful for some cases.
6
+ # Thus, the behavior remains, but it is not tested or used at the time of this comment.
7
+ class Stateful < Jemini::Behavior
8
+ class StateTransferEvent
9
+ attr_accessor :before_state, :after_state
10
+ def initialize(before_state, after_state)
11
+ @before_state = before_state
12
+ @after_state = after_state
13
+ end
14
+ end
15
+ attr_accessor :default_state, :current_state
16
+ wrap_with_callbacks :transfer_state
17
+
18
+ def load
19
+ @state_transitions = {}
20
+ @game_object.enable_listeners_for :state_transfer_accepted
21
+ @game_object.enable_listeners_for :state_transfer_rejected
22
+ end
23
+
24
+ def transfer_state(state)
25
+ event = StateTransferEvent.new(@current_state, state)
26
+ if @state_transitions[@current_state].include? state
27
+ @current_state = state
28
+ notify :state_transfer_accepted, event
29
+ else
30
+ notify :state_transfer_rejected, event
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,28 @@
1
+ #Allows an object to be categorized.
2
+ class Taggable < Jemini::Behavior
3
+
4
+ def load
5
+ @tags = []
6
+ @game_object.enable_listeners_for :tag_added, :tag_removed
7
+ end
8
+
9
+ def add_tag(*tags)
10
+ new_tags = tags - @tags
11
+ @tags.concat new_tags
12
+ new_tags.each { |tag| @game_object.notify :tag_added, tag }
13
+ end
14
+
15
+ def remove_tag(*tags)
16
+ tags_to_remove = @tags & tags
17
+ @tags -= tags_to_remove
18
+ tags_to_remove.each {|tag| @game_object.notify :tag_removed, tag}
19
+ end
20
+
21
+ def has_tag?(*tags)
22
+ tags.any? {|tag| @tags.member?(tag) }
23
+ end
24
+
25
+ def tags
26
+ @tags.clone
27
+ end
28
+ end
@@ -0,0 +1,59 @@
1
+ #A shape used to determine if one object collides with another.
2
+ class TangibleBox
3
+ attr_accessor :size
4
+ def get_points(top_left_position, rotation)
5
+ top_left = top_left_position
6
+ top_right = Vector.new(top_left_position.x + size.x, top_left_position.y)
7
+ bottom_left = Vector.new(top_left_position.x, top_left_position.y + size.y)
8
+ bottom_right = Vector.new(top_left_position.x + size.x, top_left_position.y + size.y)
9
+ [top_left, top_right, bottom_right, bottom_left]
10
+ end
11
+ end
12
+
13
+ #Allows an object to indicate when it collides with another.
14
+ class Tangible < Jemini::Behavior
15
+ depends_on :Spatial
16
+ attr_reader :tangible_shape
17
+
18
+ def load
19
+ @game_object.enable_listeners_for :tangible_collision
20
+ end
21
+
22
+ def tangible_debug_mode=(mode)
23
+ if mode
24
+ @game_object.add_behavior :DebugTangible
25
+ else
26
+ @game_object.remove_behavior :DebugTangible
27
+ end
28
+ end
29
+ alias_method :set_tangible_debug_mode, :tangible_debug_mode=
30
+
31
+ #Set the shape of the object as seen by collision calculations.
32
+ #call-seq:
33
+ #set_shape(:Box, vector)
34
+ #set_shape(:Box, width, height)
35
+ #
36
+ def set_tangible_shape(name, *args)
37
+ @tangible_shape = case name
38
+ when :Box
39
+ box = TangibleBox.new
40
+ if args.size == 1
41
+ box.size = args[0]
42
+ else
43
+ box.size = Vector.new(args[0], args[1])
44
+ end
45
+ box
46
+ end
47
+ end
48
+
49
+ #Indicates whether this object collides with the given object.
50
+ def tangibly_collides_with?(other_tangible)
51
+ #TODO: top_left isn't on spatial...
52
+ other_shape = other_tangible.tangible_shape
53
+
54
+ ((@game_object.x <= other_tangible.x && (@game_object.x + @tangible_shape.size.x) >= other_tangible.x) ||
55
+ ( @game_object.x >= other_tangible.x && @game_object.x <= (other_tangible.x + other_shape.size.x))) &&
56
+ ((@game_object.y <= other_tangible.y && (@game_object.y + @tangible_shape.size.y) >= other_tangible.y) ||
57
+ ( @game_object.y >= other_tangible.y && @game_object.y <= (other_tangible.y + other_shape.size.y)))
58
+ end
59
+ end