jemini 2009.10.27
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.
- data/README.txt +9 -0
- data/bin/jemini +26 -0
- data/lib/ibxm.jar +0 -0
- data/lib/jinput.jar +0 -0
- data/lib/jogg-0.0.7.jar +0 -0
- data/lib/jorbis-0.0.15.jar +0 -0
- data/lib/jruby-complete.jar +0 -0
- data/lib/lwjgl.jar +0 -0
- data/lib/lwjgl_util_applet.jar +0 -0
- data/lib/native_files/OpenAL32.dll +0 -0
- data/lib/native_files/jinput-dx8.dll +0 -0
- data/lib/native_files/jinput-dx8_64.dll +0 -0
- data/lib/native_files/jinput-raw.dll +0 -0
- data/lib/native_files/jinput-raw_64.dll +0 -0
- data/lib/native_files/jinput-wintab.dll +0 -0
- data/lib/native_files/libjinput-linux.so +0 -0
- data/lib/native_files/libjinput-linux64.so +0 -0
- data/lib/native_files/libjinput-osx.jnilib +0 -0
- data/lib/native_files/liblwjgl.jnilib +0 -0
- data/lib/native_files/liblwjgl.so +0 -0
- data/lib/native_files/liblwjgl64.so +0 -0
- data/lib/native_files/libopenal.so +0 -0
- data/lib/native_files/lwjgl.dll +0 -0
- data/lib/native_files/openal.dylib +0 -0
- data/lib/natives-linux.jar +0 -0
- data/lib/natives-mac.jar +0 -0
- data/lib/natives-win32.jar +0 -0
- data/lib/phys2d.jar +0 -0
- data/lib/slick.jar +0 -0
- data/package/jar/jemini.jar +0 -0
- data/src/behavior.rb +248 -0
- data/src/behavior_event.rb +23 -0
- data/src/behaviors/animated_image.rb +88 -0
- data/src/behaviors/audible.rb +16 -0
- data/src/behaviors/axis_stateful.rb +35 -0
- data/src/behaviors/bounding_box_collidable.rb +27 -0
- data/src/behaviors/cardinal_movable.rb +121 -0
- data/src/behaviors/clickable.rb +19 -0
- data/src/behaviors/countable.rb +32 -0
- data/src/behaviors/debug_physical.rb +43 -0
- data/src/behaviors/debug_tangible.rb +31 -0
- data/src/behaviors/drawable.rb +7 -0
- data/src/behaviors/drawable_image.rb +111 -0
- data/src/behaviors/drawable_line.rb +32 -0
- data/src/behaviors/drawable_shape.rb +48 -0
- data/src/behaviors/fading_image_trail_emittable.rb +32 -0
- data/src/behaviors/game_object_emittable.rb +13 -0
- data/src/behaviors/grid_bound.rb +108 -0
- data/src/behaviors/handles_events.rb +33 -0
- data/src/behaviors/inertial.rb +14 -0
- data/src/behaviors/magnetic.rb +34 -0
- data/src/behaviors/metered.rb +3 -0
- data/src/behaviors/movable.rb +81 -0
- data/src/behaviors/particle_emitter.rb +27 -0
- data/src/behaviors/physical.rb +384 -0
- data/src/behaviors/physical_cardinal_movable.rb +111 -0
- data/src/behaviors/physical_image.rb +45 -0
- data/src/behaviors/pointer.rb +30 -0
- data/src/behaviors/pressable.rb +17 -0
- data/src/behaviors/regional.rb +76 -0
- data/src/behaviors/rotates_to_point.rb +19 -0
- data/src/behaviors/spatial.rb +43 -0
- data/src/behaviors/stateful.rb +33 -0
- data/src/behaviors/taggable.rb +28 -0
- data/src/behaviors/tangible.rb +59 -0
- data/src/behaviors/timeable.rb +88 -0
- data/src/behaviors/top_down_vehicle.rb +42 -0
- data/src/behaviors/triangle_trail_emittable.rb +46 -0
- data/src/behaviors/unique.rb +0 -0
- data/src/behaviors/updates.rb +8 -0
- data/src/behaviors/updates_at_consistant_rate.rb +28 -0
- data/src/behaviors/vectored_movement.rb +48 -0
- data/src/behaviors/world_collidable.rb +9 -0
- data/src/color.rb +70 -0
- data/src/events/grid_changed_event.rb +8 -0
- data/src/events/physical_message.rb +9 -0
- data/src/events/tangible_collision_event.rb +8 -0
- data/src/file_system.rb +17 -0
- data/src/game.rb +110 -0
- data/src/game_object.rb +176 -0
- data/src/game_objects/background.rb +10 -0
- data/src/game_objects/fading_image.rb +23 -0
- data/src/game_objects/tangible_object.rb +4 -0
- data/src/game_objects/text.rb +71 -0
- data/src/game_objects/triangle_trail.rb +85 -0
- data/src/game_state.rb +164 -0
- data/src/inflector.rb +68 -0
- data/src/input_helpers/joystick_dead_zone_filter.rb +9 -0
- data/src/jemini.rb +31 -0
- data/src/jemini_version.rb +4 -0
- data/src/listenable_mixin.rb +15 -0
- data/src/logger_mixin.rb +11 -0
- data/src/managers/basic_game_object_manager.rb +95 -0
- data/src/managers/basic_physics_manager.rb +95 -0
- data/src/managers/basic_render_manager.rb +49 -0
- data/src/managers/basic_tile_manager.rb +3 -0
- data/src/managers/basic_update_manager.rb +30 -0
- data/src/managers/diagnostic/diagnostic_input_manager.rb +0 -0
- data/src/managers/input_manager.rb +161 -0
- data/src/managers/input_support/input_binding.rb +77 -0
- data/src/managers/input_support/input_builder.rb +44 -0
- data/src/managers/input_support/input_listener.rb +74 -0
- data/src/managers/input_support/input_message.rb +5 -0
- data/src/managers/input_support/joystick_listener.rb +53 -0
- data/src/managers/input_support/key_listener.rb +27 -0
- data/src/managers/input_support/mouse_listener.rb +38 -0
- data/src/managers/input_support/slick_input_listener.rb +20 -0
- data/src/managers/input_support/slick_input_message.rb +11 -0
- data/src/managers/input_support/slick_input_translator.rb +15 -0
- data/src/managers/message_queue.rb +60 -0
- data/src/managers/network_manager.rb +41 -0
- data/src/managers/render_support/hardware_cursor.rb +13 -0
- data/src/managers/resource_manager.rb +167 -0
- data/src/managers/sound_manager.rb +47 -0
- data/src/managers/tag_manager.rb +47 -0
- data/src/managers/tangible_manager.rb +36 -0
- data/src/math.rb +23 -0
- data/src/org/rubyforge/rawr/Main.java +67 -0
- data/src/platform.rb +28 -0
- data/src/proc_enhancement.rb +5 -0
- data/src/project_generator.rb +138 -0
- data/src/resource.rb +31 -0
- data/src/spline.rb +13 -0
- data/src/states/input_diagnostic_state.rb +53 -0
- data/src/vector.rb +143 -0
- data/test/test_state.rb +3 -0
- metadata +188 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#Makes an object receive an event when a given time period has elapsed.
|
|
2
|
+
class Timeable < Jemini::Behavior
|
|
3
|
+
depends_on :Updates
|
|
4
|
+
|
|
5
|
+
def load
|
|
6
|
+
@game_object.enable_listeners_for :timer_tick, :countdown_complete
|
|
7
|
+
@timers = {}
|
|
8
|
+
@game_object.on_update do |delta|
|
|
9
|
+
update_timers delta
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
#Add a countdown delay of the given number of seconds to the object.
|
|
14
|
+
#When the specified time has elapsed, a :countdown_complete event with the specified name will be passed to the object.
|
|
15
|
+
#If notify_frequency is specified, a :timer_tick event with the Timer object will be passed to the object each time the specified interval elapses.
|
|
16
|
+
def add_countdown(name, seconds, notify_frequency = nil)
|
|
17
|
+
@timers[name] = Timer.new(name, Timer::COUNTDOWN, seconds, notify_frequency) {|timer| @game_object.notify :timer_tick, timer }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
#Add a countup delay to the object. See add_countdown.
|
|
21
|
+
def add_countup(name, seconds, notify_frequency = nil)
|
|
22
|
+
@timers[name] = Timer.new(name, Timer::COUNTUP, seconds, notify_frequency) {|timer| @game_object.notify :timer_tick, timer }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
def update_timers(delta)
|
|
27
|
+
@timers.each do |name, timer|
|
|
28
|
+
timer.apply_delta delta
|
|
29
|
+
if timer.countdown_complete?
|
|
30
|
+
@game_object.notify :countdown_complete, name
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
# in order to keep from mutating the array while we iterate, handle separately.
|
|
34
|
+
@timers.delete_if {|name, timer| timer.countdown_complete? }
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
#Used to track how much time has elapsed.
|
|
39
|
+
class Timer
|
|
40
|
+
COUNTDOWN = :countdown
|
|
41
|
+
COUNTUP = :countup
|
|
42
|
+
def initialize(name, direction, seconds, notify_frequency, ¬ify_callback)
|
|
43
|
+
@name = name
|
|
44
|
+
@direction = direction
|
|
45
|
+
@milliseconds = seconds * 1000.0
|
|
46
|
+
@notify_frequency = notify_frequency * 1000.0 if notify_frequency
|
|
47
|
+
@notify_callback = notify_callback unless notify_frequency.nil?
|
|
48
|
+
@current_milliseconds = 0
|
|
49
|
+
@milliseconds_since_last_notify = 0
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
#Use the given elapsed time to determine if callbacks should be triggered.
|
|
53
|
+
def apply_delta(delta_in_milliseconds)
|
|
54
|
+
return if @countdown_complete
|
|
55
|
+
|
|
56
|
+
@current_milliseconds += delta_in_milliseconds
|
|
57
|
+
@milliseconds_since_last_notify += delta_in_milliseconds
|
|
58
|
+
|
|
59
|
+
if @notify_callback && @notify_frequency && (@milliseconds_since_last_notify >= @notify_frequency)
|
|
60
|
+
@notify_callback.call(self)
|
|
61
|
+
@milliseconds_since_last_notify = 0
|
|
62
|
+
end
|
|
63
|
+
@countdown_complete = true if (COUNTDOWN == @direction) && (@current_milliseconds >= @milliseconds)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def reset
|
|
67
|
+
@current_milliseconds = 0
|
|
68
|
+
@countdown_complete = false
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
#Number of timer ticks (notification periods) that have passed.
|
|
72
|
+
def ticks_elapsed
|
|
73
|
+
(@current_milliseconds / (@notify_frequency)).round
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
#Number of timer ticks (notification periods) left before the countdown/countup is complete.
|
|
77
|
+
def ticks_left
|
|
78
|
+
((@milliseconds - @current_milliseconds) / (@notify_frequency)).round
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def percent_complete
|
|
82
|
+
@current_milliseconds / @milliseconds
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def countdown_complete?
|
|
86
|
+
@countdown_complete
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#Allows an object to accelerate and turn within a 2D plane.
|
|
2
|
+
class TopDownVehicle < Jemini::Behavior
|
|
3
|
+
attr_accessor :minimum_speed_to_turn
|
|
4
|
+
alias_method :set_minimum_speed_to_turn, :minimum_speed_to_turn=
|
|
5
|
+
|
|
6
|
+
depends_on :VectoredMovement
|
|
7
|
+
|
|
8
|
+
def load
|
|
9
|
+
@vm_behavior = @game_object.send(:instance_variable_get, :@__behaviors)[:VectoredMovement]
|
|
10
|
+
@game_object.set_damping 0.1
|
|
11
|
+
@game_object.set_angular_damping 0.1
|
|
12
|
+
@minimum_speed_to_turn = 2.5
|
|
13
|
+
@vectored_movement_turning = false
|
|
14
|
+
|
|
15
|
+
#TODO: Replace this with a spline method that determines how far to turn based on the spline
|
|
16
|
+
@game_object.on_update do
|
|
17
|
+
if @turning && !@vectored_movement_turning && (@game_object.velocity.x.abs + @game_object.velocity.y.abs) > @minimum_speed_to_turn
|
|
18
|
+
@at_beginning_of_turn.call
|
|
19
|
+
@vectored_movement_turning = true
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def begin_acceleration(message)
|
|
25
|
+
@vm_behavior.begin_acceleration(message)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def end_acceleration(message)
|
|
29
|
+
@vm_behavior.end_acceleration(message)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def begin_turn(message)
|
|
33
|
+
@turning = true
|
|
34
|
+
@at_beginning_of_turn = Proc.new { @vm_behavior.begin_turn(message) }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def end_turn(message)
|
|
38
|
+
@turning = false
|
|
39
|
+
@vm_behavior.end_turn(message)
|
|
40
|
+
@vectored_movement_turning = false
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require 'behaviors/drawable'
|
|
2
|
+
|
|
3
|
+
#Makes an object draw a shrinking trail behind itself as it moves.
|
|
4
|
+
class TriangleTrailEmittable < Jemini::Behavior
|
|
5
|
+
#depends_on :Movable2d
|
|
6
|
+
depends_on :Updates
|
|
7
|
+
depends_on_kind_of :Spatial
|
|
8
|
+
|
|
9
|
+
def load
|
|
10
|
+
@emitter = game_state.create :TriangleTrail
|
|
11
|
+
@emitter_offset = [0,0]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@game_object.on_update do
|
|
15
|
+
@emitter.position = Vector.new(@emitter_offset[0] + @game_object.x, @emitter_offset[1] + @game_object.y)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def unload
|
|
20
|
+
game_state.remove @emitter
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
#Transparency to use. 1.0 is opaque. Default is 0.5.
|
|
24
|
+
def alpha
|
|
25
|
+
@emitter.alpha
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def alpha=(alpha)
|
|
29
|
+
@emitter.alpha = alpha
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
#Takes an Array with the relative x and y coordinates to begin the trail.
|
|
33
|
+
def emit_triangle_trail_from_offset(offset)
|
|
34
|
+
@emitter_offset = offset
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
#Specifies the half-width of the widest part of the trail.
|
|
38
|
+
def emit_triangle_trail_with_radius(radius)
|
|
39
|
+
@emitter.radius = radius
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
#Name of layer to draw trail on.
|
|
43
|
+
def layer=(layer_name)
|
|
44
|
+
game_state.manager(:game_object).move_game_object_to_layer(@emitter, layer_name)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
File without changes
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#Makes an object receive events when a time period has elapsed.
|
|
2
|
+
class UpdatesAtConsistantRate < Jemini::Behavior
|
|
3
|
+
attr_accessor :updates_per_second
|
|
4
|
+
|
|
5
|
+
def load
|
|
6
|
+
@update_delay = 0
|
|
7
|
+
@time_since_last_update = 0
|
|
8
|
+
@game_object.enable_listeners_for :update
|
|
9
|
+
self.updates_per_second = 30
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def updates_per_second=(count)
|
|
13
|
+
if 0 == count
|
|
14
|
+
@update_delay = 0
|
|
15
|
+
else
|
|
16
|
+
@update_delay = 1000 / count
|
|
17
|
+
end
|
|
18
|
+
@updates_per_second = count
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def update(delta_in_milliseconds)
|
|
22
|
+
@time_since_last_update += delta_in_milliseconds
|
|
23
|
+
if @time_since_last_update > @update_delay
|
|
24
|
+
@time_since_last_update -= @update_delay
|
|
25
|
+
notify :update
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#Makes an object move within a 2D plane.
|
|
2
|
+
class VectoredMovement < Jemini::Behavior
|
|
3
|
+
attr_accessor :forward_speed, :reverse_speed, :rotation_speed
|
|
4
|
+
alias_method :set_forward_speed, :forward_speed=
|
|
5
|
+
alias_method :set_reverse_speed, :reverse_speed=
|
|
6
|
+
alias_method :set_rotation_speed, :rotation_speed=
|
|
7
|
+
|
|
8
|
+
depends_on :Physical
|
|
9
|
+
depends_on :HandlesEvents
|
|
10
|
+
|
|
11
|
+
def load
|
|
12
|
+
@game_object.set_damping 0.0
|
|
13
|
+
@game_object.set_angular_damping 0.0
|
|
14
|
+
|
|
15
|
+
@forward_speed = 0
|
|
16
|
+
@reverse_speed = 0
|
|
17
|
+
@rotation_speed = 0
|
|
18
|
+
|
|
19
|
+
@intended_velocity = 0
|
|
20
|
+
@angular_velocity = 0
|
|
21
|
+
@movement_vector = Vector.new(0,0)
|
|
22
|
+
|
|
23
|
+
@game_object.on_update do
|
|
24
|
+
@game_object.set_angular_velocity(@angular_velocity)
|
|
25
|
+
@game_object.add_velocity(Vector.from_polar_vector(@intended_velocity, @game_object.rotation))
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def begin_acceleration(message)
|
|
30
|
+
@intended_velocity = :forward == message.value ? @forward_speed : @reverse_speed
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def end_acceleration(message)
|
|
34
|
+
@intended_velocity = 0
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def begin_turn(message)
|
|
38
|
+
if :clockwise == message.value
|
|
39
|
+
@angular_velocity = @rotation_speed
|
|
40
|
+
else
|
|
41
|
+
@angular_velocity = -@rotation_speed
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def end_turn(message)
|
|
46
|
+
@angular_velocity = 0
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
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
|
data/src/color.rb
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
class Color
|
|
2
|
+
attr_reader :native_color
|
|
3
|
+
|
|
4
|
+
def initialize(red_or_other, blue = 0.0, green = 0.0, alpha = 1.0)
|
|
5
|
+
if red_or_other.kind_of? Numeric
|
|
6
|
+
@native_color = new_native_color(red_or_other, blue, green, alpha)
|
|
7
|
+
else
|
|
8
|
+
# create from predefined Slick colors
|
|
9
|
+
fixed_color = Java::org::newdawn::slick::Color.send(red_or_other.to_s.downcase)
|
|
10
|
+
# 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)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def red
|
|
16
|
+
@native_color.r
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def blue
|
|
20
|
+
@native_color.b
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def green
|
|
24
|
+
@native_color.g
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def alpha
|
|
28
|
+
@native_color.a
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def transparency
|
|
32
|
+
1.0 - alpha
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def red=(new_red)
|
|
36
|
+
@native_color.r = new_red
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def green=(new_green)
|
|
40
|
+
@native_color.g = new_green
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def blue=(new_blue)
|
|
44
|
+
@native_color.b = new_blue
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def alpha=(new_alpha)
|
|
48
|
+
@native_color.a = new_alpha
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def transparency=(new_transparency)
|
|
52
|
+
self.alpha = 1.0 - new_transparency
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def darken_by(amount)
|
|
56
|
+
@native_color.darken amount
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def darken_by!(amount)
|
|
60
|
+
@native_color = @native_color.darken amount
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def fade_by(amount)
|
|
64
|
+
self.alpha = alpha * (1.0 - amount)
|
|
65
|
+
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
|
+
end
|
data/src/file_system.rb
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
class File
|
|
2
|
+
def self.in_jar?(path)
|
|
3
|
+
path =~ /(\.jar!)|(^-$)/
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def self.jar_of(path, jar_name=nil)
|
|
7
|
+
base_dir_plus_jar = path.split('.jar!').first
|
|
8
|
+
if jar_name
|
|
9
|
+
dirs = base_dir_plus_jar.split('/')
|
|
10
|
+
base_dir_plus_jar = (dirs[0..dirs.size - 2] + ['data']).join('/')
|
|
11
|
+
end
|
|
12
|
+
# jar_name = base_dir_plus_jar.split('/').last
|
|
13
|
+
# jar_name + '.jar'
|
|
14
|
+
base_dir_plus_jar.sub('file:', '') + '.jar'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
data/src/game.rb
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
module Jemini
|
|
2
|
+
class Game < Java::org::newdawn::slick::BasicGame
|
|
3
|
+
include_class 'org.newdawn.slick.AppGameContainer'
|
|
4
|
+
attr_accessor :screen_size, :fullscreen, :initial_state
|
|
5
|
+
|
|
6
|
+
def initialize(options={})
|
|
7
|
+
super(options[:screen_title] || 'Jemini Game')
|
|
8
|
+
@initial_state = options[:initial_state] || :MainState
|
|
9
|
+
@screen_size = options[:screen_size] || Vector.new(800, 600)
|
|
10
|
+
@fullscreen = options[:fullscreen]
|
|
11
|
+
@always_render = !!options[:always_render] # coercing to boolean, always_render can't be nil/null
|
|
12
|
+
@fresh_state = true
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def init(container)
|
|
16
|
+
@container = container
|
|
17
|
+
@container.always_render = @always_render
|
|
18
|
+
GameState.active_state = load_state(@initial_state)
|
|
19
|
+
GameState.active_state.load
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# depcrecated
|
|
23
|
+
def screen_width
|
|
24
|
+
screen_size.x
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# depcrecated
|
|
28
|
+
def screen_height
|
|
29
|
+
screen_size.y
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def app
|
|
33
|
+
@app ||= create_app
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def canvas
|
|
37
|
+
@canvas ||= create_canvas
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def update(container, delta)
|
|
41
|
+
#don't tell the new state that it now has to update load time worth of a delta
|
|
42
|
+
if @fresh_state
|
|
43
|
+
delta = 0
|
|
44
|
+
@fresh_state = false
|
|
45
|
+
end
|
|
46
|
+
# Workaround for image loading with Slick.
|
|
47
|
+
# Must be done in game init or game loop (instead of immediately in the event).
|
|
48
|
+
if @queued_state
|
|
49
|
+
# @queued_state.load_resources
|
|
50
|
+
game_state = load_state(*@queued_state)
|
|
51
|
+
game_state.load(*@state_args)
|
|
52
|
+
GameState.active_state = game_state
|
|
53
|
+
@queued_state = nil
|
|
54
|
+
@fresh_state = true
|
|
55
|
+
return
|
|
56
|
+
end
|
|
57
|
+
GameState.active_state.manager(:input).poll(screen_size.x, screen_size.y, delta)
|
|
58
|
+
GameState.active_state.manager(:message_queue).process_messages(delta)
|
|
59
|
+
GameState.active_state.manager(:update).update(delta)
|
|
60
|
+
GameState.active_state.manager(:game_object).__process_pending_game_objects
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def render(container, graphics)
|
|
64
|
+
GameState.active_state.manager(:render).render(graphics)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def load_state(state_name, args = [])
|
|
68
|
+
require "states/#{state_name.underscore}" unless Object.const_defined? state_name.camelize
|
|
69
|
+
@state_args = args
|
|
70
|
+
state_name.camelize.constantize.new @container, self
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def switch_state(state_name)
|
|
74
|
+
queue_state load_state(state_name)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def queue_state(state, *args)
|
|
78
|
+
@queued_state = [state, *args]
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def fresh_state?
|
|
82
|
+
@fresh_state
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def active_state
|
|
86
|
+
GameState.active_state
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
private
|
|
90
|
+
def create_app
|
|
91
|
+
@app = AppGameContainer.new(self, screen_size.x, screen_size.y, fullscreen)
|
|
92
|
+
@app.vsync = false
|
|
93
|
+
@app.maximum_logic_update_interval = 60
|
|
94
|
+
@app.smooth_deltas = false #true
|
|
95
|
+
#main.container = container
|
|
96
|
+
@app.start
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def create_canvas
|
|
100
|
+
@canvas = Java::org::newdawn::slick::CanvasGameContainer.new(self)
|
|
101
|
+
@canvas.set_size(screen_size.x, screen_size.y)
|
|
102
|
+
container = @canvas.container
|
|
103
|
+
container.vsync = false
|
|
104
|
+
container.maximum_logic_update_interval = 60
|
|
105
|
+
#container.start
|
|
106
|
+
@canvas
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
end
|
|
110
|
+
end
|