jemini 2009.10.27 → 2010.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/README.txt CHANGED
@@ -1,9 +1,17 @@
1
- Jemini 2009.10.27
1
+ Jemini 2010.1.5
2
2
 
3
3
  == Description
4
4
 
5
5
  Jemini is a game library designed to allow creation of reusable features. How many times has someone implemented the aiming on a first person shooter, or a minimap on a real time strategy? Jemini comes packaged with lots of behaviors out of the box, with the ability to easily author more. Jemini uses Phys2D and Slick for physics and graphics, with 3D on the roadmap.
6
6
 
7
+ == Installation
8
+
9
+ At a command line, type:
10
+
11
+ sudo gem install jemini
12
+
13
+ (Leave off the "sudo" if on Windows.)
14
+
7
15
  == License
8
16
 
9
17
  Jemini is released under the BSD license. See the COPYING file for the full license.
Binary file
data/src/behavior.rb CHANGED
@@ -42,7 +42,7 @@ module Jemini
42
42
  callback_abort = CallbackStatus.new
43
43
  @game_object.notify :before_#{method_name}_changes, event
44
44
  if callback_abort.continue?
45
- self.wrapped_#{method} #{args}
45
+ self.wrapped_#{method} event.desired_value
46
46
  @game_object.notify :after_#{method_name}_changes, event
47
47
  end
48
48
  end
@@ -228,14 +228,6 @@ module Jemini
228
228
  end
229
229
  end
230
230
 
231
- def add_reference_count
232
- @reference_count += 1
233
- end
234
-
235
- def remove_reference_count
236
- @reference_count -= 1
237
- end
238
-
239
231
  def load; end
240
232
  def unload; end
241
233
  end
@@ -5,12 +5,8 @@ class Clickable < Jemini::Behavior
5
5
  wrap_with_callbacks :pressed, :released
6
6
 
7
7
  def load
8
- @game_object.handle_event :mouse_button1_pressed do |mouse_event|
9
- pressed if @game_object.within_region? mouse_event.value.location
10
- end
11
-
12
- @game_object.handle_event :mouse_button1_released do |mouse_event|
13
- released if @game_object.within_region? mouse_event.value.location
8
+ @game_object.handle_event :click do |mouse_event|
9
+ released if @game_object.within_region? mouse_event.value.screen_position
14
10
  end
15
11
  end
16
12
 
@@ -0,0 +1,51 @@
1
+ #Allows an object to load attributes from a file.
2
+ class Configurable < Jemini::Behavior
3
+
4
+ #The loaded configuration for the object.
5
+ attr_reader :config
6
+
7
+ #Loads a configuration with the given name.
8
+ def configure_as(key)
9
+ string = game_state.manager(:config).get_config(key)
10
+ @config = parse(string)
11
+ end
12
+
13
+ private
14
+
15
+ #Parse the config string, returning a hash of attributes.
16
+ def parse(string)
17
+ attributes = {}
18
+ string.split("\n").each do |line|
19
+ line.strip!
20
+ next if line.empty?
21
+ next if line =~ /^#/
22
+ if line =~ /^([^=]+)=(.*)$/
23
+ key = $1.strip.to_sym
24
+ value = parse_value($2.strip)
25
+ attributes[key] = value
26
+ end
27
+ end
28
+ attributes
29
+ end
30
+
31
+ #Treats quoted strings as strings, unquoted numbers as numbers.
32
+ def parse_value(value)
33
+ case value
34
+ when /^"(.*)"$/
35
+ escape($1)
36
+ when /^([\-\d]+)$/
37
+ $1.to_i
38
+ when /^([\-\d\.]+)$/
39
+ $1.to_f
40
+ else
41
+ escape(value)
42
+ end
43
+ end
44
+
45
+ def escape(string)
46
+ string.gsub!(/\\\"/, '"')
47
+ string.gsub!(/\\\\/, '\\')
48
+ string
49
+ end
50
+
51
+ end
@@ -4,7 +4,7 @@ class DebugPhysical < Jemini::Behavior
4
4
  PhysVector = Java::net::phys2d::math::Vector2f
5
5
  PhysCircle = Java::net.phys2d.raw.shapes.Circle
6
6
  PhysPolygon = Java::net.phys2d.raw.shapes.Polygon
7
- PhysLine = Java::net.phys2d.raw.shapes.Line
7
+ PhysLine = Java::net.phys2d.raw.shapes.Line
8
8
  SlickVector = Java::org::newdawn::slick::geom::Vector2f
9
9
  SlickPolygon = Java::org.newdawn.slick.geom.Polygon
10
10
  SlickCircle = Java::org.newdawn.slick.geom.Circle
@@ -33,8 +33,9 @@ private
33
33
  SlickPolygon.new(physics_shape.get_vertices(body.position, body.rotation).map{|point| [point.x, point.y]}.flatten.to_java(:float))
34
34
  elsif physics_shape.kind_of? PhysCircle
35
35
  SlickCircle.new(body.position.x, body.position.y, physics_shape.radius)
36
- # elsif physics_shape.kind_of? PhysLine
37
- # SlickLine.new(body_position.x, )
36
+ elsif physics_shape.kind_of? PhysLine
37
+ # SlickLine.new(physics_shape.start.x, physics_shape.start.y, physics_shape.end.x, physics_shape.end.y)
38
+ SlickLine.new(*physics_shape.get_vertices(body.position, body.rotation).map{|point| [point.x, point.y]}.flatten.to_java(:float))
38
39
  else
39
40
  raise "#{self.class} does not know how to draw the shape #{physics_shape.class}"
40
41
  end
@@ -0,0 +1,53 @@
1
+ # draws a line on the screen
2
+ class DrawableEllipse < Jemini::Behavior
3
+ java_import 'org.newdawn.slick.geom.Ellipse'
4
+ java_import 'org.newdawn.slick.Color'
5
+ depends_on :Spatial
6
+ wrap_with_callbacks :draw
7
+
8
+ #The Color to draw the ellipse in.
9
+ attr_accessor :color
10
+ #If true, the shape will be drawn filled in. If false, only the frame will be drawn.
11
+ attr_accessor :ellipse_filled
12
+
13
+ def load
14
+ @color = Color.white
15
+ @ellipse_filled = true
16
+ @ellipse = Ellipse.new @game_object.position.x, @game_object.position.y, 1.0, 1.0
17
+ @game_object.on_after_position_changes { set_drawing_location }
18
+ end
19
+
20
+ #The ellipse height.
21
+ def height=(value)
22
+ @ellipse.radius2 = value / 2.0
23
+ set_drawing_location
24
+ end
25
+ def height
26
+ @ellipse.radius2 * 2.0
27
+ end
28
+
29
+ #The ellipse width.
30
+ def width=(value)
31
+ @ellipse.radius1 = value / 2.0
32
+ set_drawing_location
33
+ end
34
+ def width
35
+ @ellipse.radius1 * 2.0
36
+ end
37
+
38
+ #Draw an outline to the given graphics context.
39
+ def draw(graphics)
40
+ graphics.set_color @color
41
+ if @ellipse_filled
42
+ graphics.fill @ellipse
43
+ else
44
+ graphics.draw @ellipse
45
+ end
46
+ end
47
+
48
+ private
49
+ def set_drawing_location
50
+ @ellipse.x = @game_object.position.x - @ellipse.radius1
51
+ @ellipse.y = @game_object.position.y - @ellipse.radius2
52
+ end
53
+ end
@@ -1,7 +1,5 @@
1
- require 'behaviors/drawable'
2
-
3
1
  #Makes an object draw itself as a bitmap image.
4
- class DrawableImage < Drawable
2
+ class DrawableImage < Jemini::Behavior
5
3
  include_class 'org.newdawn.slick.Image'
6
4
  depends_on :Spatial
7
5
  attr_accessor :image, :color, :texture_coords, :image_size
@@ -1,18 +1,20 @@
1
1
  # draws a line on the screen
2
- # TODO: Enable color
3
2
  class DrawableLine < Jemini::Behavior
4
3
  java_import 'org.newdawn.slick.geom.Line'
4
+ java_import 'org.newdawn.slick.Color'
5
5
  depends_on :Spatial
6
6
  wrap_with_callbacks :draw
7
7
 
8
+ #A Vector with the coordinates of the other end of the line.
8
9
  attr_reader :line_end_position
10
+ #The Color to draw the line in.
9
11
  attr_accessor :color
10
12
 
11
13
  def load
14
+ @color = Color.white
12
15
  @line_end_position = Vector.new(0.0, 0.0)
13
16
  @line = Line.new @game_object.position.to_slick_vector, @line_end_position.to_slick_vector
14
17
  @game_object.on_after_position_changes { set_line }
15
- #@color = Color.white
16
18
  end
17
19
 
18
20
  def line_end_position=(end_point)
@@ -21,7 +23,9 @@ class DrawableLine < Jemini::Behavior
21
23
  @line_end_position
22
24
  end
23
25
 
26
+ #Draw the line to the given graphics context.
24
27
  def draw(graphics)
28
+ graphics.set_color @color
25
29
  graphics.draw @line
26
30
  end
27
31
 
@@ -0,0 +1,53 @@
1
+ # draws a line on the screen
2
+ class DrawableRectangle < Jemini::Behavior
3
+ java_import 'org.newdawn.slick.geom.Rectangle'
4
+ java_import 'org.newdawn.slick.Color'
5
+ depends_on :Spatial
6
+ wrap_with_callbacks :draw
7
+
8
+ #The Color to draw the shape in.
9
+ attr_accessor :color
10
+ #If true, the shape will be drawn filled in. If false, only the frame will be drawn.
11
+ attr_accessor :rectangle_filled
12
+
13
+ def load
14
+ @color = Color.white
15
+ @rectangle_filled = true
16
+ @rectangle = Rectangle.new @game_object.position.x, @game_object.position.y, 1.0, 1.0
17
+ @game_object.on_after_position_changes { set_drawing_location }
18
+ end
19
+
20
+ #The rectangle height.
21
+ def height=(value)
22
+ @rectangle.height = value
23
+ set_drawing_location
24
+ end
25
+ def height
26
+ @rectangle.height
27
+ end
28
+
29
+ #The rectangle width.
30
+ def width=(value)
31
+ @rectangle.width = value
32
+ set_drawing_location
33
+ end
34
+ def width
35
+ @rectangle.width
36
+ end
37
+
38
+ #Draw an outline to the given graphics context.
39
+ def draw(graphics)
40
+ graphics.set_color @color
41
+ if @rectangle_filled
42
+ graphics.fill @rectangle
43
+ else
44
+ graphics.draw @rectangle
45
+ end
46
+ end
47
+
48
+ private
49
+ def set_drawing_location
50
+ @rectangle.x = @game_object.position.x - (@rectangle.width / 2.0)
51
+ @rectangle.y = @game_object.position.y - (@rectangle.height / 2.0)
52
+ end
53
+ end
@@ -1,5 +1,3 @@
1
- require 'behaviors/drawable'
2
-
3
1
  #Makes an object draw itself on the screen as a polygon.
4
2
  class DrawableShape < Jemini::Behavior
5
3
  java_import 'org.newdawn.slick.geom.Vector2f'
@@ -6,18 +6,19 @@ class Physical < Jemini::Behavior
6
6
 
7
7
  INFINITE_MASS = Java::net::phys2d::raw::Body::INFINITE_MASS
8
8
 
9
- include_class "net.phys2d.raw.Body"
10
- include_class "net.phys2d.raw.shapes.Box"
11
- include_class "net.phys2d.raw.shapes.Circle"
12
- include_class "net.phys2d.raw.shapes.Line"
13
- include_class "net.phys2d.raw.shapes.Polygon"
14
- include_class "net.phys2d.raw.shapes.ConvexPolygon"
15
- include_class "net.phys2d.math.Vector2f"
16
- include_class 'net.phys2d.raw.AngleJoint'
17
- include_class 'net.phys2d.raw.BasicJoint'
18
- include_class 'net.phys2d.raw.SpringJoint'
19
- include_class 'net.phys2d.raw.FixedAngleJoint'
20
- include_class 'net.phys2d.raw.DistanceJoint'
9
+ java_import "net.phys2d.raw.Body"
10
+ java_import "net.phys2d.raw.shapes.Box"
11
+ java_import "net.phys2d.raw.shapes.Circle"
12
+ java_import "net.phys2d.raw.shapes.Line"
13
+ java_import "net.phys2d.raw.shapes.Polygon"
14
+ java_import "net.phys2d.raw.shapes.ConvexPolygon"
15
+ java_import "net.phys2d.math.Vector2f"
16
+ java_import 'net.phys2d.raw.AngleJoint'
17
+ java_import 'net.phys2d.raw.BasicJoint'
18
+ java_import 'net.phys2d.raw.SpringJoint'
19
+ java_import 'net.phys2d.raw.FixedAngleJoint'
20
+ java_import 'net.phys2d.raw.DistanceJoint'
21
+ java_import 'net.phys2d.raw.FixedJoint'
21
22
 
22
23
  attr_reader :mass, :name, :shape
23
24
  depends_on :Spatial
@@ -33,6 +34,8 @@ class Physical < Jemini::Behavior
33
34
  @angular_damping = 0.0
34
35
  @game_object.enable_listeners_for :physical_collided
35
36
  @game_object.on_after_position_changes { move_body @game_object.position }
37
+ @joints = []
38
+
36
39
  # Manual angular damping. New Phys2D may support this? If not, file a bug.
37
40
  @game_object.on_update do |delta|
38
41
  next if @angular_damping.zero? || angular_velocity.zero?
@@ -75,6 +78,9 @@ class Physical < Jemini::Behavior
75
78
  end
76
79
  alias_method :set_body_position, :body_position=
77
80
 
81
+ def add_joint(joint)
82
+ @joints << joint
83
+ end
78
84
  # See about Phys2D joints here: http://www.cokeandcode.com/phys2d/source/javadoc/net/phys2d/raw/Joint.html
79
85
  # TODO: Make the joint a game object and/or behavior
80
86
  def join_to_physical(physical_game_object, options={})
@@ -91,7 +97,9 @@ class Physical < Jemini::Behavior
91
97
  AngleJoint.new(@body, other_body, self_body_point, other_body_point, options[:self_body_angle], options[:other_body_angle])
92
98
  when :basic
93
99
  joint = BasicJoint.new(@body, other_body, options[:anchor].to_phys2d_vector)
94
- joint.relaxation = options[:relaxation] if options[:relaxation]
100
+ joint
101
+ when :fixed
102
+ joint = FixedJoint.new(@body, other_body)
95
103
  joint
96
104
  when :spring
97
105
  joint = SpringJoint.new(@body, other_body, options[:self_anchor].to_phys2d_vector, options[:other_anchor].to_phys2d_vector)
@@ -99,7 +107,12 @@ class Physical < Jemini::Behavior
99
107
  else
100
108
  raise "Joint type #{options[:joint].inspect} not supported."
101
109
  end
110
+ joint.relaxation = options[:relaxation] if options[:relaxation]
111
+
112
+ @joints << joint
113
+
102
114
  @world.add joint
115
+ joint
103
116
  end
104
117
 
105
118
  #The maximum speed the object is allowed to travel. Takes either a Vector with the x/y limits or the numeric value to assign to both x and y.
@@ -198,7 +211,8 @@ class Physical < Jemini::Behavior
198
211
  end
199
212
 
200
213
  def angular_velocity=(delta)
201
- @body.adjust_angular_velocity(delta - angular_velocity)
214
+ velocity = (delta - angular_velocity).to_f
215
+ @body.adjust_angular_velocity velocity
202
216
  end
203
217
  alias_method :set_angular_velocity, :angular_velocity=
204
218
 
@@ -254,6 +268,8 @@ class Physical < Jemini::Behavior
254
268
  case shape.to_s
255
269
  when 'Polygon', 'ConvexPolygon'
256
270
  params = [params.map {|vector| vector.to_phys2d_vector }.to_java(Vector2f)]
271
+ when 'Line'
272
+ params = params.map {|vector| vector.to_phys2d_vector }.to_java(Vector2f)
257
273
  end
258
274
  @shape = ("Physical::" + shape.to_s).constantize.new(*params)
259
275
  else
@@ -283,6 +299,7 @@ class Physical < Jemini::Behavior
283
299
  #Remove this object from the control of the physics engine.
284
300
  def remove_from_world(world)
285
301
  world.remove @body
302
+ @joints.each {|j| world.remove j }
286
303
  @world = nil
287
304
  end
288
305
 
@@ -1,5 +1,3 @@
1
- require 'behaviors/drawable'
2
-
3
1
  #Makes an object draw a shrinking trail behind itself as it moves.
4
2
  class TriangleTrailEmittable < Jemini::Behavior
5
3
  #depends_on :Movable2d
@@ -19,6 +17,10 @@ class TriangleTrailEmittable < Jemini::Behavior
19
17
  def unload
20
18
  game_state.remove @emitter
21
19
  end
20
+
21
+ def triangle_trail
22
+ @emitter
23
+ end
22
24
 
23
25
  #Transparency to use. 1.0 is opaque. Default is 0.5.
24
26
  def alpha
data/src/color.rb CHANGED
@@ -1,14 +1,19 @@
1
1
  class Color
2
+ SlickColor = Java::org::newdawn::slick::Color
2
3
  attr_reader :native_color
3
4
 
4
- def initialize(red_or_other, blue = 0.0, green = 0.0, alpha = 1.0)
5
+ def initialize(red_or_other, blue = nil, green = nil, alpha = 1.0)
5
6
  if red_or_other.kind_of? Numeric
6
- @native_color = new_native_color(red_or_other, blue, green, alpha)
7
+ if green.nil? && blue.nil? #alpha defaults to 1.0
8
+ @native_color = SlickColor.new(red_or_other)
9
+ else
10
+ @native_color = SlickColor.new(red_or_other, blue, green, alpha)
11
+ end
7
12
  else
8
13
  # create from predefined Slick colors
9
- fixed_color = Java::org::newdawn::slick::Color.send(red_or_other.to_s.downcase)
14
+ fixed_color = SlickColor.send(red_or_other.to_s.downcase)
10
15
  # 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)
16
+ @native_color = SlickColor.new(fixed_color.r, fixed_color.g, fixed_color.b, fixed_color.a)
12
17
  end
13
18
  end
14
19
 
@@ -63,8 +68,4 @@ class Color
63
68
  def fade_by(amount)
64
69
  self.alpha = alpha * (1.0 - amount)
65
70
  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
71
  end
data/src/game.rb CHANGED
@@ -89,7 +89,7 @@ module Jemini
89
89
  private
90
90
  def create_app
91
91
  @app = AppGameContainer.new(self, screen_size.x, screen_size.y, fullscreen)
92
- @app.vsync = false
92
+ @app.vsync = true
93
93
  @app.maximum_logic_update_interval = 60
94
94
  @app.smooth_deltas = false #true
95
95
  #main.container = container
@@ -101,6 +101,7 @@ module Jemini
101
101
  @canvas.set_size(screen_size.x, screen_size.y)
102
102
  container = @canvas.container
103
103
  container.vsync = false
104
+ # container.vsync = true
104
105
  container.maximum_logic_update_interval = 60
105
106
  #container.start
106
107
  @canvas
data/src/game_object.rb CHANGED
@@ -31,29 +31,28 @@ module Jemini
31
31
  end
32
32
 
33
33
  def add_behavior(behavior_name)
34
+ underscored_name = behavior_name.underscore
34
35
  klass = nil
35
36
  retried = false
36
37
  begin
37
38
  klass = behavior_name.camelize.constantize
38
39
  rescue NameError
39
40
  raise if retried
40
- require "behaviors/#{behavior_name.underscore}"
41
+ require "behaviors/#{underscored_name}"
41
42
  retried = true
42
43
  retry
43
44
  end
44
- @__behaviors[behavior_name] = klass.new(self) if @__behaviors[behavior_name].nil?
45
+ @__behaviors[underscored_name] = klass.new(self) if @__behaviors[underscored_name].nil?
45
46
  validate_dependant_behaviors
46
47
  rescue NameError => e
47
- raise "Unable to load behavior #{behavior_name}, #{e.message}\n#{e.backtrace.join("\n")}"
48
+ raise "Unable to load behavior #{underscored_name}, #{e.message}\n#{e.backtrace.join("\n")}"
48
49
  end
49
50
 
50
51
  def __destroy
51
52
  notify :before_remove, self
52
- #TODO: Perhaps expose this as a method on Behavior
53
- #Jemini::Behavior.send(:class_variable_get, :@@depended_on_by).delete self
54
53
  __remove_listeners
55
54
  @__behaviors.each do |name, behavior|
56
- #the list is being modified as we go through it, so check before use.
55
+ # the list is being modified as we go through it, so check before use.
57
56
  next if behavior.nil?
58
57
  behavior.send(:delete)
59
58
  end
@@ -99,6 +98,7 @@ module Jemini
99
98
  end
100
99
 
101
100
  def remove_registered_listener(listener_method_name, object, callback_or_callback_method)
101
+
102
102
  if callback_or_callback_method.nil? || callback_or_callback_method.kind_of?(Symbol)
103
103
  @callbacks[listener_method_name].delete callback_or_callback_method
104
104
  else
@@ -0,0 +1,57 @@
1
+ class IconStripCounterDisplay < Jemini::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
+ icon_count = count < 0 ? 0 : count
21
+ diff = @icons.size - icon_count
22
+ if diff > 0
23
+ 1.upto diff do
24
+ last_icon = @icons.pop
25
+ game_state.remove_game_object last_icon
26
+ end
27
+ elsif diff < 0
28
+ 1.upto diff.abs do
29
+ sprite = game_state.create_game_object :GameObject
30
+ sprite.add_behavior :Sprite
31
+ sprite.add_behavior :CameraAnchoredDrawable
32
+ sprite.image = @icon
33
+ position_sprite(x, y, @icons.size, sprite)
34
+ @icons << sprite
35
+ end
36
+ end
37
+ end
38
+ on_after_move do
39
+ @icons.each_with_index do |sprite, index|
40
+ position_sprite(x, y, index, sprite)
41
+ end
42
+ end
43
+ end
44
+
45
+ def position_sprite(offset_x, offset_y, sprite_index, sprite)
46
+ row_number = @rows.nil? ? sprite_index : (sprite_index % @rows)
47
+ column_number = @columns.nil? ? sprite_index : (sprite_index % @columns)
48
+ if TOP_LEFT_TO_BOTTOM_RIGHT_LAYOUT_MODE == @layout_mode
49
+ sprite_x = offset_x + (@icon.width * column_number)
50
+ sprite_y = offset_y + (@icon.height * row_number)
51
+ elsif BOTTOM_RIGHT_TO_TOP_LEFT_LAYOUT_MODE == @layout_mode
52
+ sprite_x = offset_x - (@icon.width * column_number)
53
+ sprite_y = offset_y - (@icon.height * row_number)
54
+ end
55
+ sprite.move(sprite_x, sprite_y)
56
+ end
57
+ end
@@ -1,21 +1,16 @@
1
- require 'behaviors/drawable'
2
-
3
1
  class Text < Jemini::GameObject
4
- include_class "org.newdawn.slick.TrueTypeFont"
5
- include_class "java.awt.Font"
2
+ java_import "org.newdawn.slick.TrueTypeFont"
3
+ java_import "java.awt.Font"
6
4
 
7
5
  has_behavior :Spatial
8
- PLAIN = Font::PLAIN
9
- ITALIC = Font::ITALIC
10
- BOLD = Font::BOLD
11
6
 
12
7
  attr_accessor :text, :size, :style, :font_name
13
8
 
14
9
  def load(text, options={})
15
- @font_name = "Arial"
16
- @size = 12
17
- @text = text
18
- @style = PLAIN
10
+ @font_name = options[:name] || "Arial"
11
+ @size = options[:size] || 12
12
+ @text = text
13
+ @style = get_style(options[:style])
19
14
  load_font
20
15
  orient_text(options)
21
16
  end
@@ -47,8 +42,8 @@ class Text < Jemini::GameObject
47
42
  alias_method :set_size, :size=
48
43
 
49
44
  def style=(style)
50
- raise "Invalid font style, must be PLAIN, ITALIC or BOLD" unless [PLAIN, ITALIC, BOLD].member? style
51
- @style = style
45
+ raise "Invalid font style #{style.inspect}, must be :bold, :italic or :plain" unless [:bold, :italic, :plain].member? style
46
+ @style = get_style(style)
52
47
  load_font
53
48
  end
54
49
  alias_method :set_style, :style=
@@ -61,11 +56,22 @@ private
61
56
  when :bottom_right
62
57
  self.position = options[:position] - Vector.new(text_width, text_height).half if options[:position]
63
58
  when :center, nil
64
- self.position = options[:position]
59
+ self.position = options[:position] if options[:position]
65
60
  end
66
61
  end
67
62
 
68
63
  def load_font
69
64
  @font = TrueTypeFont.new(Font.new(@font_name, @style, @size), true)
70
65
  end
66
+
67
+ def get_style(style)
68
+ case style
69
+ when :bold
70
+ Font::BOLD
71
+ when :italic
72
+ Font::ITALIC
73
+ when :plain, nil
74
+ Font::PLAIN
75
+ end
76
+ end
71
77
  end
@@ -1,7 +1,7 @@
1
1
  class TriangleTrail < Jemini::GameObject
2
2
  #has_behavior :Movable2d
3
3
  has_behavior :Spatial
4
- attr_accessor :radius, :alpha
4
+ attr_accessor :radius, :alpha, :color
5
5
 
6
6
  def load
7
7
  @trail = []
@@ -9,6 +9,7 @@ class TriangleTrail < Jemini::GameObject
9
9
  @trail_size = 50
10
10
  @radius = 10
11
11
  @alpha = 0.5
12
+ @color = Color.new(0.0, 1.0, 1.0)
12
13
  @flip = false
13
14
  #TODO: Remove message when the callback stuff is checked in
14
15
  @first_move = true
@@ -23,40 +24,39 @@ class TriangleTrail < Jemini::GameObject
23
24
  end
24
25
 
25
26
  def draw(graphics)
26
- if @trail.size > 3
27
- gl = Java::org::newdawn::slick::opengl::renderer::Renderer.get
27
+ return unless @trail.size > 3
28
+ gl = Java::org::newdawn::slick::opengl::renderer::Renderer.get
28
29
 
29
- #Java::org::newdawn::slick::opengl::SlickCallable.new do
30
- callable_class = Java::org::newdawn::slick::opengl::SlickCallable
31
- callable_class.enter_safe_block
32
- # use LWJGL's const directly, Slick's wrapper does not have the triangle strip const
33
- triangle_strip_enum = Java::org::lwjgl::opengl::GL11::GL_TRIANGLE_STRIP
34
- gl.gl_begin triangle_strip_enum
35
- gl.gl_color4f(0.0, 1.0, 1.0, @alpha)
30
+ #Java::org::newdawn::slick::opengl::SlickCallable.new do
31
+ callable_class = Java::org::newdawn::slick::opengl::SlickCallable
32
+ callable_class.enter_safe_block
33
+ # use LWJGL's const directly, Slick's wrapper does not have the triangle strip const
34
+ triangle_strip_enum = Java::org::lwjgl::opengl::GL11::GL_TRIANGLE_STRIP
35
+ gl.gl_begin triangle_strip_enum
36
+ gl.gl_color4f(@color.red, @color.green, @color.blue, @alpha)
36
37
 
37
- origin_x, origin_y = calculate_point_on_trail_edge(@trail[1], @trail[0], @radius, @flip)
38
- gl.gl_vertex2f(origin_x, origin_y)
38
+ origin_x, origin_y = calculate_point_on_trail_edge(@trail[1], @trail[0], @radius, @flip)
39
+ gl.gl_vertex2f(origin_x, origin_y)
39
40
 
40
- flipped_origin_x, flipped_origin_y = calculate_point_on_trail_edge(@trail[1], @trail[0], @radius, !@flip)
41
- gl.gl_vertex2f(flipped_origin_x, flipped_origin_y)
42
-
43
- last_trail_vector = @trail[1]
44
- #gl.gl_color4f(0.0, 1.0, 1.0, alpha)
45
- @trail[2..-1].each_with_index do |trail_vector, index|
46
- next if trail_vector == last_trail_vector
47
- actual_trail_size = (@trail.size - 1).to_f
48
- trail_radius = (@radius) * ((actual_trail_size - (index + 2).to_f) / actual_trail_size)
49
-
50
- rotated_x, rotated_y = calculate_point_on_trail_edge(trail_vector, last_trail_vector, trail_radius, @flip)
51
- gl.gl_vertex2f(rotated_x, rotated_y)
52
- rotated_x, rotated_y = calculate_point_on_trail_edge(trail_vector, last_trail_vector, trail_radius, !@flip)
53
- gl.gl_vertex2f(rotated_x, rotated_y)
54
-
55
- last_trail_vector = trail_vector
56
- end
57
- gl.gl_end
58
- callable_class.leave_safe_block
59
- end
41
+ flipped_origin_x, flipped_origin_y = calculate_point_on_trail_edge(@trail[1], @trail[0], @radius, !@flip)
42
+ gl.gl_vertex2f(flipped_origin_x, flipped_origin_y)
43
+
44
+ last_trail_vector = @trail[1]
45
+ #gl.gl_color4f(0.0, 1.0, 1.0, alpha)
46
+ @trail[2..-1].each_with_index do |trail_vector, index|
47
+ next if trail_vector == last_trail_vector
48
+ actual_trail_size = (@trail.size - 1).to_f
49
+ trail_radius = (@radius) * ((actual_trail_size - (index + 2).to_f) / actual_trail_size)
50
+
51
+ rotated_x, rotated_y = calculate_point_on_trail_edge(trail_vector, last_trail_vector, trail_radius, @flip)
52
+ gl.gl_vertex2f(rotated_x, rotated_y)
53
+ rotated_x, rotated_y = calculate_point_on_trail_edge(trail_vector, last_trail_vector, trail_radius, !@flip)
54
+ gl.gl_vertex2f(rotated_x, rotated_y)
55
+
56
+ last_trail_vector = trail_vector
57
+ end
58
+ gl.gl_end
59
+ callable_class.leave_safe_block
60
60
  end
61
61
 
62
62
  def calculate_point_on_trail_edge(current_vector, previous_vector, trail_radius, flip)
data/src/game_state.rb CHANGED
@@ -67,7 +67,8 @@ module Jemini
67
67
  log.debug "Creating: #{type.camelize.to_sym}"
68
68
  type.constantize
69
69
  else
70
- try_require("game_objects/#{type.underscore}") or try_require("managers/#{type.underscore}")
70
+ successful_require = try_require("game_objects/#{type.underscore}") || try_require("managers/#{type.underscore}")
71
+ raise "Could not find the game object #{type.inspect}." unless successful_require
71
72
  type.camelize.constantize
72
73
  end
73
74
  game_object = game_object_type.new(self, *params)
@@ -153,12 +154,12 @@ module Jemini
153
154
  def try_require(path)
154
155
  begin
155
156
  require path
157
+ log.debug "Successful require: #{path}"
158
+ true
156
159
  rescue LoadError => e
157
160
  log.warn "Failed to require: #{path}"
158
- return false
161
+ false
159
162
  end
160
- log.debug "Successful require: #{path}"
161
- return true
162
163
  end
163
164
  end
164
165
  end
@@ -14,7 +14,7 @@ class BasicPhysicsManager < Jemini::GameObject
14
14
  has_behavior :HandlesEvents
15
15
 
16
16
  def load
17
- @delta_debt = 0
17
+ # @delta_debt = 0
18
18
  @world = World.new(Vector2f.new(0, 0), 5, QuadSpaceStrategy.new(20, 5))
19
19
  # @world = World.new(Vector2f.new(0, 0), 10, BruteCollisionStrategy.new)
20
20
  @world.add_listener self
@@ -34,24 +34,25 @@ class BasicPhysicsManager < Jemini::GameObject
34
34
  end
35
35
 
36
36
  def update(delta)
37
- delta += @delta_debt
38
- @delta_debt = 0
39
- if delta == MILLISECONDS_PER_UPDATE
40
- sleep PHYS2D_UPDATE_DIFF / 1000.0
41
- step
42
- else
43
- temp_delta = delta
44
- until temp_delta <= 0
45
- new_delta = temp_delta > MILLISECONDS_PER_UPDATE ? MILLISECONDS_PER_UPDATE : temp_delta
46
- if new_delta < MILLISECONDS_PER_UPDATE
47
- @delta_debt = new_delta
48
- return #don't step, we'll try again next update
49
- else
50
- step
51
- temp_delta -= new_delta
52
- end
53
- end
54
- end
37
+ step
38
+ # delta += @delta_debt
39
+ # @delta_debt = 0
40
+ # if delta == MILLISECONDS_PER_UPDATE
41
+ # sleep PHYS2D_UPDATE_DIFF / 1000.0
42
+ # step
43
+ # else
44
+ # temp_delta = delta
45
+ # until temp_delta <= 0
46
+ # new_delta = temp_delta > MILLISECONDS_PER_UPDATE ? MILLISECONDS_PER_UPDATE : temp_delta
47
+ # if new_delta < MILLISECONDS_PER_UPDATE
48
+ # @delta_debt = new_delta
49
+ # return #don't step, we'll try again next update
50
+ # else
51
+ # step
52
+ # temp_delta -= new_delta
53
+ # end
54
+ # end
55
+ # end
55
56
  end
56
57
 
57
58
  # there's a typo in the API, I swears it.
@@ -0,0 +1,12 @@
1
+ class ConfigManager < Jemini::GameObject
2
+
3
+ def load
4
+ @configs = {}
5
+ end
6
+
7
+ #Takes a reference to a config loaded via the resource manager, and returns it.
8
+ def get_config(reference)
9
+ game_state.manager(:resource).get_config(reference)
10
+ end
11
+
12
+ end
@@ -13,27 +13,35 @@ module Jemini
13
13
  # type can be one of :hold, :release, :press, and :move
14
14
  def add_input_listener(type, button_id, options={})
15
15
  device = detect_device(button_id, type)
16
- real_button = detect_button(button_id, device)
16
+ real_button = detect_button(button_id, options, device)
17
17
  value = options[:value]
18
18
  to = options[:to]
19
+ id = options[:id]
19
20
  listener = InputListener.create(action_name, type, device, real_button)
20
21
  listener.default_value = value
21
22
  listener.message_to = to
23
+ listener.joystick_id = id
24
+ listener.axis_inverted = options[:invert]
25
+ listener.deadzone = options[:deadzone]
22
26
  InputManager.loading_input_manager.listeners << listener
23
27
  end
24
28
 
25
29
  def detect_device(button_id, type)
26
30
  if mouse_button?(button_id, type)
27
31
  :mouse
32
+ elsif joystick_button?(button_id, type)
33
+ :joystick
28
34
  else
29
35
  :key
30
36
  end
31
37
  end
32
38
 
33
- def detect_button(button_id, device)
39
+ def detect_button(button_id, options, device)
34
40
  case device
35
41
  when :mouse
36
42
  detect_mouse_button(button_id)
43
+ when :joystick
44
+ detect_joystick_button(button_id, options)
37
45
  when :key
38
46
  case button_id.to_s
39
47
  when /(left|right)_alt/
@@ -59,6 +67,18 @@ module Jemini
59
67
  return true if button_id.has_key? :mouse_button
60
68
  end
61
69
 
70
+ def joystick_button?(button_id, type)
71
+ return true if button_id == :joystick
72
+ # return true if type == :move && button_id == :joystick
73
+ # return false unless button_id.respond_to? :has_key?
74
+ # return true if button_id.has_key? :joystick_button
75
+ # return true if button_id.has_key? :joystick_button
76
+ end
77
+
78
+ def detect_joystick_button(button_id, options)
79
+ options[:button] || options[:axis]
80
+ end
81
+
62
82
  def detect_mouse_button(button_id)
63
83
  case button_id
64
84
  when :mouse_left
@@ -11,7 +11,9 @@ module Jemini
11
11
  :input_callback,
12
12
  :game_state,
13
13
  :default_value,
14
- :message_to
14
+ :message_to,
15
+ :axis_inverted,
16
+ :deadzone
15
17
 
16
18
  def self.create(message, type, device, button_id, options={}, &callback)
17
19
  options[:input_callback] = callback
@@ -54,6 +56,10 @@ module Jemini
54
56
  @cancel_post
55
57
  end
56
58
 
59
+ def axis_inverted?
60
+ @axis_inverted
61
+ end
62
+
57
63
  def key
58
64
  "#{@device}_#{@input_type}_#{@input_button_or_axis}_#{@joystick_id || 'any'}"
59
65
  end
@@ -6,9 +6,7 @@ module Jemini
6
6
  :joystick
7
7
  end
8
8
 
9
- def find_axis_id_by_axis_name(raw_input, axis_name)
10
- (0..raw_input.get_axis_count(@joystick_id)).find {|axis_id| raw_input.get_axis_name(@joystick_id, axis_id) == axis_name}
11
- end
9
+
12
10
 
13
11
  def poll_value(raw_input)
14
12
  if @joystick_id && @joystick_id >= raw_input.controller_count
@@ -17,29 +15,35 @@ module Jemini
17
15
  end
18
16
 
19
17
  case @input_type
20
- when :axis_update
18
+ when :move, :axis_update
21
19
  @axis_id ||= find_axis_id_by_axis_name(raw_input, @input_button_or_axis)
22
- axis_value = raw_input.get_axis_value(@joystick_id, @axis_id)
23
- axis_value
24
- when :pressed
25
20
  if @joystick_id.nil?
26
- result = (0..raw_input.controller_count).any? {|i| raw_input.is_button_pressed(@input_button_or_axis, i)} unless raw_input.controller_count.zero?
21
+ nil # how do we send back multiple axis values?
22
+ else
23
+ axis_value = raw_input.get_axis_value(@joystick_id, @axis_id)
24
+ axis_value = 0.0 if deadzone && (deadzone > axis_value.abs)
25
+ axis_value *= -1 if axis_inverted?
26
+ axis_value
27
+ end
28
+ when :press
29
+ if @joystick_id.nil?
30
+ result = (0...raw_input.controller_count).any? {|i| raw_input.is_button_pressed(@input_button_or_axis, i)}
27
31
  else
28
32
  result = raw_input.is_button_pressed(@input_button_or_axis, @joystick_id)
29
33
  end
30
34
  pressed = !@key_down_on_last_poll && result
31
- @key_down_on_last_poll = result
35
+ @key_down_on_last_poll = result
32
36
  cancel_post! unless pressed
33
37
  pressed
34
- when :held
38
+ when :hold
35
39
  if @joystick_id.nil?
36
- result = (0..raw_input.controller_count).any? {|i| raw_input.is_button_pressed(@input_button_or_axis, i)} unless raw_input.controller_count.zero?
40
+ result = (0...raw_input.controller_count).any? {|i| raw_input.is_button_pressed(@input_button_or_axis, i)}
37
41
  else
38
42
  result = raw_input.is_button_pressed(@input_button_or_axis, @joystick_id)
39
43
  end
40
44
  cancel_post! unless result
41
45
  result
42
- when :released
46
+ when :release
43
47
  button_down = raw_input.is_button_pressed(@input_button_or_axis, @joystick_id)
44
48
  result = (@key_down_on_last_poll && !button_down) ? true : false
45
49
  @key_down_on_last_poll = button_down
@@ -49,5 +53,22 @@ module Jemini
49
53
  cancel_post!
50
54
  end
51
55
  end
56
+
57
+ private
58
+ def find_axis_id_by_axis_name(raw_input, axis_name)
59
+ if @joystick_id
60
+ find_axis_id_by_joystick_id_and_axis_name(raw_input, @joystick_id, axis_name)
61
+ else
62
+ (0...raw_input.controller_count).each do |joystick_id|
63
+ axis_id = find_axis_id_by_joystick_id_and_axis_name(raw_input, joystick_id, axis_name)
64
+ return axis_id if axis_id
65
+ end
66
+ raise "Could not find axis '#{axis_name}' for any connected joystick"
67
+ end
68
+ end
69
+
70
+ def find_axis_id_by_joystick_id_and_axis_name(raw_input, joystick_id, axis_name)
71
+ (0..raw_input.get_axis_count(joystick_id)).find {|axis_id| raw_input.get_axis_name(joystick_id, axis_id) == axis_name}
72
+ end
52
73
  end
53
74
  end
@@ -8,6 +8,7 @@ class ResourceManager < Jemini::GameObject
8
8
  #Sets a default data directory path of "data".
9
9
  def load
10
10
  enable_listeners_for :resources_loaded
11
+ @configs = {}
11
12
  @images = {}
12
13
  @sounds = {}
13
14
  @songs = {}
@@ -25,6 +26,13 @@ class ResourceManager < Jemini::GameObject
25
26
  notify :resources_loaded
26
27
  end
27
28
 
29
+ #Load the config at the given path, and make it accessible via the given key.
30
+ def cache_config(key, path)
31
+ log.debug "Caching config for #{key} with path: #{path}"
32
+ log.warn "Skipping duplicate config for #{key} with path: #{path}" and return if @configs[key]
33
+ @configs[key] = load_resource(path, :config)
34
+ end
35
+
28
36
  #Load the image at the given path, and make it accessible via the given key.
29
37
  def cache_image(key, path)
30
38
  log.debug "Caching image for #{key} with path: #{path}"
@@ -46,6 +54,22 @@ class ResourceManager < Jemini::GameObject
46
54
  @songs[key] = load_resource(path, :music)
47
55
  end
48
56
 
57
+ #Get a config stored previously with cache_config.
58
+ def get_config(key)
59
+ @configs[key] or raise "Could not find config: #{key} - cached configs: #{@configs.keys}"
60
+ end
61
+ alias_method :config, :get_config
62
+
63
+ #Get all configs stored previously with cache_config.
64
+ def get_all_configs
65
+ @configs.values
66
+ end
67
+ alias_method :configs, :get_all_configs
68
+
69
+ def config_names
70
+ @configs.keys
71
+ end
72
+
49
73
  #Get an image stored previously with cache_image.
50
74
  def get_image(key)
51
75
  @images[key] or raise "Could not find image: #{key} - cached images: #{@images.keys}"
@@ -90,30 +114,27 @@ private
90
114
 
91
115
  def load_resource(path, type_name)
92
116
  # due to some JRuby trickery involved with java_import, we can't use metaprogramming tricks here.
93
- type = case type_name
94
- when :image
95
- Image
96
- when :sound
97
- Sound
98
- when :music
99
- Music
100
- end
101
- type.new(Jemini::Resource.path_of(path))
117
+ case type_name
118
+ when :config
119
+ File.read(Jemini::Resource.path_of(path))
120
+ when :image
121
+ Image.new(Jemini::Resource.path_of(path))
122
+ when :sound
123
+ Sound.new(Jemini::Resource.path_of(path))
124
+ when :music
125
+ Music.new(Jemini::Resource.path_of(path))
126
+ end
102
127
  end
103
128
 
104
129
  # root dirs can't be skipped
105
130
  def load_directory(directory, root = false)
106
131
  log.debug "Loading contents of #{directory}"
107
132
  begin
108
- #Dir.open(directory).each do |file|
109
133
  resources_for(directory).each do |file|
110
134
  next if file =~ /^\./
111
- # path = File.join(directory, file)
112
135
  path = File.in_jar?(directory) ? file : File.join(directory, file)
113
136
  log.debug "Dir in jar? #{File.in_jar?(directory)}"
114
137
  log.debug "Using path #{path} for #{file}"
115
- # File.file? doesn't work in a jar.
116
- # next unless File.file?(path)
117
138
  extension = File.extname(file).downcase
118
139
  key = File.basename(file, extension).downcase.to_sym
119
140
  log.debug "Extension: #{extension}"
@@ -124,6 +145,8 @@ private
124
145
  cache_sound(key, path)
125
146
  when '.ogg'
126
147
  cache_song(key, path)
148
+ when '.ini'
149
+ cache_config(key, path)
127
150
  else
128
151
  log.warn "Skipping unknown file: #{path}"
129
152
  end
@@ -159,9 +182,6 @@ private
159
182
  entries_under_directory = all_entries.select {|e| e =~ dir_regex }
160
183
  # need a shallow resultset
161
184
  entries_directly_under_directory = entries_under_directory.reject {|e| e =~ /#{just_dir}\/.*\//}
162
- # log.debug "entries directly under dir"
163
- # log.debug entries_directly_under_directory
164
- # log.debug "------------"
165
185
  entries_directly_under_directory
166
186
  end
167
187
  end
@@ -1,7 +1,6 @@
1
1
  #Tracks tags applied to objects.
2
2
  class TagManager < Jemini::GameObject
3
3
  def load
4
- require 'behaviors/taggable'
5
4
  @tagged_objects = Hash.new { |h,k| h[k] = [] }
6
5
  listen_for(:after_add_game_object, game_state.manager(:game_object)) do |game_object|
7
6
  if game_object.has_behavior? :Taggable
@@ -29,7 +29,6 @@ module Jemini
29
29
  f << <<-ENDL
30
30
  require 'java'
31
31
 
32
- $LOAD_PATH.clear
33
32
  $LOAD_PATH << File.expand_path(File.dirname(__FILE__))
34
33
  $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), 'game_objects'))
35
34
  $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), 'managers'))
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jemini
3
3
  version: !ruby/object:Gem::Version
4
- version: 2009.10.27
4
+ version: 2010.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Logan Barnett, David Koontz, Jay McGavren
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-27 00:00:00 -07:00
12
+ date: 2010-01-05 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -20,7 +20,7 @@ dependencies:
20
20
  requirements:
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: 1.3.7
23
+ version: 1.3.8
24
24
  version:
25
25
  description: Jemini is a game library designed to allow creation of reusable features. How many times has someone implemented the aiming on a first person shooter, or a minimap on a real time strategy? Jemini comes packaged with lots of behaviors out of the box, with the ability to easily author more. Jemini uses Phys2D and Slick for physics and graphics, with 3D on the roadmap.
26
26
  email: logustus@gmail.com
@@ -53,21 +53,21 @@ files:
53
53
  - src/behaviors/animated_image.rb
54
54
  - src/behaviors/audible.rb
55
55
  - src/behaviors/axis_stateful.rb
56
- - src/behaviors/bounding_box_collidable.rb
57
56
  - src/behaviors/cardinal_movable.rb
58
57
  - src/behaviors/clickable.rb
58
+ - src/behaviors/configurable.rb
59
59
  - src/behaviors/countable.rb
60
60
  - src/behaviors/debug_physical.rb
61
61
  - src/behaviors/debug_tangible.rb
62
- - src/behaviors/drawable.rb
62
+ - src/behaviors/drawable_ellipse.rb
63
63
  - src/behaviors/drawable_image.rb
64
64
  - src/behaviors/drawable_line.rb
65
+ - src/behaviors/drawable_rectangle.rb
65
66
  - src/behaviors/drawable_shape.rb
66
67
  - src/behaviors/fading_image_trail_emittable.rb
67
68
  - src/behaviors/game_object_emittable.rb
68
69
  - src/behaviors/grid_bound.rb
69
70
  - src/behaviors/handles_events.rb
70
- - src/behaviors/inertial.rb
71
71
  - src/behaviors/magnetic.rb
72
72
  - src/behaviors/metered.rb
73
73
  - src/behaviors/movable.rb
@@ -86,16 +86,15 @@ files:
86
86
  - src/behaviors/timeable.rb
87
87
  - src/behaviors/top_down_vehicle.rb
88
88
  - src/behaviors/triangle_trail_emittable.rb
89
- - src/behaviors/unique.rb
90
89
  - src/behaviors/updates.rb
91
90
  - src/behaviors/updates_at_consistant_rate.rb
92
91
  - src/behaviors/vectored_movement.rb
93
- - src/behaviors/world_collidable.rb
94
92
  - src/events/grid_changed_event.rb
95
93
  - src/events/physical_message.rb
96
94
  - src/events/tangible_collision_event.rb
97
95
  - src/game_objects/background.rb
98
96
  - src/game_objects/fading_image.rb
97
+ - src/game_objects/icon_strip_counter_display.rb
99
98
  - src/game_objects/tangible_object.rb
100
99
  - src/game_objects/text.rb
101
100
  - src/game_objects/triangle_trail.rb
@@ -105,6 +104,7 @@ files:
105
104
  - src/managers/basic_render_manager.rb
106
105
  - src/managers/basic_tile_manager.rb
107
106
  - src/managers/basic_update_manager.rb
107
+ - src/managers/config_manager.rb
108
108
  - src/managers/input_manager.rb
109
109
  - src/managers/message_queue.rb
110
110
  - src/managers/network_manager.rb
@@ -1,27 +0,0 @@
1
- require 'behavior_event'
2
- include_class 'org.newdawn.slick.geom.Rectangle'
3
-
4
- #Makes an object generate a BoundingBoxCollisionEvent if its bounding box intersects another's.
5
- class BoundingBoxCollidable < Jemini::Behavior
6
- depends_on :Spatial2d
7
-
8
- def load
9
- @game_object.enable_listeners_for :collided
10
- end
11
-
12
- def collision_check(collidable)
13
- return if self == collidable || @game_object == collidable
14
-
15
- notify :collided, BoundingBoxCollisionEvent.new(@game_object, collidable) if bounds.intersects(collidable.bounds)
16
- end
17
- end
18
-
19
- #Indicates that one object has collided with another.
20
- class BoundingBoxCollisionEvent < Jemini::BehaviorEvent
21
- attr_accessor :colliding_object, :collided_object
22
-
23
- def load(source, other)
24
- @colliding_object = source
25
- @collided_object = other
26
- end
27
- end
@@ -1,7 +0,0 @@
1
- #Makes an object draw itself to the screen.
2
- class Drawable < Jemini::Behavior
3
- depends_on_kind_of :Spatial
4
- wrap_with_callbacks :draw
5
-
6
- def draw(graphics); end
7
- end
@@ -1,14 +0,0 @@
1
- # deprecated
2
- class Inertial < Jemini::Behavior
3
- depends_on :UpdatesAtConsistantRate
4
-
5
- #A 2-element array with x/y inertial values. 0 means no resistance to acceleration.
6
- attr_accessor :inertia
7
-
8
- def load
9
- @inertia = [0,0]
10
- @game_object.on_update do
11
- move(@inertia[0] + x, @inertia[1] + y)
12
- end
13
- end
14
- end
File without changes
@@ -1,9 +0,0 @@
1
- #Makes an object generate an event if it collides with another.
2
- class WorldCollidable < Jemini::Behavior
3
- depends_on :BoundingBoxCollidable
4
- depends_on_kind_of :CollisionPoolAlgorithm
5
-
6
- def world_collision_check
7
- get_collision_candidates.each {|candidate| collision_check candidate}
8
- end
9
- end