slickr 0.0.1 → 0.0.2

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 (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