slickr 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +6 -14
  2. data/.rspec +0 -1
  3. data/.travis.yml +4 -0
  4. data/Gemfile +0 -2
  5. data/README.md +58 -52
  6. data/Rakefile +4 -0
  7. data/lib/slickr.rb +18 -1
  8. data/lib/slickr/actions/generate.rb +51 -0
  9. data/lib/slickr/behavior.rb +68 -0
  10. data/lib/slickr/cli.rb +12 -3
  11. data/lib/slickr/entity.rb +64 -0
  12. data/lib/slickr/entity_manager.rb +105 -0
  13. data/lib/slickr/generators/base.rb +95 -0
  14. data/lib/slickr/generators/behavior.rb +9 -0
  15. data/lib/slickr/generators/entity.rb +10 -0
  16. data/{files → lib/slickr/generators/files}/Rakefile +0 -0
  17. data/{files → lib/slickr/generators/files}/jinput.jar +0 -0
  18. data/{files → lib/slickr/generators/files}/libjinput-osx.jnilib +0 -0
  19. data/{files → lib/slickr/generators/files}/liblwjgl.jnilib +0 -0
  20. data/{files → lib/slickr/generators/files}/lwjgl.jar +0 -0
  21. data/{files → lib/slickr/generators/files}/openal.dylib +0 -0
  22. data/{files → lib/slickr/generators/files}/slick.jar +0 -0
  23. data/lib/slickr/generators/project.rb +36 -0
  24. data/lib/slickr/generators/reactor.rb +9 -0
  25. data/lib/slickr/generators/renderer.rb +9 -0
  26. data/lib/slickr/generators/templates/behavior.erb +3 -0
  27. data/lib/slickr/generators/templates/behaviors.erb +1 -0
  28. data/{templates → lib/slickr/generators/templates}/engine.erb +13 -9
  29. data/lib/slickr/generators/templates/entities.erb +1 -0
  30. data/lib/slickr/generators/templates/entity.erb +2 -0
  31. data/lib/slickr/generators/templates/reactor.erb +4 -0
  32. data/lib/slickr/generators/templates/reactors.erb +1 -0
  33. data/lib/slickr/generators/templates/renderer.erb +4 -0
  34. data/lib/slickr/generators/templates/renderers.erb +1 -0
  35. data/lib/slickr/reactor.rb +86 -0
  36. data/lib/slickr/renderer.rb +37 -0
  37. data/lib/slickr/tasks.rb +1 -3
  38. data/lib/slickr/version.rb +1 -1
  39. data/slickr.gemspec +0 -2
  40. data/spec/build/.gitkeep +0 -0
  41. data/spec/slickr/actions/generate_spec.rb +38 -0
  42. data/spec/slickr/entity_manager_spec.rb +31 -0
  43. data/spec/slickr/entity_spec.rb +21 -0
  44. data/spec/slickr/generators/behavior_spec.rb +17 -0
  45. data/spec/slickr/generators/entity_spec.rb +21 -0
  46. data/spec/slickr/generators/project_spec.rb +120 -0
  47. data/spec/slickr/generators/reactor_spec.rb +17 -0
  48. data/spec/slickr/generators/renderer_spec.rb +17 -0
  49. data/spec/slickr/reactor_spec.rb +25 -0
  50. data/spec/spec_helper.rb +17 -4
  51. metadata +64 -57
  52. data/lib/slickr/actions/create.rb +0 -79
  53. data/spec/slickj/actions/create_spec.rb +0 -174
  54. data/templates/components.erb +0 -5
  55. data/templates/entities.erb +0 -5
  56. data/templates/renderers.erb +0 -5
  57. 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
@@ -0,0 +1,9 @@
1
+ module Slickr
2
+ module Generators
3
+ class Behavior < Base
4
+ def start
5
+ template "behavior.erb", "lib/behaviors/#{name}.rb"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ module Slickr
2
+ module Generators
3
+ class Entity < Base
4
+ def start
5
+ template "entity.erb", "lib/entities/#{name}.rb"
6
+ Renderer.new(name.gsub("entity", "renderer")).start
7
+ end
8
+ end
9
+ end
10
+ end
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,9 @@
1
+ module Slickr
2
+ module Generators
3
+ class Reactor < Base
4
+ def start
5
+ template "reactor.erb", "lib/reactors/#{name}.rb"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Slickr
2
+ module Generators
3
+ class Renderer < Base
4
+ def start
5
+ template "renderer.erb", "lib/renderers/#{name}.rb"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module <%= name.classify %>
2
+ include Slickr::Behavior
3
+ 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
- module <%= module_name %>
15
- class Engine < BasicGame
16
- def init(container)
17
- end
20
+ class Engine < BasicGame
21
+ def init(container)
22
+ end
18
23
 
19
- def update(container, delta)
20
- end
24
+ def update(container, delta)
25
+ end
21
26
 
22
- def render(container, graphics)
23
- end
27
+ def render(container, graphics)
24
28
  end
25
29
  end
26
30
 
27
- game = AppGameContainer.new(<%= module_name %>::Engine.new("<%= name %>"))
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,2 @@
1
+ class <%= name.classify %> < Slickr::Entity
2
+ end
@@ -0,0 +1,4 @@
1
+ class <%= name.classify %> < Slickr::Reactor
2
+ def call(container, delta)
3
+ end
4
+ end
@@ -0,0 +1 @@
1
+ # require "reactors/..."
@@ -0,0 +1,4 @@
1
+ class <%= name.classify %> < Slickr::Renderer
2
+ def render
3
+ end
4
+ end
@@ -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
@@ -4,9 +4,7 @@ module Slickr
4
4
 
5
5
  def self.all
6
6
  desc "Play the game"
7
- task :play do
8
- sh "ruby -I./lib lib/engine.rb"
9
- end
7
+ task(:play) { sh "ruby -I./lib lib/engine.rb" }
10
8
  end
11
9
  end
12
10
  end
@@ -1,3 +1,3 @@
1
1
  module Slickr
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
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
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