slickr 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +6 -14
- data/.rspec +0 -1
- data/.travis.yml +4 -0
- data/Gemfile +0 -2
- data/README.md +58 -52
- data/Rakefile +4 -0
- data/lib/slickr.rb +18 -1
- data/lib/slickr/actions/generate.rb +51 -0
- data/lib/slickr/behavior.rb +68 -0
- data/lib/slickr/cli.rb +12 -3
- data/lib/slickr/entity.rb +64 -0
- data/lib/slickr/entity_manager.rb +105 -0
- data/lib/slickr/generators/base.rb +95 -0
- data/lib/slickr/generators/behavior.rb +9 -0
- data/lib/slickr/generators/entity.rb +10 -0
- data/{files → lib/slickr/generators/files}/Rakefile +0 -0
- data/{files → lib/slickr/generators/files}/jinput.jar +0 -0
- data/{files → lib/slickr/generators/files}/libjinput-osx.jnilib +0 -0
- data/{files → lib/slickr/generators/files}/liblwjgl.jnilib +0 -0
- data/{files → lib/slickr/generators/files}/lwjgl.jar +0 -0
- data/{files → lib/slickr/generators/files}/openal.dylib +0 -0
- data/{files → lib/slickr/generators/files}/slick.jar +0 -0
- data/lib/slickr/generators/project.rb +36 -0
- data/lib/slickr/generators/reactor.rb +9 -0
- data/lib/slickr/generators/renderer.rb +9 -0
- data/lib/slickr/generators/templates/behavior.erb +3 -0
- data/lib/slickr/generators/templates/behaviors.erb +1 -0
- data/{templates → lib/slickr/generators/templates}/engine.erb +13 -9
- data/lib/slickr/generators/templates/entities.erb +1 -0
- data/lib/slickr/generators/templates/entity.erb +2 -0
- data/lib/slickr/generators/templates/reactor.erb +4 -0
- data/lib/slickr/generators/templates/reactors.erb +1 -0
- data/lib/slickr/generators/templates/renderer.erb +4 -0
- data/lib/slickr/generators/templates/renderers.erb +1 -0
- data/lib/slickr/reactor.rb +86 -0
- data/lib/slickr/renderer.rb +37 -0
- data/lib/slickr/tasks.rb +1 -3
- data/lib/slickr/version.rb +1 -1
- data/slickr.gemspec +0 -2
- data/spec/build/.gitkeep +0 -0
- data/spec/slickr/actions/generate_spec.rb +38 -0
- data/spec/slickr/entity_manager_spec.rb +31 -0
- data/spec/slickr/entity_spec.rb +21 -0
- data/spec/slickr/generators/behavior_spec.rb +17 -0
- data/spec/slickr/generators/entity_spec.rb +21 -0
- data/spec/slickr/generators/project_spec.rb +120 -0
- data/spec/slickr/generators/reactor_spec.rb +17 -0
- data/spec/slickr/generators/renderer_spec.rb +17 -0
- data/spec/slickr/reactor_spec.rb +25 -0
- data/spec/spec_helper.rb +17 -4
- metadata +64 -57
- data/lib/slickr/actions/create.rb +0 -79
- data/spec/slickj/actions/create_spec.rb +0 -174
- data/templates/components.erb +0 -5
- data/templates/entities.erb +0 -5
- data/templates/renderers.erb +0 -5
- data/templates/systems.erb +0 -5
@@ -0,0 +1,95 @@
|
|
1
|
+
module Slickr
|
2
|
+
module Generators
|
3
|
+
class Base
|
4
|
+
attr_accessor :name
|
5
|
+
attr_accessor :destination
|
6
|
+
|
7
|
+
def initialize(name)
|
8
|
+
@name = name
|
9
|
+
@destination = Pathname.new(Dir.pwd)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Create an empty directory at +path+ inside the project.
|
13
|
+
#
|
14
|
+
# @param path [String] Path in the project to create the directory.
|
15
|
+
#
|
16
|
+
# @example
|
17
|
+
# empty_directory "lib"
|
18
|
+
#
|
19
|
+
def empty_directory(path)
|
20
|
+
destination.join(with_correct_path_seperator(path)).mkpath
|
21
|
+
end
|
22
|
+
|
23
|
+
# Copy a file from ROOT/files to somewhere in the project
|
24
|
+
# directory.
|
25
|
+
#
|
26
|
+
# This does not render anything, it's just a simple +cp+.
|
27
|
+
#
|
28
|
+
# @param filename [String] Name of the source file located in ROOT/files
|
29
|
+
# @param path [String] Path to place the file in the project
|
30
|
+
#
|
31
|
+
# @example Place file in the root of the project
|
32
|
+
# copy_file "Rakefile"
|
33
|
+
#
|
34
|
+
# @example Place file somewhere nested in the project
|
35
|
+
# copy_file "jinput.jar", "java"
|
36
|
+
# # => Creates PROJECT/java/jinput.jar
|
37
|
+
#
|
38
|
+
def copy_file(filename, path="")
|
39
|
+
source = root.join("files", filename)
|
40
|
+
dest = destination.join(path, filename)
|
41
|
+
FileUtils.cp(source, dest)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Render an erb template at a specific path within
|
45
|
+
# the project.
|
46
|
+
#
|
47
|
+
# Renders ERB in the context of the class calling this method.
|
48
|
+
# Meaning you'll need to make whatever variables you want in your template
|
49
|
+
# available within the class. See Actions::Create, +name+ is an accessor
|
50
|
+
# and used in the template.
|
51
|
+
#
|
52
|
+
# @param filename [String] Name of the erb template living in ROOT/templates
|
53
|
+
# @param path [String] Path in the project to write the resulting file
|
54
|
+
#
|
55
|
+
# @example
|
56
|
+
# template "application.erb", "app/application.rb"
|
57
|
+
#
|
58
|
+
def template(filename, path)
|
59
|
+
file = lib_file(with_correct_path_seperator(path))
|
60
|
+
file.dirname.mkpath
|
61
|
+
file.open("w+") { |f| f << render(template_root(filename)) }
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
# Root of this gem, where the source files live.
|
67
|
+
#
|
68
|
+
def root
|
69
|
+
@root ||= Pathname.new(__FILE__).dirname.expand_path
|
70
|
+
end
|
71
|
+
|
72
|
+
# Normalizes file paths per OS.
|
73
|
+
#
|
74
|
+
# You can just use "/" in your calls to Util methods
|
75
|
+
# and it will update paths to whatever the OS actually
|
76
|
+
# uses.
|
77
|
+
#
|
78
|
+
def with_correct_path_seperator(path)
|
79
|
+
path.gsub("/", File::SEPARATOR)
|
80
|
+
end
|
81
|
+
|
82
|
+
def lib_file(filename)
|
83
|
+
destination.join(filename)
|
84
|
+
end
|
85
|
+
|
86
|
+
def render(source)
|
87
|
+
ERB.new(source).result(binding)
|
88
|
+
end
|
89
|
+
|
90
|
+
def template_root(filename)
|
91
|
+
root.join("templates", filename).read
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Slickr
|
2
|
+
module Generators
|
3
|
+
class Project < Base
|
4
|
+
def initialize(name)
|
5
|
+
super(name)
|
6
|
+
@destination = @destination.join(name)
|
7
|
+
end
|
8
|
+
|
9
|
+
def start
|
10
|
+
empty_directory "java"
|
11
|
+
empty_directory "assets"
|
12
|
+
empty_directory "lib"
|
13
|
+
empty_directory "lib/renderers"
|
14
|
+
empty_directory "lib/behaviors"
|
15
|
+
empty_directory "lib/reactors"
|
16
|
+
empty_directory "lib/entities"
|
17
|
+
|
18
|
+
copy_file "jinput.jar", "java"
|
19
|
+
copy_file "lwjgl.jar", "java"
|
20
|
+
copy_file "slick.jar", "java"
|
21
|
+
|
22
|
+
copy_file "libjinput-osx.jnilib"
|
23
|
+
copy_file "liblwjgl.jnilib"
|
24
|
+
copy_file "openal.dylib"
|
25
|
+
|
26
|
+
copy_file "Rakefile"
|
27
|
+
|
28
|
+
template "engine.erb", "lib/engine.rb"
|
29
|
+
template "behaviors.erb", "lib/behaviors.rb"
|
30
|
+
template "renderers.erb", "lib/renderers.rb"
|
31
|
+
template "reactors.erb", "lib/reactors.rb"
|
32
|
+
template "entities.erb", "lib/entities.rb"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
# require "behaviors/..."
|
@@ -3,6 +3,12 @@ require "java"
|
|
3
3
|
require "lwjgl.jar"
|
4
4
|
require "slick.jar"
|
5
5
|
|
6
|
+
$LOAD_PATH << File.expand_path("../../lib", __FILE__)
|
7
|
+
require "behaviors"
|
8
|
+
require "entities"
|
9
|
+
require "renderers"
|
10
|
+
require "reactors"
|
11
|
+
|
6
12
|
java_import org.newdawn.slick.AppGameContainer
|
7
13
|
java_import org.newdawn.slick.BasicGame
|
8
14
|
java_import org.newdawn.slick.Color
|
@@ -11,20 +17,18 @@ java_import org.newdawn.slick.Graphics
|
|
11
17
|
java_import org.newdawn.slick.Image
|
12
18
|
java_import org.newdawn.slick.Input
|
13
19
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
20
|
+
class Engine < BasicGame
|
21
|
+
def init(container)
|
22
|
+
end
|
18
23
|
|
19
|
-
|
20
|
-
|
24
|
+
def update(container, delta)
|
25
|
+
end
|
21
26
|
|
22
|
-
|
23
|
-
end
|
27
|
+
def render(container, graphics)
|
24
28
|
end
|
25
29
|
end
|
26
30
|
|
27
|
-
game = AppGameContainer.new(
|
31
|
+
game = AppGameContainer.new(Engine.new("<%= name %>"))
|
28
32
|
game.set_display_mode(800, 600, false)
|
29
33
|
game.start
|
30
34
|
|
@@ -0,0 +1 @@
|
|
1
|
+
# require "entities/..."
|
@@ -0,0 +1 @@
|
|
1
|
+
# require "reactors/..."
|
@@ -0,0 +1 @@
|
|
1
|
+
# require "renderers/..."
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Slickr
|
2
|
+
# Reactors take info about the game world and tell relevant
|
3
|
+
# entities to do something. Emphasis is on the word "tell".
|
4
|
+
#
|
5
|
+
# == Concerns
|
6
|
+
#
|
7
|
+
# Reactors are always concerned with entities who implement
|
8
|
+
# one or more specific behaviors. For instance, an # +InputReactor+
|
9
|
+
# would care about entities who implement the +Controllable+
|
10
|
+
# behavior.
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
#
|
14
|
+
# class InputReactor < Slickr::Reactors
|
15
|
+
# concerned_with :controllable
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# == Using Ractors
|
19
|
+
#
|
20
|
+
# Reactors are middleware of your game's Engine. They are called
|
21
|
+
# during every +update+ tick of your game. They are passed the
|
22
|
+
# game's +container+ and the +delta+ of time that has passed since
|
23
|
+
# the last tick.
|
24
|
+
#
|
25
|
+
# @example
|
26
|
+
#
|
27
|
+
# class Engine < BasicGame
|
28
|
+
# use InputReactor
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# if you need to do some special setup in your Reactors, do it
|
32
|
+
# in the initializer like any normal ruby object.
|
33
|
+
#
|
34
|
+
# @example
|
35
|
+
#
|
36
|
+
# class Engine < BasicGame
|
37
|
+
# use InputReactor.new(:ignore => :up)
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# == Reacting
|
41
|
+
#
|
42
|
+
# Reactors simply orcestrate. They take that delta and tell the
|
43
|
+
# entities they care about to do something. Following the above
|
44
|
+
# example, here's a simple Reactor that moves entities around
|
45
|
+
# the world.
|
46
|
+
#
|
47
|
+
# @example
|
48
|
+
#
|
49
|
+
# class InputReactor < Slickr::Reactor
|
50
|
+
# concerned_with :controllable
|
51
|
+
#
|
52
|
+
# def call(container, delta)
|
53
|
+
# entities.each do |entity|
|
54
|
+
# entity.up(delta) if input.is_key_down?(Input::KEY_UP)
|
55
|
+
# entity.down(delta) if input.is_key_down?(Input::KEY_DOWN)
|
56
|
+
# entity.right(delta) if input.is_key_down?(Input::KEY_RIGHT)
|
57
|
+
# entity.left(delta) if input.is_key_down?(Input::KEY_LEFT)
|
58
|
+
# end
|
59
|
+
# end
|
60
|
+
# end
|
61
|
+
#
|
62
|
+
class Reactor
|
63
|
+
class << self
|
64
|
+
attr_accessor :concerns
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.concerned_with(*behaviors)
|
68
|
+
@concerns ||= []
|
69
|
+
@concerns += behaviors
|
70
|
+
end
|
71
|
+
|
72
|
+
def call(*args)
|
73
|
+
raise NotImplementedError
|
74
|
+
end
|
75
|
+
|
76
|
+
def entities
|
77
|
+
EntityManager.entities_with(*concerns)
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def concerns
|
83
|
+
self.class.concerns
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Slickr
|
2
|
+
# Renderers take the current state of an entity and draws it to
|
3
|
+
# the screen.
|
4
|
+
#
|
5
|
+
# @example Simple renderer that draws a graphic on the screen
|
6
|
+
#
|
7
|
+
# class HeroRenderer < Slickr::Renderer
|
8
|
+
# attr_reader :image
|
9
|
+
#
|
10
|
+
# def initialize(entity)
|
11
|
+
# super
|
12
|
+
# @image = Image.new("assets/hero.png", false)
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# def render
|
16
|
+
# image.draw(entity.x, entity.y)
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# == Never Mutate Entities
|
21
|
+
#
|
22
|
+
# Renderers should know as little as possible about the entity it's
|
23
|
+
# drawing. They should also never, ever, mutate an entity. They only
|
24
|
+
# request information and push a representation of that to the screen.
|
25
|
+
#
|
26
|
+
class Renderer
|
27
|
+
attr_reader :entity
|
28
|
+
|
29
|
+
def initialize(entity)
|
30
|
+
@entity = entity
|
31
|
+
end
|
32
|
+
|
33
|
+
def render
|
34
|
+
raise NotImplementedError
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/slickr/tasks.rb
CHANGED
data/lib/slickr/version.rb
CHANGED
data/slickr.gemspec
CHANGED
@@ -23,7 +23,5 @@ Gem::Specification.new do |spec|
|
|
23
23
|
|
24
24
|
spec.add_development_dependency "bundler", "~> 1.3"
|
25
25
|
spec.add_development_dependency "rake"
|
26
|
-
spec.add_development_dependency "debugger"
|
27
26
|
spec.add_development_dependency "rspec"
|
28
|
-
spec.add_development_dependency "fakefs"
|
29
27
|
end
|
data/spec/build/.gitkeep
ADDED
File without changes
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Slickr::Actions::Generate do
|
4
|
+
it "finds the generator class from its lowercase name" do
|
5
|
+
action = described_class.new("behavior", "spatiality")
|
6
|
+
action.generator_class.should == Slickr::Generators::Behavior
|
7
|
+
end
|
8
|
+
|
9
|
+
it "finds the generator class from its Capitalized name" do
|
10
|
+
action = described_class.new("Behavior", "spatiality")
|
11
|
+
action.generator_class.should == Slickr::Generators::Behavior
|
12
|
+
end
|
13
|
+
|
14
|
+
it "finds the generator class from its ALL CAPS name" do
|
15
|
+
action = described_class.new("BEHAVIOR", "spatiality")
|
16
|
+
action.generator_class.should == Slickr::Generators::Behavior
|
17
|
+
end
|
18
|
+
|
19
|
+
it "finds the generator class from its FuCkEdUpCaSe name" do
|
20
|
+
action = described_class.new("BeHaViOr", "spatiality")
|
21
|
+
action.generator_class.should == Slickr::Generators::Behavior
|
22
|
+
end
|
23
|
+
|
24
|
+
it "adds the object type to its name" do
|
25
|
+
action = described_class.new("behavior", "spatiality")
|
26
|
+
action.name.should == "spatiality_behavior"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "does not change the name when its already in the correct form" do
|
30
|
+
action = described_class.new("behavior", "spatiality_behavior")
|
31
|
+
action.name.should == "spatiality_behavior"
|
32
|
+
end
|
33
|
+
|
34
|
+
it "does nothing to the name is in class form" do
|
35
|
+
action = described_class.new("behavior", "SpatialityBehavior")
|
36
|
+
action.name.should == "spatiality_behavior"
|
37
|
+
end
|
38
|
+
end
|