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.
Files changed (127) hide show
  1. data/README.txt +9 -0
  2. data/bin/jemini +26 -0
  3. data/lib/ibxm.jar +0 -0
  4. data/lib/jinput.jar +0 -0
  5. data/lib/jogg-0.0.7.jar +0 -0
  6. data/lib/jorbis-0.0.15.jar +0 -0
  7. data/lib/jruby-complete.jar +0 -0
  8. data/lib/lwjgl.jar +0 -0
  9. data/lib/lwjgl_util_applet.jar +0 -0
  10. data/lib/native_files/OpenAL32.dll +0 -0
  11. data/lib/native_files/jinput-dx8.dll +0 -0
  12. data/lib/native_files/jinput-dx8_64.dll +0 -0
  13. data/lib/native_files/jinput-raw.dll +0 -0
  14. data/lib/native_files/jinput-raw_64.dll +0 -0
  15. data/lib/native_files/jinput-wintab.dll +0 -0
  16. data/lib/native_files/libjinput-linux.so +0 -0
  17. data/lib/native_files/libjinput-linux64.so +0 -0
  18. data/lib/native_files/libjinput-osx.jnilib +0 -0
  19. data/lib/native_files/liblwjgl.jnilib +0 -0
  20. data/lib/native_files/liblwjgl.so +0 -0
  21. data/lib/native_files/liblwjgl64.so +0 -0
  22. data/lib/native_files/libopenal.so +0 -0
  23. data/lib/native_files/lwjgl.dll +0 -0
  24. data/lib/native_files/openal.dylib +0 -0
  25. data/lib/natives-linux.jar +0 -0
  26. data/lib/natives-mac.jar +0 -0
  27. data/lib/natives-win32.jar +0 -0
  28. data/lib/phys2d.jar +0 -0
  29. data/lib/slick.jar +0 -0
  30. data/package/jar/jemini.jar +0 -0
  31. data/src/behavior.rb +248 -0
  32. data/src/behavior_event.rb +23 -0
  33. data/src/behaviors/animated_image.rb +88 -0
  34. data/src/behaviors/audible.rb +16 -0
  35. data/src/behaviors/axis_stateful.rb +35 -0
  36. data/src/behaviors/bounding_box_collidable.rb +27 -0
  37. data/src/behaviors/cardinal_movable.rb +121 -0
  38. data/src/behaviors/clickable.rb +19 -0
  39. data/src/behaviors/countable.rb +32 -0
  40. data/src/behaviors/debug_physical.rb +43 -0
  41. data/src/behaviors/debug_tangible.rb +31 -0
  42. data/src/behaviors/drawable.rb +7 -0
  43. data/src/behaviors/drawable_image.rb +111 -0
  44. data/src/behaviors/drawable_line.rb +32 -0
  45. data/src/behaviors/drawable_shape.rb +48 -0
  46. data/src/behaviors/fading_image_trail_emittable.rb +32 -0
  47. data/src/behaviors/game_object_emittable.rb +13 -0
  48. data/src/behaviors/grid_bound.rb +108 -0
  49. data/src/behaviors/handles_events.rb +33 -0
  50. data/src/behaviors/inertial.rb +14 -0
  51. data/src/behaviors/magnetic.rb +34 -0
  52. data/src/behaviors/metered.rb +3 -0
  53. data/src/behaviors/movable.rb +81 -0
  54. data/src/behaviors/particle_emitter.rb +27 -0
  55. data/src/behaviors/physical.rb +384 -0
  56. data/src/behaviors/physical_cardinal_movable.rb +111 -0
  57. data/src/behaviors/physical_image.rb +45 -0
  58. data/src/behaviors/pointer.rb +30 -0
  59. data/src/behaviors/pressable.rb +17 -0
  60. data/src/behaviors/regional.rb +76 -0
  61. data/src/behaviors/rotates_to_point.rb +19 -0
  62. data/src/behaviors/spatial.rb +43 -0
  63. data/src/behaviors/stateful.rb +33 -0
  64. data/src/behaviors/taggable.rb +28 -0
  65. data/src/behaviors/tangible.rb +59 -0
  66. data/src/behaviors/timeable.rb +88 -0
  67. data/src/behaviors/top_down_vehicle.rb +42 -0
  68. data/src/behaviors/triangle_trail_emittable.rb +46 -0
  69. data/src/behaviors/unique.rb +0 -0
  70. data/src/behaviors/updates.rb +8 -0
  71. data/src/behaviors/updates_at_consistant_rate.rb +28 -0
  72. data/src/behaviors/vectored_movement.rb +48 -0
  73. data/src/behaviors/world_collidable.rb +9 -0
  74. data/src/color.rb +70 -0
  75. data/src/events/grid_changed_event.rb +8 -0
  76. data/src/events/physical_message.rb +9 -0
  77. data/src/events/tangible_collision_event.rb +8 -0
  78. data/src/file_system.rb +17 -0
  79. data/src/game.rb +110 -0
  80. data/src/game_object.rb +176 -0
  81. data/src/game_objects/background.rb +10 -0
  82. data/src/game_objects/fading_image.rb +23 -0
  83. data/src/game_objects/tangible_object.rb +4 -0
  84. data/src/game_objects/text.rb +71 -0
  85. data/src/game_objects/triangle_trail.rb +85 -0
  86. data/src/game_state.rb +164 -0
  87. data/src/inflector.rb +68 -0
  88. data/src/input_helpers/joystick_dead_zone_filter.rb +9 -0
  89. data/src/jemini.rb +31 -0
  90. data/src/jemini_version.rb +4 -0
  91. data/src/listenable_mixin.rb +15 -0
  92. data/src/logger_mixin.rb +11 -0
  93. data/src/managers/basic_game_object_manager.rb +95 -0
  94. data/src/managers/basic_physics_manager.rb +95 -0
  95. data/src/managers/basic_render_manager.rb +49 -0
  96. data/src/managers/basic_tile_manager.rb +3 -0
  97. data/src/managers/basic_update_manager.rb +30 -0
  98. data/src/managers/diagnostic/diagnostic_input_manager.rb +0 -0
  99. data/src/managers/input_manager.rb +161 -0
  100. data/src/managers/input_support/input_binding.rb +77 -0
  101. data/src/managers/input_support/input_builder.rb +44 -0
  102. data/src/managers/input_support/input_listener.rb +74 -0
  103. data/src/managers/input_support/input_message.rb +5 -0
  104. data/src/managers/input_support/joystick_listener.rb +53 -0
  105. data/src/managers/input_support/key_listener.rb +27 -0
  106. data/src/managers/input_support/mouse_listener.rb +38 -0
  107. data/src/managers/input_support/slick_input_listener.rb +20 -0
  108. data/src/managers/input_support/slick_input_message.rb +11 -0
  109. data/src/managers/input_support/slick_input_translator.rb +15 -0
  110. data/src/managers/message_queue.rb +60 -0
  111. data/src/managers/network_manager.rb +41 -0
  112. data/src/managers/render_support/hardware_cursor.rb +13 -0
  113. data/src/managers/resource_manager.rb +167 -0
  114. data/src/managers/sound_manager.rb +47 -0
  115. data/src/managers/tag_manager.rb +47 -0
  116. data/src/managers/tangible_manager.rb +36 -0
  117. data/src/math.rb +23 -0
  118. data/src/org/rubyforge/rawr/Main.java +67 -0
  119. data/src/platform.rb +28 -0
  120. data/src/proc_enhancement.rb +5 -0
  121. data/src/project_generator.rb +138 -0
  122. data/src/resource.rb +31 -0
  123. data/src/spline.rb +13 -0
  124. data/src/states/input_diagnostic_state.rb +53 -0
  125. data/src/vector.rb +143 -0
  126. data/test/test_state.rb +3 -0
  127. metadata +188 -0
@@ -0,0 +1,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
@@ -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
+ }
@@ -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,5 @@
1
+ class Proc
2
+ def source
3
+ eval "self", binding
4
+ end
5
+ 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