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
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
ZGRkMzg4NGE3MTE1OTkyNzk1MDkxMDk5MjViNTdiYzU5ODliMDUyYTZhMDk4
|
10
|
-
YTVmMWNkNTgxZjlhOWQ3NDAyYzIwYWJkMjJmYWI0ODlmMzM2ZmU4NmJiYTI5
|
11
|
-
YjZjYjQ5NWNjM2RmZWM4ZTZiMjY0ZjY1MTllNGFiZTI1MjRlNTI=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
YzQ4MWI3YTE3YzZkZmJjMzMwOTY4NzFkMzUyMzk5Zjg4NmVkNDQ1MDRlNzg2
|
14
|
-
OTc2OWE4NWVjODg1MWZkOTJmMmE2MDg0NmFhMzRhMWYwZTkzZDdkNzM2MWNk
|
15
|
-
NWFmMGY0YzFiYmY5Y2ZhYjU4M2UxZmViY2YzMDY4OTIzZTUyODM=
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7593e388d74d18775d44ce56aac159b23a9e93ad
|
4
|
+
data.tar.gz: 05a5b28e4c555ec670421a490e6dda4c54413eb5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 870175e5c09cea5de268086d2cc3e643f64193b947c26dd2d5c378e7660ecd20ffc42dc4fb0ea7493ca60c4a211ad88a4cf3b81cce853288502ce903e342ff1a
|
7
|
+
data.tar.gz: e0e2781159242322ad0be3ce13a439f8e32df97a6739a5aa7ee7d4f5a655a92386603013a5b933cf4e16782b261365a024a8b9c33a11c757d024eafffb51a472
|
data/.rspec
CHANGED
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,18 +1,49 @@
|
|
1
|
-
#
|
1
|
+
# Welcome to Slickr
|
2
|
+
[![Build Status](https://travis-ci.org/mnoble/slickr.png?branch=master)](https://travis-ci.org/mnoble/slickr)
|
3
|
+
[![Code Climate](https://codeclimate.com/github/mnoble/slickr.png)](https://codeclimate.com/github/mnoble/slickr)
|
2
4
|
|
3
|
-
JRuby Slick2D project
|
5
|
+
Slickr is a JRuby, Slick2D, project framework.
|
4
6
|
|
5
|
-
|
7
|
+
Slickr tries to merge concepts from Entity-Component and good old
|
8
|
+
fashion Object Oriented Design. Ruby gives you a lot of power to
|
9
|
+
write great code and Slickr tries to help you do that, while developing
|
10
|
+
games.
|
6
11
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
that well.
|
12
|
+
"Slick2D is an easy to use set of tools and utilities wrapped around
|
13
|
+
LWJGL OpenGL bindings to make 2D Java game development easier." —
|
14
|
+
[http://www.slick2d.org/wiki/index.php/Main_Page](http://www.slick2d.org/wiki/index.php/Main_Page)
|
11
15
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
+
## Getting Started
|
17
|
+
|
18
|
+
1\. Install Slickr
|
19
|
+
|
20
|
+
```
|
21
|
+
$ gem install slickr
|
22
|
+
```
|
23
|
+
|
24
|
+
2\. Create a new Slickr game
|
25
|
+
|
26
|
+
```
|
27
|
+
$ slickr new my_game
|
28
|
+
```
|
29
|
+
|
30
|
+
where "my_game" is the name of the game.
|
31
|
+
|
32
|
+
3\. Change directory to `my_game` and play it
|
33
|
+
|
34
|
+
```
|
35
|
+
$ cd my_game
|
36
|
+
$ rake play
|
37
|
+
```
|
38
|
+
|
39
|
+
You should see a Window with nothing but a white background and some FPS
|
40
|
+
information.
|
41
|
+
|
42
|
+
## Generating New Code
|
43
|
+
|
44
|
+
```
|
45
|
+
$ slickr generate [component|entity|renderer|system] NAME
|
46
|
+
```
|
16
47
|
|
17
48
|
## Project Structure
|
18
49
|
|
@@ -22,62 +53,37 @@ says and follow it.
|
|
22
53
|
│ ├── jinput.jar
|
23
54
|
│ ├── lwjgl.jar
|
24
55
|
│ └── slick.jar
|
25
|
-
├── lib
|
26
|
-
│ ├──
|
27
|
-
│ ├──
|
56
|
+
├── lib/
|
57
|
+
│ ├── behaviors/
|
58
|
+
│ ├── behaviors.rb
|
28
59
|
│ ├── engine.rb
|
29
|
-
│ ├── entities
|
60
|
+
│ ├── entities/
|
30
61
|
│ ├── entities.rb
|
31
|
-
│ ├── renderers
|
62
|
+
│ ├── renderers/
|
32
63
|
│ ├── renderers.rb
|
33
|
-
│ ├──
|
34
|
-
│ └──
|
64
|
+
│ ├── reactors/
|
65
|
+
│ └── reactors.rb
|
35
66
|
├── libjinput-osx.jnilib
|
36
67
|
├── liblwjgl.jnilib
|
37
68
|
└── openal.dylib
|
38
69
|
|
39
|
-
|
40
|
-
|
70
|
+
**assets/**<br/>
|
41
71
|
Images, sounds, videos, etc.
|
42
72
|
|
43
|
-
|
44
|
-
|
73
|
+
**java/**<br/>
|
45
74
|
Slick2D framework jars.
|
46
75
|
|
47
|
-
|
48
|
-
|
49
|
-
Your game code.
|
50
|
-
|
51
|
-
### lib/components
|
52
|
-
|
53
|
-
Behaviors that entities will include. These are modules that implement
|
54
|
-
whatever behavior the entity should have. A common example will be a
|
55
|
-
`Spatial` component that implements `x` and `y` position and movement.
|
56
|
-
|
57
|
-
### lib/entities
|
58
|
-
|
59
|
-
The actual objects that live your game's world. Entities will implement
|
60
|
-
Components and Systems conduct Entities. These will be your Heros,
|
61
|
-
Enemies, Bosses, etc.
|
76
|
+
**lib/behaviors/**<br/>
|
77
|
+
Behaviors that entities will include.
|
62
78
|
|
63
|
-
|
79
|
+
**lib/entities/**<br/>
|
80
|
+
The actual objects that live your game's world.
|
64
81
|
|
82
|
+
**lib/renderers/**<br/>
|
65
83
|
Draws the current state of entities to the screen.
|
66
84
|
|
67
|
-
|
68
|
-
|
69
|
-
Systems react to changes in the world and update entitites accordingly.
|
70
|
-
View these as controllers of sorts. A good example of this is an `Input`
|
71
|
-
system. It would react to keyboard events and tell the appropriate
|
72
|
-
entities where to move.
|
73
|
-
|
74
|
-
## Installation
|
75
|
-
|
76
|
-
$ gem install slickr
|
77
|
-
|
78
|
-
## Usage
|
79
|
-
|
80
|
-
$ slickr new PROJECT_NAME
|
85
|
+
**lib/reactors/**<br/>
|
86
|
+
Reactors take changes in the world and updates entitites accordingly.
|
81
87
|
|
82
88
|
## Contributing
|
83
89
|
|
data/Rakefile
CHANGED
data/lib/slickr.rb
CHANGED
@@ -2,6 +2,23 @@ require "fileutils"
|
|
2
2
|
require "pathname"
|
3
3
|
require "thor"
|
4
4
|
require "active_support/all"
|
5
|
+
|
5
6
|
require "slickr/version"
|
7
|
+
require "slickr/actions/generate"
|
8
|
+
require "slickr/generators/base"
|
9
|
+
require "slickr/generators/project"
|
10
|
+
require "slickr/generators/behavior"
|
11
|
+
require "slickr/generators/entity"
|
12
|
+
require "slickr/generators/renderer"
|
13
|
+
require "slickr/generators/reactor"
|
14
|
+
require "slickr/entity_manager"
|
15
|
+
require "slickr/entity"
|
16
|
+
require "slickr/behavior"
|
17
|
+
require "slickr/reactor"
|
18
|
+
require "slickr/renderer"
|
6
19
|
require "slickr/cli"
|
7
|
-
|
20
|
+
|
21
|
+
module Slickr
|
22
|
+
class SlickrError < StandardError; end
|
23
|
+
class NotImplementedError < SlickrError; end
|
24
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Slickr
|
2
|
+
module Actions
|
3
|
+
# Adapter for calling the different types of Generators.
|
4
|
+
#
|
5
|
+
# This class takes the name of the generator, in any form, and
|
6
|
+
# the name the user wants to give to the new piece of code. It
|
7
|
+
# will normalize both to follow Slickr conventions.
|
8
|
+
#
|
9
|
+
# == Naming Conventions
|
10
|
+
#
|
11
|
+
# Slickr follows the same sort of conventions as Rails. Classes
|
12
|
+
# are appended with their type. Eg. a "spatiality" behavior will
|
13
|
+
# become +SpatialityBehavior+, a "hero" renderer will become
|
14
|
+
# +HeroRenderer+, etc.
|
15
|
+
#
|
16
|
+
# @example Generating a new behavior
|
17
|
+
# Slickr::Actions::Generate.new("behavior", "spatiality").start
|
18
|
+
# # => lib/behaviors/spatiality_behavior.rb
|
19
|
+
#
|
20
|
+
# @example Generating a new behavior by specifying the full name
|
21
|
+
# Slickr::Actions::Generate.new("behavior", "spatiality_behavior").start
|
22
|
+
# # => lib/behaviors/spatiality_behavior.rb
|
23
|
+
#
|
24
|
+
# @example Generating a new behavior by specifying the name in class form
|
25
|
+
# Slickr::Actions::Generate.new("behavior", "SpatialityBehavior").start
|
26
|
+
# # => lib/behaviors/spatiality_behavior.rb
|
27
|
+
#
|
28
|
+
class Generate
|
29
|
+
def initialize(type, name)
|
30
|
+
@type = type
|
31
|
+
@name = name
|
32
|
+
end
|
33
|
+
|
34
|
+
def start
|
35
|
+
generator_class.new(name).start
|
36
|
+
end
|
37
|
+
|
38
|
+
def generator_class
|
39
|
+
Slickr::Generators.const_get(:"#{@type.capitalize}")
|
40
|
+
end
|
41
|
+
|
42
|
+
def name
|
43
|
+
"#{basename}_#{@type}".squeeze("_")
|
44
|
+
end
|
45
|
+
|
46
|
+
def basename
|
47
|
+
@name.gsub(/#{@type}/i, "").downcase
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Slickr
|
2
|
+
# Behaviors give entities the ability to do things. They should
|
3
|
+
# implement the logic to move around the world, detect collision,
|
4
|
+
# etc.
|
5
|
+
#
|
6
|
+
# A behavior should not care about what entities use it. It should
|
7
|
+
# specify all the attribute and methods relevant to what it does.
|
8
|
+
#
|
9
|
+
# module Spatiality
|
10
|
+
# include Slickr::Behavior
|
11
|
+
#
|
12
|
+
# attr_access :x, :y, :speed
|
13
|
+
#
|
14
|
+
# def prepare(options={})
|
15
|
+
# @x = options.fetch(:x, 0)
|
16
|
+
# @y = options.fetch(:y, 0)
|
17
|
+
# @speed = options.fetch(:speed, 0)
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# def up(delta)
|
21
|
+
# self.y -= speed * delta
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# def down(delta)
|
25
|
+
# self.y += speed * delta
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# def left(delta)
|
29
|
+
# self.x -= speed * delta
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# def right(delta)
|
33
|
+
# self.x += speed * delta
|
34
|
+
# end
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# == Preparing
|
38
|
+
#
|
39
|
+
# since behaviors are modules that get mixed into entities, we can't
|
40
|
+
# use the normal +initialize+ to set defaults. Instead, Slickr uses
|
41
|
+
# a convention of the +prepare+ method.
|
42
|
+
#
|
43
|
+
# When you specify an entity should implement some behavior, it's
|
44
|
+
# pushed into the entity's behavior stack. When that entity is
|
45
|
+
# instantiated, it will run through all of its behaviors and
|
46
|
+
# +prepare+ each one with the options specified in the entity.
|
47
|
+
#
|
48
|
+
# class Hero < Slickr::Entity
|
49
|
+
# use Spatiality, x: 10, y: 10, speed: 0.2
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# hero = Hero.new
|
53
|
+
# hero.x #=> 10
|
54
|
+
# hero.y #=> 10
|
55
|
+
# hero.speed #=> 0.2
|
56
|
+
#
|
57
|
+
# == Don't Clobber Behavior Attributes
|
58
|
+
#
|
59
|
+
# Use good OO common-sense here. Don't create multiple behaviors that
|
60
|
+
# all depend on attributes of the same name. Behaviors should be
|
61
|
+
# independent of one another.
|
62
|
+
#
|
63
|
+
module Behavior
|
64
|
+
def prepare(*args)
|
65
|
+
raise NotImplementedError
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/slickr/cli.rb
CHANGED
@@ -1,9 +1,18 @@
|
|
1
1
|
module Slickr
|
2
2
|
class CLI < Thor
|
3
|
-
desc "
|
4
|
-
|
3
|
+
desc "generate GENERATOR NAME", "Generate new code"
|
4
|
+
def generate(generator, name)
|
5
|
+
Actions::Generate.new(generator, name).start
|
6
|
+
end
|
7
|
+
|
8
|
+
desc "g GENERATOR NAME", "Shortcut for generate", hide: true
|
9
|
+
def g(*args)
|
10
|
+
generate(*args)
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "new NAME [options]", "Create a new jruby slick2d project"
|
5
14
|
def new(name)
|
6
|
-
|
15
|
+
Generators::Project.new(name).start
|
7
16
|
end
|
8
17
|
end
|
9
18
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Slickr
|
2
|
+
class Entity
|
3
|
+
class << self
|
4
|
+
attr_writer :behaviors
|
5
|
+
end
|
6
|
+
|
7
|
+
# Specify that an Entity should behave a certain way.
|
8
|
+
#
|
9
|
+
# @param behavior [Slickr::Behavior] The behavior to use.
|
10
|
+
# @param options [Hash] Default behavior values.
|
11
|
+
#
|
12
|
+
# @example A Hero can move about the world.
|
13
|
+
#
|
14
|
+
# class Hero < Slickr::Entity
|
15
|
+
# use Spatiality
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# Different Behaviors will allow you to specify different
|
19
|
+
# default values. For example, a Spatiality behavior that
|
20
|
+
# allows an Entity to move about the world, may take a
|
21
|
+
# default +x+ and +y+ value. The Entity will be placed at
|
22
|
+
# that location when the scene is first loaded.
|
23
|
+
#
|
24
|
+
# @example A Hero starting at a specific location.
|
25
|
+
#
|
26
|
+
# class Hero < Slickr::Entity
|
27
|
+
# use Spatiality, x: 100, y: 100
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
def self.use(behavior, options={})
|
31
|
+
behaviors << [behavior, options]
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.behaviors
|
35
|
+
@behaviors ||= []
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.reset
|
39
|
+
@behaviors = []
|
40
|
+
end
|
41
|
+
|
42
|
+
def initialize
|
43
|
+
behaviors.each { |behavior, options| behave_like(behavior, options) }
|
44
|
+
end
|
45
|
+
|
46
|
+
def behaviors
|
47
|
+
self.class.behaviors
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
# Mixin a behavior and configure it with the appropriate options.
|
53
|
+
#
|
54
|
+
# Each behavior must implement a +prepare+ method that initializes
|
55
|
+
# the Entity with any default values. The +prepare+ method will
|
56
|
+
# always be that of the last Behavior mixed in.
|
57
|
+
#
|
58
|
+
def behave_like(behavior, options={})
|
59
|
+
extend behavior
|
60
|
+
prepare(options)
|
61
|
+
EntityManager.register(self, behavior)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Slickr
|
2
|
+
# Provides a central repository for storing and querying for Entities
|
3
|
+
# that exhibit some behavior.
|
4
|
+
#
|
5
|
+
# Each scene of your game will probably have many entities. When you
|
6
|
+
# instantiate one of those Entities, it's automatically registered
|
7
|
+
# to the +EntityManager+, with the behaviors it implements.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
#
|
11
|
+
# class Boss < Slickr::Entity
|
12
|
+
# use Spatial, x: 0, y: 0
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# boss = Boss.new
|
16
|
+
# # => #<Boss components=[:spatial]>
|
17
|
+
#
|
18
|
+
# EntityManager.entities
|
19
|
+
# # => [#<Boss components=[:spatial]>]
|
20
|
+
#
|
21
|
+
# Systems and Renderers are the two things that will likely need to
|
22
|
+
# alter or manipulate entities. Systems change the data associated
|
23
|
+
# with an entity and Renderers draw that to the screen. These objects
|
24
|
+
# can ask the +EntityManager+ for any entities that care about the
|
25
|
+
# behaviors they affect.
|
26
|
+
#
|
27
|
+
# @example
|
28
|
+
#
|
29
|
+
# class Systems::Input
|
30
|
+
# def call(delta)
|
31
|
+
# entities.each { |e| e.up(delta) } if up_key?
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# def entities
|
35
|
+
# EntityManager.entities_with(:controllable, :spatial)
|
36
|
+
# end
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# The +Input+ system cares about entities that can be moved by keyboard
|
40
|
+
# or mouse input and have spatial awareness; that is, things that can
|
41
|
+
# move. The above +System+ tells an entity to move up if the up key is
|
42
|
+
# pressed. What "moving up" means is determined by the component. The
|
43
|
+
# System doesn't care; it just reacts to events in the world and tells
|
44
|
+
# entities to do stuff based on that.
|
45
|
+
#
|
46
|
+
# It's important to view +:controllable+ and +:spatial+ as behaviors.
|
47
|
+
# Systems and Renderers expect these objects to conform to some standard
|
48
|
+
# API. We don't care where the object came from, what type it is or
|
49
|
+
# what it does outside of what we expect. We're going for good object
|
50
|
+
# oriented design through duck typing here.
|
51
|
+
#
|
52
|
+
module EntityManager
|
53
|
+
extend self
|
54
|
+
|
55
|
+
# @!attribute entities
|
56
|
+
# Hash of entities and their registered components
|
57
|
+
#
|
58
|
+
def entities
|
59
|
+
@entities ||= reset!
|
60
|
+
end
|
61
|
+
|
62
|
+
# Register an +Entity+ as conforming to a specific +Component+
|
63
|
+
# behavior.
|
64
|
+
#
|
65
|
+
# @param entity [Entity] The +Entity+ that includes the behavior
|
66
|
+
# @param type [Module] A +Component+ module.
|
67
|
+
#
|
68
|
+
def register(entity, type)
|
69
|
+
entities[entity] << symbolize(type)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Retrieve all registered entities that include all of the
|
73
|
+
# components passed.
|
74
|
+
#
|
75
|
+
# @param components [Array<Component>] List of components
|
76
|
+
#
|
77
|
+
# @example
|
78
|
+
# EntityManager.entities
|
79
|
+
# => { #<Entity components=[:spatial, :size]>, #<Entity components=[:spatial]> }
|
80
|
+
#
|
81
|
+
# EntityManager.entities_with(:spatial, :size)
|
82
|
+
# => #<Entity components=[:spatial, :size]>
|
83
|
+
#
|
84
|
+
def entities_with(*components)
|
85
|
+
entities.select { |entity, types| includes_all?(types, Set[*components]) }.keys
|
86
|
+
end
|
87
|
+
|
88
|
+
# Remove all entities.
|
89
|
+
#
|
90
|
+
def reset!
|
91
|
+
@entities = Hash.new { |h,k| h[k] = Set.new }
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def includes_all?(types, items)
|
97
|
+
items.subset?(types)
|
98
|
+
end
|
99
|
+
|
100
|
+
def symbolize(type)
|
101
|
+
type.name.demodulize.underscore.gsub("_behavior", "").to_sym
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|