Skip to content

Commit

Permalink
Merge branch 'master' of ssh://LoganBarnett@git.kenai.com/jemini~main…
Browse files Browse the repository at this point in the history
…line
  • Loading branch information
LoganBarnett committed Dec 16, 2009
2 parents 496d55c + 19f5648 commit 65d92b8
Show file tree
Hide file tree
Showing 16 changed files with 454 additions and 22 deletions.
10 changes: 9 additions & 1 deletion README.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
Jemini 2009.10.27
Jemini 2009.11.24

== 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.

== Installation

At a command line, type:

sudo gem install jemini

(Leave off the "sudo" if on Windows.)

== License

Jemini is released under the BSD license. See the COPYING file for the full license.
51 changes: 51 additions & 0 deletions src/behaviors/configurable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#Allows an object to load attributes from a file.
class Configurable < Jemini::Behavior

#The loaded configuration for the object.
attr_reader :config

#Loads a configuration with the given name.
def configure_as(key)
string = game_state.manager(:config).get_config(key)
@config = parse(string)
end

private

#Parse the config string, returning a hash of attributes.
def parse(string)
attributes = {}
string.split("\n").each do |line|
line.strip!
next if line.empty?
next if line =~ /^#/
if line =~ /^([^=]+)=(.*)$/
key = $1.strip.to_sym
value = parse_value($2.strip)
attributes[key] = value
end
end
attributes
end

#Treats quoted strings as strings, unquoted numbers as numbers.
def parse_value(value)
case value
when /^"(.*)"$/
escape($1)
when /^([\-\d]+)$/
$1.to_i
when /^([\-\d\.]+)$/
$1.to_f
else
escape(value)
end
end

def escape(string)
string.gsub!(/\\\"/, '"')
string.gsub!(/\\\\/, '\\')
string
end

end
53 changes: 53 additions & 0 deletions src/behaviors/drawable_ellipse.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# draws a line on the screen
class DrawableEllipse < Jemini::Behavior
java_import 'org.newdawn.slick.geom.Ellipse'
java_import 'org.newdawn.slick.Color'
depends_on :Spatial
wrap_with_callbacks :draw

#The Color to draw the ellipse in.
attr_accessor :color
#If true, the shape will be drawn filled in. If false, only the frame will be drawn.
attr_accessor :ellipse_filled

def load
@color = Color.white
@ellipse_filled = true
@ellipse = Ellipse.new @game_object.position.x, @game_object.position.y, 1.0, 1.0
@game_object.on_after_position_changes { set_drawing_location }
end

#The ellipse height.
def height=(value)
@ellipse.radius2 = value / 2.0
set_drawing_location
end
def height
@ellipse.radius2 * 2.0
end

#The ellipse width.
def width=(value)
@ellipse.radius1 = value / 2.0
set_drawing_location
end
def width
@ellipse.radius1 * 2.0
end

#Draw an outline to the given graphics context.
def draw(graphics)
graphics.set_color @color
if @ellipse_filled
graphics.fill @ellipse
else
graphics.draw @ellipse
end
end

private
def set_drawing_location
@ellipse.x = @game_object.position.x - @ellipse.radius1
@ellipse.y = @game_object.position.y - @ellipse.radius2
end
end
8 changes: 6 additions & 2 deletions src/behaviors/drawable_line.rb
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
# draws a line on the screen
# TODO: Enable color
class DrawableLine < Jemini::Behavior
java_import 'org.newdawn.slick.geom.Line'
java_import 'org.newdawn.slick.Color'
depends_on :Spatial
wrap_with_callbacks :draw

#A Vector with the coordinates of the other end of the line.
attr_reader :line_end_position
#The Color to draw the line in.
attr_accessor :color

def load
@color = Color.white
@line_end_position = Vector.new(0.0, 0.0)
@line = Line.new @game_object.position.to_slick_vector, @line_end_position.to_slick_vector
@game_object.on_after_position_changes { set_line }
#@color = Color.white
end

def line_end_position=(end_point)
Expand All @@ -21,7 +23,9 @@ def line_end_position=(end_point)
@line_end_position
end

#Draw the line to the given graphics context.
def draw(graphics)
graphics.set_color @color
graphics.draw @line
end

Expand Down
53 changes: 53 additions & 0 deletions src/behaviors/drawable_rectangle.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# draws a line on the screen
class DrawableRectangle < Jemini::Behavior
java_import 'org.newdawn.slick.geom.Rectangle'
java_import 'org.newdawn.slick.Color'
depends_on :Spatial
wrap_with_callbacks :draw

#The Color to draw the shape in.
attr_accessor :color
#If true, the shape will be drawn filled in. If false, only the frame will be drawn.
attr_accessor :rectangle_filled

def load
@color = Color.white
@rectangle_filled = true
@rectangle = Rectangle.new @game_object.position.x, @game_object.position.y, 1.0, 1.0
@game_object.on_after_position_changes { set_drawing_location }
end

#The rectangle height.
def height=(value)
@rectangle.height = value
set_drawing_location
end
def height
@rectangle.height
end

#The rectangle width.
def width=(value)
@rectangle.width = value
set_drawing_location
end
def width
@rectangle.width
end

#Draw an outline to the given graphics context.
def draw(graphics)
graphics.set_color @color
if @rectangle_filled
graphics.fill @rectangle
else
graphics.draw @rectangle
end
end

private
def set_drawing_location
@rectangle.x = @game_object.position.x - (@rectangle.width / 2.0)
@rectangle.y = @game_object.position.y - (@rectangle.height / 2.0)
end
end
12 changes: 12 additions & 0 deletions src/managers/config_manager.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class ConfigManager < Jemini::GameObject

def load
@configs = {}
end

#Takes a reference to a config loaded via the resource manager, and returns it.
def get_config(reference)
game_state.manager(:resource).get_config(reference)
end

end
52 changes: 36 additions & 16 deletions src/managers/resource_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class ResourceManager < Jemini::GameObject
#Sets a default data directory path of "data".
def load
enable_listeners_for :resources_loaded
@configs = {}
@images = {}
@sounds = {}
@songs = {}
Expand All @@ -25,6 +26,13 @@ def load_resources(state_name = nil)
notify :resources_loaded
end

#Load the config at the given path, and make it accessible via the given key.
def cache_config(key, path)
log.debug "Caching config for #{key} with path: #{path}"
log.warn "Skipping duplicate config for #{key} with path: #{path}" and return if @configs[key]
@configs[key] = load_resource(path, :config)
end

#Load the image at the given path, and make it accessible via the given key.
def cache_image(key, path)
log.debug "Caching image for #{key} with path: #{path}"
Expand All @@ -46,6 +54,22 @@ def cache_song(key, path)
@songs[key] = load_resource(path, :music)
end

#Get a config stored previously with cache_config.
def get_config(key)
@configs[key] or raise "Could not find config: #{key} - cached configs: #{@configs.keys}"
end
alias_method :config, :get_config

#Get all configs stored previously with cache_config.
def get_all_configs
@configs.values
end
alias_method :configs, :get_all_configs

def config_names
@configs.keys
end

#Get an image stored previously with cache_image.
def get_image(key)
@images[key] or raise "Could not find image: #{key} - cached images: #{@images.keys}"
Expand Down Expand Up @@ -90,30 +114,27 @@ def get_all_songs

def load_resource(path, type_name)
# due to some JRuby trickery involved with java_import, we can't use metaprogramming tricks here.
type = case type_name
when :image
Image
when :sound
Sound
when :music
Music
end
type.new(Jemini::Resource.path_of(path))
case type_name
when :config
File.read(Jemini::Resource.path_of(path))
when :image
Image.new(Jemini::Resource.path_of(path))
when :sound
Sound.new(Jemini::Resource.path_of(path))
when :music
Music.new(Jemini::Resource.path_of(path))
end
end

# root dirs can't be skipped
def load_directory(directory, root = false)
log.debug "Loading contents of #{directory}"
begin
#Dir.open(directory).each do |file|
resources_for(directory).each do |file|
next if file =~ /^\./
# path = File.join(directory, file)
path = File.in_jar?(directory) ? file : File.join(directory, file)
log.debug "Dir in jar? #{File.in_jar?(directory)}"
log.debug "Using path #{path} for #{file}"
# File.file? doesn't work in a jar.
# next unless File.file?(path)
extension = File.extname(file).downcase
key = File.basename(file, extension).downcase.to_sym
log.debug "Extension: #{extension}"
Expand All @@ -124,6 +145,8 @@ def load_directory(directory, root = false)
cache_sound(key, path)
when '.ogg'
cache_song(key, path)
when '.ini'
cache_config(key, path)
else
log.warn "Skipping unknown file: #{path}"
end
Expand Down Expand Up @@ -159,9 +182,6 @@ def scan_entire_jar(directory)
entries_under_directory = all_entries.select {|e| e =~ dir_regex }
# need a shallow resultset
entries_directly_under_directory = entries_under_directory.reject {|e| e =~ /#{just_dir}\/.*\//}
# log.debug "entries directly under dir"
# log.debug entries_directly_under_directory
# log.debug "------------"
entries_directly_under_directory
end
end
1 change: 0 additions & 1 deletion src/project_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ def generate_main
f << <<-ENDL
require 'java'
$LOAD_PATH.clear
$LOAD_PATH << File.expand_path(File.dirname(__FILE__))
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), 'game_objects'))
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), 'managers'))
Expand Down
1 change: 1 addition & 0 deletions test/game_with_ini/data/test.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
shot_power = 75
5 changes: 4 additions & 1 deletion test/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
$game_path = File.expand_path(File.join(File.dirname(__FILE__), 'game'))
$LOAD_PATH << $game_path

#Margin of error for RSpec be_close matchers.
MARGIN = 0.001

require 'jemini'
require 'test_state'

Expand All @@ -28,4 +31,4 @@ def stub_image_resource(reference)
@game_state.manager(:resource).stub!(:get_image) do |key|
@references[key]
end
end
end
Loading

0 comments on commit 65d92b8

Please sign in to comment.