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,43 @@
1
+ require 'behaviors/drawable'
2
+
3
+ class DrawableShape < Drawable
4
+ include_class 'org.newdawn.slick.geom.Vector2f'
5
+ include_class 'org.newdawn.slick.geom.Polygon'
6
+ depends_on :Spatial
7
+ attr_accessor :color, :image
8
+ attr_reader :visual_shape
9
+
10
+ def load
11
+ $u = 0.0
12
+ $v = 0.0
13
+ end
14
+
15
+ def set_visual_shape(shape, *params)
16
+ if shape == :polygon || shape == :Polygon
17
+ @visual_shape = "#{self.class}::#{shape}".constantize.new
18
+ params.each do |vector|
19
+ @visual_shape.add_point vector.x, vector.y
20
+ end
21
+ else
22
+ @visual_shape = ("DrawableShape::"+ shape.to_s).constantize.new(params)
23
+ end
24
+ end
25
+
26
+ def image=(image)
27
+ @image = image
28
+ puts "width: #{@image.width}, height: #{@image.height}"
29
+ puts "width / screen width: #{@image.width.to_f / @target.game_state.screen_width.to_f}"
30
+ puts "1/width: #{1.0 / @image.width.to_f}"
31
+ end
32
+ alias_method :set_image, :image=
33
+
34
+ def draw(graphics)
35
+ if @visual_shape.kind_of? Polygon
36
+ #TODO: Tweak these values!!!!
37
+ #@image.width.to_f / @target.game_state.screen_width.to_f, @image.height.to_f / @target.game_state.screen_height.to_f
38
+ graphics.texture @visual_shape, @image, 1.0 / @image.width.to_f, 1.0 / @image.height.to_f
39
+ else
40
+ raise "#{@visual_shape.class} is not supported"
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,28 @@
1
+ class FadingImageTrailEmittable < Gemini::Behavior
2
+ depends_on :Updates
3
+
4
+ def load
5
+ @fading_image_offset = Vector.new(0,0)
6
+ @move_threshold = 4
7
+ @move_count = 0
8
+ @seconds_to_fade_away = 2
9
+ @target.on_update do
10
+ @move_count += 1
11
+ if @move_count >= @move_threshold
12
+ fading_image = @target.game_state.create_game_object :FadingImage, @image, Color.new(:white), @seconds_to_fade_away
13
+ #center_position = @target.center_position
14
+ fading_image.move(@fading_image_offset.x + @target.x, @fading_image_offset.y + @target.y)
15
+ @move_count = 0
16
+ end
17
+ end
18
+ end
19
+
20
+ def emit_fading_image(image)
21
+ @image = image
22
+ end
23
+
24
+ def emit_fading_image_trail_from_offset(offset)
25
+ @fading_image_offset = offset
26
+ end
27
+
28
+ end
@@ -0,0 +1,12 @@
1
+ class GameObjectEmittable < Gemini::Behavior
2
+ attr_accessor :emitting_game_object_name
3
+ alias_method :set_emitting_game_object_name, :emitting_game_object_name=
4
+ def load
5
+ @target.enable_listeners_for :emit_game_object
6
+ end
7
+
8
+ def emit_game_object(message=nil)
9
+ game_object = @target.game_state.create_game_object @emitting_game_object_name
10
+ @target.notify :emit_game_object, game_object
11
+ end
12
+ end
@@ -0,0 +1,21 @@
1
+ # Enables game objects to attract other Physical game objects towards it
2
+ class GravitySource < Gemini::Behavior
3
+ depends_on :Physical
4
+
5
+ attr_accessor :gravity
6
+ alias_method :set_gravity, :gravity=
7
+
8
+ def load
9
+ @gravity = 0
10
+ @target.on_update do |delta|
11
+ physicals = @target.game_state.manager(:game_object).game_objects.select {|game_object| game_object.kind_of? Physical}.compact
12
+ physicals.each do |physical|
13
+ next if @target == physical
14
+ distance = @target.position.distance_from physical
15
+ force = delta * @gravity / (distance * Gemini::Math::SQUARE_ROOT_OF_TWO)
16
+ gravitation = Vector.from_polar_vector(force, @target.position.angle_from(physical))
17
+ physical.add_force gravitation
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,11 @@
1
+ class Inertial < Gemini::Behavior
2
+ depends_on :UpdatesAtConsistantRate
3
+ attr_accessor :inertia
4
+
5
+ def load
6
+ @inertia = [0,0]
7
+ @target.on_update do
8
+ move(@inertia[0] + x, @inertia[1] + y)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ class Movable2d < Gemini::Behavior
2
+ depends_on :Spatial2d
3
+ wrap_with_callbacks :move
4
+
5
+ def move(x, y)
6
+ self.x = x unless x.nil?
7
+ self.y = y unless y.nil?
8
+ end
9
+ end
@@ -0,0 +1,22 @@
1
+ class MultiAnimatedSprite < Gemini::Behavior
2
+ depends_on :AnimatedSprite
3
+
4
+ def load
5
+ @animations = {}
6
+ end
7
+
8
+ def add_animation(options)
9
+ name = options[:name]
10
+ sprites = options[:sprites]
11
+ speed = options[:speed]
12
+ sprite_images = sprites.map do |sprite_image_name|
13
+ Java::org::newdawn::slick::Image.new sprite_image_name
14
+ end
15
+ animation = Java::org::newdawn::slick::Animation.new(sprite_images.to_java(Java::org::newdawn::slick::Image), speed)
16
+ @animations[name] = animation
17
+ end
18
+
19
+ def animate(animation_name)
20
+ @target.animation = @animations[animation_name]
21
+ end
22
+ end
@@ -0,0 +1,348 @@
1
+ require 'behaviors/spatial'
2
+
3
+ class Physical < Gemini::Behavior
4
+ # TODO: Move to Math?
5
+ SQUARE_ROOT_OF_TWO = Math.sqrt(2)
6
+ INFINITE_MASS = Java::net::phys2d::raw::Body::INFINITE_MASS
7
+
8
+ include_class "net.phys2d.raw.Body"
9
+ include_class "net.phys2d.raw.shapes.Box"
10
+ include_class "net.phys2d.raw.shapes.Circle"
11
+ include_class "net.phys2d.raw.shapes.Line"
12
+ include_class "net.phys2d.raw.shapes.Polygon"
13
+ include_class "net.phys2d.raw.shapes.ConvexPolygon"
14
+ include_class "net.phys2d.math.Vector2f"
15
+ include_class 'net.phys2d.raw.AngleJoint'
16
+ include_class 'net.phys2d.raw.BasicJoint'
17
+
18
+ attr_reader :mass, :name, :shape
19
+ depends_on :Spatial
20
+ depends_on :Updates
21
+ wrap_with_callbacks :mass=
22
+
23
+ def load
24
+ @mass = 1
25
+ @shape = Box.new(1,1)
26
+ setup_body
27
+ @body.restitution = 0.0
28
+ @body.user_data = @target
29
+ @angular_damping = 0.0
30
+ @target.enable_listeners_for :physical_collided
31
+ @target.on_after_move { move @target.x , @target.y}
32
+ # Manual angular damping. New Phys2D may support this? If not, file a bug.
33
+ @target.on_update {|delta| set_angular_velocity(angular_velocity - (angular_velocity * (@angular_damping * (1.0/mass) ))) }
34
+ end
35
+
36
+ def add_excluded_physical(physical_game_object)
37
+ @body.add_excluded_body physical_game_object.instance_variable_get(:@__behaviors)[:Physical].instance_variable_get(:@body)
38
+ end
39
+
40
+ def physics_bitmask
41
+ @body.bitmask
42
+ end
43
+
44
+ def physics_bitmask=(bitmask)
45
+ @body.bitmask = bitmask
46
+ end
47
+ alias_method :set_physics_bitmask, :physics_bitmask=
48
+
49
+
50
+ def body_position
51
+ @body.position
52
+ end
53
+
54
+ def body_position=(vector)
55
+ # set_position doesn't take a vector, only x/y
56
+ @body.set_position(vector.x, vector.y)
57
+ end
58
+ alias_method :set_body_position, :body_position=
59
+
60
+ # See about Phys2D joints here: http://www.cokeandcode.com/phys2d/source/javadoc/net/phys2d/raw/Joint.html
61
+ # what do we do with the joint? Just let it die when the objects die? Makes sense to me.
62
+ # Both physicals might want to own the joint
63
+ # This seems to need more work
64
+ def join_to_physical(physical_game_object, options={})
65
+ other_body = physical_game_object.instance_variable_get(:@__behaviors)[:Physical].instance_variable_get(:@body)
66
+ case options[:joint]
67
+ when :angle
68
+ AngleJoint.new(@body, other_body, options[:self_body_point].to_phys2d_vector, options[:other_body_point].to_phys2d_vector, options[:self_body_angle], options[:other_body_angle])
69
+ when :basic
70
+ BasicJoint.new(@body, other_body, options[:anchor].to_phys2d_vector)
71
+ else
72
+ raise "Joint type #{options[:joint].inspect} not supported."
73
+ end
74
+ end
75
+
76
+ def speed_limit=(vector_or_shared_value)
77
+ if vector_or_shared_value.kind_of? Numeric
78
+ axis_limit_x = axis_limit_y = vector_or_shared_value / SQUARE_ROOT_OF_TWO
79
+ else
80
+ axis_limit_x = vector_or_shared_value.x
81
+ axis_limit_y = vector_or_shared_value.y
82
+ end
83
+ @body.set_max_velocity(axis_limit_x, axis_limit_y)
84
+ end
85
+ alias_method :set_speed_limit, :speed_limit=
86
+
87
+ # def safe_move=(safe_move)
88
+ # @safe_move = safe_move
89
+ # if safe_move
90
+ # puts "adding safe move listener"
91
+ # listen_for(:collided, @target) do
92
+ # puts "collision event"
93
+ # if @safe_move
94
+ # puts "position: #{@body.position}"
95
+ # puts "last position: #{@body.last_position}"
96
+ # #@body.set_position(@body.last_position.x, @body.last_position.y)
97
+ # puts "reseting position to #{@last_x}, #{@last_y}"
98
+ # @body.set_position(@last_x, @last_y)
99
+ # end
100
+ # end
101
+ # end
102
+ # end
103
+ # alias_method :set_safe_move, :safe_move=
104
+
105
+ def wish_move(x, y)
106
+ # WARNING: @body.last_position is not to be trusted. We'll just handle it ourselves.
107
+ @last_x = @target.x
108
+ @last_y = @target.y
109
+ @body.move(x, y)
110
+ #@body.set_position(@last_x, @last_y) if @target.game_state.manager(:physics).colliding? @body
111
+ end
112
+
113
+ def width
114
+ @body.shape.bounds.width
115
+ end
116
+
117
+ def height
118
+ @body.shape.bounds.height
119
+ end
120
+
121
+ def radius
122
+ @body.shape.radius
123
+ end
124
+
125
+ def box_size
126
+ @body.shape.size
127
+ end
128
+
129
+ def physical_rotation=(rotation)
130
+ @body.rotation = Gemini::Math.degrees_to_radians(rotation)
131
+ end
132
+ alias_method :set_physical_rotation, :physical_rotation=
133
+
134
+ def rotate_physical(degrees)
135
+ @body.adjust_rotation Gemini::Math.degrees_to_radians(degrees)
136
+ end
137
+
138
+ def physical_rotation
139
+ Gemini::Math.radians_to_degrees(@body.rotation)
140
+ end
141
+
142
+ def physical_rotatable?
143
+ @body.rotatable?
144
+ end
145
+
146
+ def physical_rotatable=(rotatable)
147
+ @body.rotatable = rotatable
148
+ end
149
+ alias_method :set_physical_rotatable, :physical_rotatable=
150
+
151
+ def add_force(x_or_vector, y = nil)
152
+ if y.nil?
153
+ @body.add_force(x_or_vector.to_phys2d_vector)
154
+ else
155
+ @body.add_force(Vector2f.new(x_or_vector, y))
156
+ end
157
+ end
158
+
159
+ def set_force(x, y)
160
+ @body.set_force(x, y)
161
+ end
162
+
163
+ def force
164
+ @body.force
165
+ end
166
+
167
+ def add_velocity(x_or_vector, y = nil)
168
+ if x_or_vector.kind_of? Vector
169
+ @body.adjust_velocity(x_or_vector.to_phys2d_vector)
170
+ else
171
+ @body.adjust_velocity(Java::net::phys2d::math::Vector2f.new(x_or_vector, y))
172
+ end
173
+ end
174
+
175
+ def velocity
176
+ @body.velocity.to_vector
177
+ end
178
+
179
+ def velocity=(vector)
180
+ @body.adjust_velocity(Java::net::phys2d::math::Vector2f.new(vector.x - @body.velocity.x, vector.y - @body.velocity.y))
181
+ end
182
+ alias_method :set_velocity, :velocity=
183
+
184
+ def angular_velocity
185
+ @body.angular_velocity
186
+ end
187
+
188
+ def angular_velocity=(delta)
189
+ @body.adjust_angular_velocity(delta - angular_velocity)
190
+ end
191
+ alias_method :set_angular_velocity, :angular_velocity=
192
+
193
+ def come_to_rest
194
+ current_velocity = @body.velocity
195
+ add_velocity(-current_velocity.x, -current_velocity.y)
196
+ set_angular_velocity(0)
197
+ @body.is_resting = true
198
+ end
199
+
200
+ # numbers or :infinite
201
+ def mass=(mass)
202
+ @mass = mass
203
+ x, y = @target.x, @target.y
204
+ @mass = @mass.kind_of?(Symbol) ? INFINITE_MASS : @mass
205
+ @body.set(@shape, @mass)
206
+ # TODO: Consider moving to set_shape
207
+ # A body's position is lost when it moves, reset the position to where it was
208
+ @body.move x, y
209
+ end
210
+ alias_method :set_mass, :mass=
211
+
212
+ def restitution
213
+ @body.restitution
214
+ end
215
+
216
+ def restitution=(restitution)
217
+ @body.restitution = restitution
218
+ end
219
+ alias_method :set_restitution, :restitution=
220
+
221
+ def set_shape(shape, *params)
222
+ # Save off data that is destroyed when @body.set is called
223
+ saved_damping = damping
224
+ saved_angular_damping = angular_damping
225
+ saved_body_position = body_position
226
+ saved_position = @target.position
227
+ saved_x, saved_y = @target.x, @target.y
228
+ if shape.respond_to?(:to_str) || shape.kind_of?(Symbol)
229
+ case shape.to_s
230
+ when 'Polygon', 'ConvexPolygon'
231
+ params = [params.map {|vector| vector.to_phys2d_vector }.to_java(Vector2f)]
232
+ end
233
+ @shape = ("Physical::" + shape.to_s).constantize.new(*params)
234
+ else
235
+ @shape = shape
236
+ end
237
+
238
+ @body.set(@shape, @mass)
239
+ set_body_position saved_body_position
240
+ @target.set_position saved_position
241
+ @target.move(saved_x, saved_y)
242
+ self.damping = saved_damping
243
+ self.angular_damping = saved_angular_damping
244
+ end
245
+
246
+ def name=(name)
247
+ @name = name
248
+ setup_body
249
+ end
250
+
251
+ def add_to_world(world)
252
+ world.add @body
253
+ @world = world
254
+ end
255
+
256
+ def remove_from_world(world)
257
+ world.remove @body
258
+ @world = nil
259
+ end
260
+
261
+ def physical_debug_mode=(mode)
262
+ if mode
263
+ @target.add_behavior :DebugPhysical
264
+ else
265
+ @target.remove_behavior :DebugPhysical
266
+ end
267
+ end
268
+ alias_method :set_physical_debug_mode, :physical_debug_mode=
269
+
270
+ def movable=(movable)
271
+ @body.moveable = movable
272
+ end
273
+ alias_method :set_movable, :movable=
274
+
275
+ def movable?
276
+ @body.moveable?
277
+ end
278
+
279
+ def damping
280
+ @body.damping
281
+ end
282
+
283
+ def damping=(damping)
284
+ @body.damping = damping
285
+ end
286
+ alias_method :set_damping, :damping=
287
+
288
+ def angular_damping
289
+ @angular_damping
290
+ end
291
+
292
+ def angular_damping=(damping)
293
+ @angular_damping = damping
294
+ end
295
+ alias_method :set_angular_damping, :damping=
296
+
297
+ def set_static_body
298
+ @body.moveable = false
299
+ @body.rotatable = false
300
+ @body.is_resting = true
301
+ end
302
+
303
+ def gravity_effected=(effected)
304
+ @body.gravity_effected = effected
305
+ end
306
+ alias_method :set_gravity_effected, :gravity_effected=
307
+
308
+ def friction
309
+ @body.friction
310
+ end
311
+
312
+ def friction=(friction)
313
+ @body.friction = friction
314
+ end
315
+ alias_method :set_friction, :friction=
316
+
317
+ # def get_colliding_game_objects(tangible_game_object)
318
+ # # TODO: Tangibles only?
319
+ # tangible_game_object
320
+ # end
321
+
322
+ def get_collision_events
323
+ @world.get_contacts(@body)
324
+ end
325
+
326
+ private
327
+ def setup_body
328
+ if @name
329
+ @body = Body.new(@name, @shape, @mass)
330
+ else
331
+ @body = Body.new(@shape, @mass)
332
+ end
333
+
334
+ x = @body.position.x
335
+ y = @body.position.y
336
+
337
+ @body.set(@shape, @mass)
338
+ @body.move(x, y)
339
+ end
340
+
341
+ def move(x_or_vector, y=nil)
342
+ if x_or_vector.kind_of? Numeric
343
+ @body.move(x_or_vector, y)
344
+ else
345
+ @body.move(x_or_vector.x, x_or_vector.y)
346
+ end
347
+ end
348
+ end