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,13 @@
|
|
|
1
|
+
module HardwareCursor
|
|
2
|
+
def use_available_hardware_cursor
|
|
3
|
+
resource_manager = game_state.manager(:resource)
|
|
4
|
+
resource_manager.on_resources_loaded do
|
|
5
|
+
cursor_resource = resource_manager.get_image(:mouse_cursor) rescue nil
|
|
6
|
+
game_state.container.set_mouse_cursor(cursor_resource, 0, 0) if cursor_resource
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def revert_hardware_cursor
|
|
11
|
+
game_state.container.set_default_mouse_cursor
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
require 'resource'
|
|
2
|
+
|
|
3
|
+
class ResourceManager < Jemini::GameObject
|
|
4
|
+
java_import 'org.newdawn.slick.Image'
|
|
5
|
+
java_import 'org.newdawn.slick.Music'
|
|
6
|
+
java_import 'org.newdawn.slick.Sound'
|
|
7
|
+
|
|
8
|
+
#Sets a default data directory path of "data".
|
|
9
|
+
def load
|
|
10
|
+
enable_listeners_for :resources_loaded
|
|
11
|
+
@images = {}
|
|
12
|
+
@sounds = {}
|
|
13
|
+
@songs = {}
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
#Load resources for the given state.
|
|
17
|
+
#Uses the current state if none specified.
|
|
18
|
+
def load_resources(state_name = nil)
|
|
19
|
+
state_name ||= game_state.name
|
|
20
|
+
log.debug "Loading resources for state: #{state_name}"
|
|
21
|
+
subdirectory = File.join(Jemini::Resource.base_path, state_name)
|
|
22
|
+
log.debug "Looking for subdirectory: #{subdirectory}"
|
|
23
|
+
load_directory(subdirectory) if File.directory?(subdirectory) || File.in_jar?(subdirectory)
|
|
24
|
+
load_directory(Jemini::Resource.base_path, true)
|
|
25
|
+
notify :resources_loaded
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
#Load the image at the given path, and make it accessible via the given key.
|
|
29
|
+
def cache_image(key, path)
|
|
30
|
+
log.debug "Caching image for #{key} with path: #{path}"
|
|
31
|
+
log.warn "Skipping duplicate image for #{key} with path: #{path}" and return if @images[key]
|
|
32
|
+
@images[key] = load_resource(path, :image)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
#Load the sound at the given path, and make it accessible via the given key.
|
|
36
|
+
def cache_sound(key, path)
|
|
37
|
+
log.debug "Caching sound for #{key} with path: #{path}"
|
|
38
|
+
log.warn "Skipping duplicate sound for #{key} with path: #{path}" and return if @sounds[key]
|
|
39
|
+
@sounds[key] = load_resource(path, :sound)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
#Load the song at the given path, and make it accessible via the given key.
|
|
43
|
+
def cache_song(key, path)
|
|
44
|
+
log.debug "Caching song for #{key} with path: #{path}"
|
|
45
|
+
log.warn "Skipping duplicate song for #{key} with path: #{path}" and return if @songs[key]
|
|
46
|
+
@songs[key] = load_resource(path, :music)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
#Get an image stored previously with cache_image.
|
|
50
|
+
def get_image(key)
|
|
51
|
+
@images[key] or raise "Could not find image: #{key} - cached images: #{@images.keys}"
|
|
52
|
+
end
|
|
53
|
+
alias_method :image, :get_image
|
|
54
|
+
|
|
55
|
+
#Get all images stored previously with cache_image.
|
|
56
|
+
def get_all_images
|
|
57
|
+
@images.values
|
|
58
|
+
end
|
|
59
|
+
alias_method :images, :get_all_images
|
|
60
|
+
|
|
61
|
+
def image_names
|
|
62
|
+
@images.keys
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
#Get a sound stored previously with cache_sound.
|
|
66
|
+
def get_sound(key)
|
|
67
|
+
@sounds[key] or raise "Could not find sound: #{key}"
|
|
68
|
+
end
|
|
69
|
+
alias_method :sound, :get_sound
|
|
70
|
+
|
|
71
|
+
#Get all sounds stored previously with cache_sound.
|
|
72
|
+
def get_all_sounds
|
|
73
|
+
@sounds.values
|
|
74
|
+
end
|
|
75
|
+
alias_method :sounds, :get_all_sounds
|
|
76
|
+
|
|
77
|
+
#Get a song stored previously with cache_song.
|
|
78
|
+
def get_song(key)
|
|
79
|
+
@songs[key] or raise "Could not find song: #{key}"
|
|
80
|
+
end
|
|
81
|
+
alias_method :song, :get_song
|
|
82
|
+
|
|
83
|
+
#Get all songs stored previously with cache_song.
|
|
84
|
+
def get_all_songs
|
|
85
|
+
@songs.values
|
|
86
|
+
end
|
|
87
|
+
alias_method :songs, :get_all_songs
|
|
88
|
+
|
|
89
|
+
private
|
|
90
|
+
|
|
91
|
+
def load_resource(path, type_name)
|
|
92
|
+
# 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))
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# root dirs can't be skipped
|
|
105
|
+
def load_directory(directory, root = false)
|
|
106
|
+
log.debug "Loading contents of #{directory}"
|
|
107
|
+
begin
|
|
108
|
+
#Dir.open(directory).each do |file|
|
|
109
|
+
resources_for(directory).each do |file|
|
|
110
|
+
next if file =~ /^\./
|
|
111
|
+
# path = File.join(directory, file)
|
|
112
|
+
path = File.in_jar?(directory) ? file : File.join(directory, file)
|
|
113
|
+
log.debug "Dir in jar? #{File.in_jar?(directory)}"
|
|
114
|
+
log.debug "Using path #{path} for #{file}"
|
|
115
|
+
# File.file? doesn't work in a jar.
|
|
116
|
+
# next unless File.file?(path)
|
|
117
|
+
extension = File.extname(file).downcase
|
|
118
|
+
key = File.basename(file, extension).downcase.to_sym
|
|
119
|
+
log.debug "Extension: #{extension}"
|
|
120
|
+
case extension
|
|
121
|
+
when '.png', '.gif'
|
|
122
|
+
cache_image(key, path)
|
|
123
|
+
when '.wav'
|
|
124
|
+
cache_sound(key, path)
|
|
125
|
+
when '.ogg'
|
|
126
|
+
cache_song(key, path)
|
|
127
|
+
else
|
|
128
|
+
log.warn "Skipping unknown file: #{path}"
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
rescue Errno::ENOENT => e
|
|
132
|
+
if root
|
|
133
|
+
raise
|
|
134
|
+
else
|
|
135
|
+
log.debug "#{directory} directory not found. Skipping."
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def resources_for(directory)
|
|
141
|
+
if File.in_jar?(directory)
|
|
142
|
+
scan_entire_jar(directory)
|
|
143
|
+
else
|
|
144
|
+
log.debug "opening #{directory}"
|
|
145
|
+
Dir.open(directory)
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# globs MUST start at the base dir of the jar, or it won't work.
|
|
150
|
+
def scan_entire_jar(directory)
|
|
151
|
+
just_dir = File.basename(directory)
|
|
152
|
+
log.debug "just dir: #{just_dir}"
|
|
153
|
+
log.debug "dir: #{directory}"
|
|
154
|
+
jar_name = File.jar_of(directory, 'data') # we're always going to get our data from the data jar
|
|
155
|
+
log.debug "opening jar #{jar_name}"
|
|
156
|
+
jar_file = java.util.jar.JarFile.new(jar_name)
|
|
157
|
+
dir_regex = Regexp.new(just_dir)
|
|
158
|
+
all_entries = jar_file.entries.map {|e| e.name }
|
|
159
|
+
entries_under_directory = all_entries.select {|e| e =~ dir_regex }
|
|
160
|
+
# need a shallow resultset
|
|
161
|
+
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
|
+
entries_directly_under_directory
|
|
166
|
+
end
|
|
167
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
class SoundManager < Jemini::GameObject
|
|
2
|
+
#TODO: Raise errors if sounds/music loaded/used when not on the proper thread?
|
|
3
|
+
#TODO: We can't play oggs as sounds in Windows/Linux. We get an Open AL error: 40963
|
|
4
|
+
#Wrapper for org.newdawn.slick.Sound.
|
|
5
|
+
class Sound < Java::org::newdawn::slick::Sound; end
|
|
6
|
+
class Music < Java::org::newdawn::slick::Music; end
|
|
7
|
+
|
|
8
|
+
def load
|
|
9
|
+
@sounds = {}
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def unload
|
|
13
|
+
stop_all
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
#Takes a reference to a sound loaded via the resource manager, and plays it.
|
|
17
|
+
#volume is 0.0 for silence, 1.0 for normal volume, or higher values for amplified volume.
|
|
18
|
+
#pitch is 1.0 for original pitch. Lower or higher values will bend the pitch accordingly.
|
|
19
|
+
def play_sound(reference, volume = 1.0, pitch = 1.0)
|
|
20
|
+
game_state.manager(:resource).get_sound(reference).play(pitch, volume)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
#Stop playback of all sounds.
|
|
24
|
+
def stop_all
|
|
25
|
+
@song.stop if @song
|
|
26
|
+
game_state.manager(:resource).get_all_sounds.each {|s| s.stop if s.playing}
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
#Takes a reference to a song loaded via the resource manager, and plays it.
|
|
30
|
+
#volume is 0.0 for silence, 1.0 for normal volume, or higher values for amplified volume.
|
|
31
|
+
def play_song(reference, volume=1.0)
|
|
32
|
+
@song.stop if @song
|
|
33
|
+
@song = game_state.manager(:resource).get_song(reference)
|
|
34
|
+
@song.play
|
|
35
|
+
@song.volume = volume if volume != 1.0 #Volume must be set AFTER play is called.
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
#Takes a reference to a song loaded via the resource manager, and plays it in a loop.
|
|
39
|
+
#volume is 0.0 for silence, 1.0 for normal volume, or higher values for amplified volume.
|
|
40
|
+
def loop_song(reference, volume=1.0)
|
|
41
|
+
@song.stop if @song
|
|
42
|
+
@song = game_state.manager(:resource).get_song(reference)
|
|
43
|
+
@song.loop
|
|
44
|
+
@song.volume = volume if volume != 1.0 #Volume must be set AFTER loop is called.
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#Tracks tags applied to objects.
|
|
2
|
+
class TagManager < Jemini::GameObject
|
|
3
|
+
def load
|
|
4
|
+
require 'behaviors/taggable'
|
|
5
|
+
@tagged_objects = Hash.new { |h,k| h[k] = [] }
|
|
6
|
+
listen_for(:after_add_game_object, game_state.manager(:game_object)) do |game_object|
|
|
7
|
+
if game_object.has_behavior? :Taggable
|
|
8
|
+
game_object.tags.each do |tag|
|
|
9
|
+
@tagged_objects[tag] << game_object
|
|
10
|
+
end
|
|
11
|
+
listen_for(:tag_added, game_object) do |tag|
|
|
12
|
+
@tagged_objects[tag] << game_object
|
|
13
|
+
end
|
|
14
|
+
listen_for(:tag_removed, game_object) do |tag|
|
|
15
|
+
@tagged_objects[tag].delete game_object
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
listen_for(:after_remove_game_object, game_state.manager(:game_object)) do |game_object|
|
|
21
|
+
if game_object.has_behavior? :Taggable
|
|
22
|
+
game_object.tags.each do |tag|
|
|
23
|
+
@tagged_objects[tag].delete game_object
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
#Returns all game objects that have all the given tags.
|
|
30
|
+
def find_by_all_tags(*tags)
|
|
31
|
+
tags[1..-1].inject(@tagged_objects[tags[0]]) do |results, tag|
|
|
32
|
+
results & @tagged_objects[tag]
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
#Returns all game objects that have any of the given tags.
|
|
37
|
+
def find_by_any_tags(*tags)
|
|
38
|
+
tags.inject([]) do |results, tag|
|
|
39
|
+
results.concat @tagged_objects[tag]
|
|
40
|
+
end.uniq
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
#Returns all game objects that have the given tag.
|
|
44
|
+
def find_by_tag(tag)
|
|
45
|
+
@tagged_objects[tag]
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require 'behaviors/tangible'
|
|
2
|
+
require 'events/tangible_collision_event'
|
|
3
|
+
|
|
4
|
+
class TangibleManager < Jemini::GameObject
|
|
5
|
+
has_behavior :HandlesEvents
|
|
6
|
+
has_behavior :Updates
|
|
7
|
+
|
|
8
|
+
def load
|
|
9
|
+
handle_event :toggle_debug_mode, :toggle_debug_mode
|
|
10
|
+
on_update :check_for_collisions
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def check_for_collisions(delta)
|
|
14
|
+
game_state.manager(:game_object).game_objects.each do |game_object|
|
|
15
|
+
next unless game_object.has_behavior? :Tangible
|
|
16
|
+
game_state.manager(:game_object).game_objects.each do |other_game_object|
|
|
17
|
+
next unless other_game_object.has_behavior? :Tangible
|
|
18
|
+
next if game_object == other_game_object
|
|
19
|
+
if game_object.tangibly_collides_with?(other_game_object)
|
|
20
|
+
game_object.notify :tangible_collision, TangibleCollisionEvent.new(other_game_object, delta)
|
|
21
|
+
other_game_object.notify :tangible_collision, TangibleCollisionEvent.new(game_object, delta)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def toggle_debug_mode(unused_message=nil)
|
|
28
|
+
@debug_mode = !@debug_mode
|
|
29
|
+
@game_state.manager(:game_object).game_objects.each do |game_object|
|
|
30
|
+
game_object.set_tangible_debug_mode(@debug_mode) if game_object.has_behavior? :Tangible
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
end
|
data/src/math.rb
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Jemini
|
|
2
|
+
class Math
|
|
3
|
+
SQUARE_ROOT_OF_TWO = ::Math::sqrt(2.0)
|
|
4
|
+
|
|
5
|
+
def self.degrees_to_radians(degrees)
|
|
6
|
+
degrees * (::Math::PI/180.0)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.radians_to_degrees(radians)
|
|
10
|
+
radians * (180.0/::Math::PI)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
module FloatHelpers
|
|
15
|
+
def near?(numeric, percent)
|
|
16
|
+
self <= (numeric + numeric * percent) && self >= (numeric - numeric * percent)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class Float
|
|
22
|
+
include Jemini::FloatHelpers
|
|
23
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
package org.rubyforge.rawr;
|
|
2
|
+
|
|
3
|
+
import java.io.BufferedReader;
|
|
4
|
+
import java.io.InputStreamReader;
|
|
5
|
+
import java.io.InputStream;
|
|
6
|
+
import java.io.IOException;
|
|
7
|
+
import java.net.URL;
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
import java.util.ArrayList;
|
|
11
|
+
import org.jruby.Ruby;
|
|
12
|
+
import org.jruby.RubyInstanceConfig;
|
|
13
|
+
import org.jruby.javasupport.JavaEmbedUtils;
|
|
14
|
+
|
|
15
|
+
public class Main
|
|
16
|
+
{
|
|
17
|
+
public static void main(String[] args) throws Exception
|
|
18
|
+
{
|
|
19
|
+
RubyInstanceConfig config = new RubyInstanceConfig();
|
|
20
|
+
config.setArgv(args);
|
|
21
|
+
Ruby runtime = JavaEmbedUtils.initialize(new ArrayList(0), config);
|
|
22
|
+
String mainRubyFile = "main";
|
|
23
|
+
|
|
24
|
+
ArrayList<String> config_data = new ArrayList<String>();
|
|
25
|
+
try{
|
|
26
|
+
java.io.InputStream ins = Main.class.getClassLoader().getResourceAsStream("run_configuration");
|
|
27
|
+
if (ins == null ) {
|
|
28
|
+
System.err.println("Did not find configuration file 'run_configuration', using defaults.");
|
|
29
|
+
} else {
|
|
30
|
+
config_data = getConfigFileContents(ins);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch(IOException ioe)
|
|
34
|
+
{
|
|
35
|
+
System.err.println("Error loading run configuration file 'run_configuration', using defaults: " + ioe);
|
|
36
|
+
}
|
|
37
|
+
catch(java.lang.NullPointerException npe)
|
|
38
|
+
{
|
|
39
|
+
System.err.println("Error loading run configuration file 'run_configuration', using defaults: " + npe );
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
for(String line : config_data) {
|
|
43
|
+
String[] parts = line.split(":");
|
|
44
|
+
if("main_ruby_file".equals(parts[0].replaceAll(" ", ""))) {
|
|
45
|
+
mainRubyFile = parts[1].replaceAll(" ", "");
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
runtime.evalScriptlet("require '" + mainRubyFile + "'");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public static URL getResource(String path) {
|
|
53
|
+
return Main.class.getClassLoader().getResource(path);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private static ArrayList<String> getConfigFileContents(InputStream input) throws IOException, java.lang.NullPointerException {
|
|
57
|
+
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
|
|
58
|
+
String line;
|
|
59
|
+
ArrayList<String> contents = new ArrayList<String>();
|
|
60
|
+
|
|
61
|
+
while ((line = reader.readLine()) != null) {
|
|
62
|
+
contents.add(line);
|
|
63
|
+
}
|
|
64
|
+
reader.close();
|
|
65
|
+
return(contents);
|
|
66
|
+
}
|
|
67
|
+
}
|
data/src/platform.rb
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'rbconfig'
|
|
2
|
+
|
|
3
|
+
module Platform
|
|
4
|
+
|
|
5
|
+
@@operating_system = Config::CONFIG['host_os']
|
|
6
|
+
|
|
7
|
+
def using_unix?
|
|
8
|
+
@using_unix ||= !using_windows?
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def using_windows?
|
|
12
|
+
@using_windows ||= (@@operating_system =~ /^win|mswin/i)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def using_linux?
|
|
16
|
+
@using_linux ||= (@@operating_system =~ /linux/)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def using_osx?
|
|
20
|
+
@using_osx ||= (@@operating_system =~ /darwin/)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def argument_delimiter
|
|
24
|
+
using_windows? ? ';' : ':'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
module_function :using_unix?, :using_windows?, :using_osx?, :argument_delimiter, :using_linux?
|
|
28
|
+
end
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
#require 'rawr'
|
|
3
|
+
|
|
4
|
+
module Jemini
|
|
5
|
+
class ProjectGenerator
|
|
6
|
+
include FileUtils
|
|
7
|
+
|
|
8
|
+
def initialize(options)
|
|
9
|
+
@project_dir = options[:project_dir]
|
|
10
|
+
@project_title = options[:project_title]
|
|
11
|
+
@rawr_install_args = options[:rawr_install]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def generate_project
|
|
15
|
+
generate_default_dirs
|
|
16
|
+
generate_main
|
|
17
|
+
# generate_main_with_natives
|
|
18
|
+
copy_libs
|
|
19
|
+
rawr_install
|
|
20
|
+
generate_hello_world_state
|
|
21
|
+
copy_jemini_jar
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def generate_main
|
|
25
|
+
mkdir_p File.expand_path(File.join(@project_dir, 'src'))
|
|
26
|
+
path = File.expand_path(File.join(@project_dir, 'src', 'main.rb'))
|
|
27
|
+
|
|
28
|
+
File.open(path, "w") do |f|
|
|
29
|
+
f << <<-ENDL
|
|
30
|
+
require 'java'
|
|
31
|
+
|
|
32
|
+
$LOAD_PATH.clear
|
|
33
|
+
$LOAD_PATH << File.expand_path(File.dirname(__FILE__))
|
|
34
|
+
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), 'game_objects'))
|
|
35
|
+
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), 'managers'))
|
|
36
|
+
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), 'states'))
|
|
37
|
+
|
|
38
|
+
# only when running in non-standalone
|
|
39
|
+
if File.exist? File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'java'))
|
|
40
|
+
jar_glob = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'java', '*.jar'))
|
|
41
|
+
Dir.glob(jar_glob).each do |jar|
|
|
42
|
+
$CLASSPATH << jar
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
%w{behaviors game_objects input_helpers input_mappings states}.each do |dir|
|
|
46
|
+
$LOAD_PATH << "src/\#{dir}"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
require 'jemini'
|
|
50
|
+
|
|
51
|
+
begin
|
|
52
|
+
# Change :HelloState to point to the initial state of your game
|
|
53
|
+
game = Jemini::Game.new :title => 'Jemini Game',
|
|
54
|
+
:screen_size => Vector.new(800, 600),
|
|
55
|
+
:initial_state => :HelloWorldState,
|
|
56
|
+
:fullscreen => false
|
|
57
|
+
game.app
|
|
58
|
+
rescue => e
|
|
59
|
+
warn e
|
|
60
|
+
warn e.backtrace
|
|
61
|
+
end
|
|
62
|
+
ENDL
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def generate_main_with_natives
|
|
67
|
+
mkdir_p File.expand_path(File.join(@project_dir, 'src'))
|
|
68
|
+
path = File.expand_path(File.join(@project_dir, 'src', 'main_with_natives.rb'))
|
|
69
|
+
File.open(path, "w") do |f|
|
|
70
|
+
f << <<-ENDL
|
|
71
|
+
system("jruby -J-Djava.library.path=lib/native_files \#{File.expand_path(File.join(File.dirname(__FILE__)), 'main.rb')}")
|
|
72
|
+
ENDL
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def copy_jemini_jar
|
|
77
|
+
destination = File.expand_path(File.join(@project_dir, 'lib', 'java'))
|
|
78
|
+
source = File.expand_path(File.join(File.dirname(__FILE__), '..', 'package', 'jar', 'jemini.jar'))
|
|
79
|
+
|
|
80
|
+
mkdir_p destination
|
|
81
|
+
cp source, destination
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
#TODO: Implement
|
|
85
|
+
def build_jemini_jar
|
|
86
|
+
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def generate_default_dirs
|
|
90
|
+
mkdir_p File.expand_path(File.join(@project_dir, 'data'))
|
|
91
|
+
mkdir_p File.expand_path(File.join(@project_dir, 'src', 'behaviors'))
|
|
92
|
+
mkdir_p File.expand_path(File.join(@project_dir, 'src', 'game_objects'))
|
|
93
|
+
mkdir_p File.expand_path(File.join(@project_dir, 'src', 'inputs'))
|
|
94
|
+
mkdir_p File.expand_path(File.join(@project_dir, 'src', 'states'))
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def generate_hello_world_state
|
|
98
|
+
mkdir_p File.expand_path(File.join(@project_dir, 'src', 'states'))
|
|
99
|
+
path = File.expand_path(File.join(@project_dir, 'src', 'states', 'hello_world_state.rb'))
|
|
100
|
+
File.open(path, "w") do |f|
|
|
101
|
+
f << <<-ENDL
|
|
102
|
+
class HelloWorldState < Jemini::GameState
|
|
103
|
+
def load
|
|
104
|
+
create(:Text,
|
|
105
|
+
"Now, place your own state code in the src/states folder!",
|
|
106
|
+
:position => Vector.new(screen_width / 2, screen_height / 2)
|
|
107
|
+
)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
ENDL
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def rawr_install
|
|
115
|
+
mkdir_p @project_dir
|
|
116
|
+
# TODO: Replace with equivalent of Rake's FileUtils.sh method
|
|
117
|
+
puts `rawr install #{@rawr_install_args} #{@project_dir}`
|
|
118
|
+
build_config_path = File.join(@project_dir, 'build_configuration.rb')
|
|
119
|
+
build_config = File.read build_config_path
|
|
120
|
+
build_config.sub!('#c.java_library_path = "lib/java/native"', 'c.java_library_path = "lib/java/native_files"')
|
|
121
|
+
build_config.sub!('#c.jvm_arguments = "-server"', 'c.jvm_arguments = "-XX:+UseConcMarkSweepGC -Djruby.compile.mode=FORCE -Xms256m -Xmx512m"')
|
|
122
|
+
build_config.sub!(%Q{#c.jars[:data] = { :directory => 'data/images', :location_in_jar => 'images', :exclude => /bak/}}, %Q{c.jars[:data] = { :directory => 'data', :location_in_jar => 'data', :exclude => /bak/}})
|
|
123
|
+
build_config.sub!(%Q{#c.files_to_copy = Dir['other_files/dir/**/*']}, %Q{c.files_to_copy = Dir['lib/java/native_files/**/*']})
|
|
124
|
+
File.open(build_config_path, 'w') {|f| f << build_config}
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def copy_libs
|
|
128
|
+
mkdir_p File.expand_path(File.join(@project_dir, 'lib', 'java'))
|
|
129
|
+
copy_libs = %w{ibxm.jar jinput.jar jogg-0.0.7.jar jorbis-0.0.15.jar lwjgl.jar lwjgl_util_applet.jar natives-linux.jar natives-mac.jar natives-win32.jar phys2d.jar slick.jar}
|
|
130
|
+
copy_libs.each do |copy_lib|
|
|
131
|
+
from = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', copy_lib))
|
|
132
|
+
cp from, File.join(@project_dir, 'lib', 'java')
|
|
133
|
+
end
|
|
134
|
+
# mkdir_p File.expand_path(File.join(@project_dir, 'lib', 'java', 'native_libs'))
|
|
135
|
+
cp_r File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'native_files')) + '/', File.join(@project_dir, 'lib', 'java', 'native_files')
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|