gamebox 0.4.0.rc2 → 0.4.0.rc3
Sign up to get free protection for your applications and to get access to all the features.
- data/{docs/getting_started.rdoc → README.md} +92 -77
- data/TODO.txt +16 -6
- data/lib/gamebox.rb +2 -0
- data/lib/gamebox/behaviors/input_stater.rb +11 -0
- data/lib/gamebox/behaviors/positioned.rb +3 -1
- data/lib/gamebox/core/actor.rb +25 -5
- data/lib/gamebox/core/behavior.rb +5 -1
- data/lib/gamebox/core/hooked_gosu_window.rb +1 -2
- data/lib/gamebox/core/wrapped_screen.rb +8 -0
- data/lib/gamebox/lib/method_missing_collector.rb +10 -0
- data/lib/gamebox/lib/{evented_attributes.rb → observable_attributes.rb} +1 -1
- data/lib/gamebox/spec/helper.rb +23 -1
- data/lib/gamebox/stagehands/spatial_tree_stagehand.rb +0 -2
- data/lib/gamebox/version.rb +1 -1
- data/spec/acceptance/basic_actor_lifecycle_spec.rb +26 -17
- data/spec/acceptance/input_stater_spec.rb +48 -0
- data/spec/acceptance/pausing_spec.rb +28 -12
- data/spec/core/actor_spec.rb +102 -33
- data/spec/core/behavior_spec.rb +4 -0
- data/spec/core/hooked_gosu_window_spec.rb +0 -9
- metadata +8 -5
- data/README.rdoc +0 -38
@@ -1,6 +1,18 @@
|
|
1
|
-
|
1
|
+
# Gamebox
|
2
|
+
![http://travis-ci.org/shawn42/gamebox](https://secure.travis-ci.org/shawn42/gamebox.png)
|
3
|
+
![https://gemnasium.com/shawn42/gamebox](https://gemnasium.com/shawn42/gamebox.png)
|
2
4
|
|
3
|
-
|
5
|
+
* A game template for building and distributing Gosu games.
|
6
|
+
* Quickly generate a game and have it up and running.
|
7
|
+
* Provide conventions and DSL for building your game.
|
8
|
+
* Facilitate quickly building distributable artifacts.
|
9
|
+
* http://shawn42.github.com/gamebox/
|
10
|
+
* see [gamebox on rubygems.org](https://rubygems.org/gems/gamebox) for the list of requirements
|
11
|
+
|
12
|
+
|
13
|
+
# Getting started with Gamebox
|
14
|
+
|
15
|
+
## Purpose
|
4
16
|
|
5
17
|
Why use Gamebox? Gamebox was designed to spring board game development. It allows the developer to define business rules about a game very quickly without having to worry about resource loading, sound/music management, creating windows, or messing with viewports. Gamebox allows you to define a game's business rules within minutes.
|
6
18
|
|
@@ -8,95 +20,93 @@ The driving idea behind Gamebox is to provide the ability to have as many of the
|
|
8
20
|
|
9
21
|
The reason I wrote Gamebox is twofold: first, to aid in 48 hour game writing competitions and second, to allow me to write simple educational games for my kids.
|
10
22
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
├──
|
30
|
-
|
31
|
-
├──
|
32
|
-
├──
|
33
|
-
│
|
34
|
-
│
|
35
|
-
│
|
36
|
-
├──
|
37
|
-
│
|
38
|
-
│
|
39
|
-
│
|
40
|
-
|
41
|
-
│
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
cd zapper
|
56
|
-
rake
|
57
|
-
|
58
|
-
== Actors to the Stage
|
23
|
+
## Installation
|
24
|
+
|
25
|
+
* gem install gamebox
|
26
|
+
* or [tar](http://shawn42.github.com/gamebox)
|
27
|
+
* or git clone git://github.com/shawn42/gamebox.git
|
28
|
+
|
29
|
+
## Game Creation
|
30
|
+
|
31
|
+
``` $ gamebox zapper```
|
32
|
+
|
33
|
+
```$ this will create the directory structure and needed files to get a basic actor up on the screen```
|
34
|
+
|
35
|
+
zapper
|
36
|
+
├── Gemfile
|
37
|
+
├── README.rdoc
|
38
|
+
├── Rakefile
|
39
|
+
├── config
|
40
|
+
│ ├── boot.rb
|
41
|
+
│ ├── environment.rb
|
42
|
+
│ └── game.yml
|
43
|
+
├── data
|
44
|
+
│ ├── fonts
|
45
|
+
│ │ └── FONTS_GO_HERE
|
46
|
+
│ ├── graphics
|
47
|
+
│ │ └── GRAPHICS_GO_HERE
|
48
|
+
│ ├── music
|
49
|
+
│ │ └── MUSIC_GOES_HERE
|
50
|
+
│ └── sounds
|
51
|
+
│ └── SOUND_FX_GO_HERE
|
52
|
+
├── spec
|
53
|
+
│ └── helper.rb
|
54
|
+
└── src
|
55
|
+
├── actors
|
56
|
+
│ └── player.rb
|
57
|
+
├── app.rb
|
58
|
+
└── demo_stage.rb
|
59
|
+
|
60
|
+
|
61
|
+
you now have a runnable gamebox game
|
62
|
+
`
|
63
|
+
` cd zapper
|
64
|
+
rake
|
65
|
+
|
66
|
+
## Actors to the Stage
|
59
67
|
|
60
68
|
An actor is the base class for any game object. A building, the player, the score, the bullet are all examples of actors. Actors can even be invisible. Any number of behaviors can be added to an actor to define how it will react to the world via the define_actor method. Actors are simply buckets of data and behaviors. The interactions with system are all driven by their behaviors.
|
61
69
|
|
62
70
|
So Actors sound fun, how do I get one? That's where the ActorFactory comes in. In your Stage class (demo_stage.rb by default) you can use the create_actor helper method as shown below.
|
63
|
-
|
64
|
-
@score
|
71
|
+
`
|
72
|
+
` @score # create_actor :score, x: 10, y: 10
|
65
73
|
|
66
74
|
This call will return an instance of a score (the first arg is the symbolized version of the actor type). It will also create the view for the actor and register it to be drawn. Which view is instantiated depends on the actor requested. The factory will always look for a view named the same as the actor with _view on the end. So the actor score will look for score_view. If score_view does not exist, a generic view class will be used based on the behaviors of the actor. Each view is constructed with a reference to the actor it is displaying. See ActorFactor#build for more details.
|
67
75
|
|
68
76
|
That's great, but how do I tell my actors what to do? By defining their behaviors!
|
69
|
-
|
70
|
-
define_actor :score do
|
77
|
+
`
|
78
|
+
`define_actor :score do
|
71
79
|
has_behaviors :positioned, :score_keeping
|
72
80
|
end
|
73
81
|
|
74
|
-
== Sound
|
75
82
|
|
76
|
-
|
83
|
+
## Sound
|
77
84
|
|
78
|
-
|
85
|
+
There are two ways to play sounds in Gamebox. From your stage you can simple access the SoundManager via the sound_manager method. From your actors, you can play sounds via the play_sound helper method in the audible behavior.
|
86
|
+
`
|
87
|
+
` # music
|
79
88
|
sound_manager.play_music :overworld
|
80
89
|
|
81
90
|
# sounds
|
82
91
|
sound_manager.play_sound :death
|
83
92
|
|
84
93
|
or
|
85
|
-
|
86
|
-
# from an actor
|
87
|
-
|
94
|
+
`
|
95
|
+
` # from an actor
|
96
|
+
has_behavior :audible
|
88
97
|
actor.react_to :play_sound, :jump
|
89
98
|
|
90
|
-
|
99
|
+
## Resources
|
91
100
|
|
92
101
|
All file loading is handled by the ResourceManager. It handles loading images, sounds, fonts, config files, and even svg files. The resource manager caches images based on their name and fonts based on their name/size pair. Example usage from the ScoreView class:
|
102
|
+
`
|
103
|
+
` font # @mode.resource_manager.load_font 'Asimov.ttf', 30
|
93
104
|
|
94
|
-
|
95
|
-
|
96
|
-
== Behaviors
|
105
|
+
## Behaviors
|
97
106
|
|
98
107
|
Behaviors are designed to allow you to build Actors from previously built chunks of code. Lets look at the built in Animated behavior.
|
99
|
-
|
108
|
+
`
|
109
|
+
` define_behavior :shooting do
|
100
110
|
requires :input_manager
|
101
111
|
setup do
|
102
112
|
input_manager.reg :down, KbSpace do
|
@@ -112,10 +122,9 @@ Behaviors are designed to allow you to build Actors from previously built chunks
|
|
112
122
|
end
|
113
123
|
|
114
124
|
|
115
|
-
|
116
125
|
This snippet show us that our Actor wants to be updated on every gameloop and that it wants to be animated. Gamebox favors convention over configuration. This means that there are default locations and setting for most things. They can be overridden but you are not required to do so. The animated behavior assumes that your animated images are in a directory structure based on the Actor's underscored name and its current action.
|
117
|
-
|
118
|
-
zapper/
|
126
|
+
`
|
127
|
+
` zapper/
|
119
128
|
`-- data
|
120
129
|
`-- graphics
|
121
130
|
`-- super_hero
|
@@ -129,10 +138,10 @@ This snippet show us that our Actor wants to be updated on every gameloop and th
|
|
129
138
|
|-- 1.png
|
130
139
|
`-- 2.png
|
131
140
|
|
132
|
-
Here we can see that the SuperHere class has three actions (flying, walking, idle). These actions will be set by calling action
|
141
|
+
Here we can see that the SuperHere class has three actions (flying, walking, idle). These actions will be set by calling action# on your Actor.
|
133
142
|
|
134
|
-
batman
|
135
|
-
batman.action
|
143
|
+
batman # create_actor :super_hero
|
144
|
+
batman.action # :flying
|
136
145
|
|
137
146
|
The animation will cycle through all the numbered png files for the current action. To stop animating you simple call stop_animating.
|
138
147
|
|
@@ -141,19 +150,25 @@ The animation will cycle through all the numbered png files for the current acti
|
|
141
150
|
|
142
151
|
Animated and Updatable are just two behaviors available in Gamebox. Other include graphical, audible, layered, and physical. You can easily add your own game specific behaviors by extending Behavior. (see Wanderer in rague example for a simple behavior).
|
143
152
|
|
144
|
-
|
153
|
+
## Stages
|
145
154
|
|
146
155
|
A Stage is where all the magic happens. A Stage can be any gameplay mode in your game. The main menu has a different interactions than the _real_ game. In Gamebox, each should have their own Stage. Stages are configured via the stage_config.yml file in config. Listing :demo there will create DemoStage for you. Game.rb decides which stage to start on.
|
147
156
|
|
148
|
-
|
157
|
+
## StageManager
|
149
158
|
|
150
159
|
So how do these actors end up on the screen? The StageManager. The stage manager handles contruction of new stages and drawing their actors too. Gamebox has built-in support for parallaxing. Parallax layers denote this distance from the audience an Actor should be. The clouds in the sky that are really far away can be set to INFINITY to have them not move at all as the viewport moves. Each parallax layer has layers to allow Actors to be on top of one another, but have the same distance from the audience. The StageManager respects Actor's layered behaviors, if specified. If no layer is specified, the StageManager puts the Actor on parallax layer one of layer one. Example layered behavior:
|
151
160
|
|
152
|
-
has_behavior :layered
|
161
|
+
has_behavior :layered #> {:parallax #> 30, :layer #> 2}
|
153
162
|
|
154
163
|
This Actor will be 30 layers away from the audience, and will sit on top of anything in parallax layer 30 that has layer less than 2.
|
155
164
|
|
156
165
|
|
157
|
-
|
158
|
-
|
159
|
-
|
166
|
+
## Publisher
|
167
|
+
## Physics
|
168
|
+
## SVG Levels
|
169
|
+
|
170
|
+
## LICENSE:
|
171
|
+
|
172
|
+
(MIT)
|
173
|
+
|
174
|
+
Copyright © 2012 Shawn Anderson
|
data/TODO.txt
CHANGED
@@ -1,16 +1,26 @@
|
|
1
1
|
TAKE YOUR PICK:
|
2
|
+
- convert generators to thor
|
3
|
+
- update README.rdoc in template app
|
4
|
+
- generate sample Gemfile with current gamebox version
|
5
|
+
|
6
|
+
- framerate setting should come from Gamebox.configuration.target_framerate?
|
7
|
+
- game.yml settings .. ^^^
|
8
|
+
|
9
|
+
- nice helpers for testing behaviors
|
10
|
+
|
2
11
|
- add define_style that defines a bucket of behaviors
|
3
12
|
- add helper for has_required_attributes on an actor from a behavior (checking that opts for the behavior has said key)
|
13
|
+
|
14
|
+
- solidify rdocs (including tutorial)
|
15
|
+
- input_manager should accept symbols for look up.. :space => KbSpace
|
16
|
+
- ZERO PENDING SPECS
|
17
|
+
|
18
|
+
- release!
|
19
|
+
|
4
20
|
- move all classes into Gamebox module
|
5
|
-
- collision detection performance for tiles?
|
6
21
|
- collision detection honoring rotation?
|
7
22
|
- highscore upload system (use from chingu) (takes json now)
|
8
|
-
- solidify rdocs (including tutorial)
|
9
23
|
- collidable "grouping"
|
10
|
-
- framerate setting should come from Gamebox.configuration.target_framerate?
|
11
|
-
- game.yml settings .. ^^^
|
12
|
-
- input_manager should accept symbols for look up.. :space => KbSpace
|
13
|
-
- ZERO PENDING SPECS
|
14
24
|
|
15
25
|
EXAMPLES:
|
16
26
|
- move to separate repo?
|
data/lib/gamebox.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
define_behavior :positioned do
|
2
2
|
requires :director
|
3
3
|
setup do
|
4
|
-
|
4
|
+
x = opts[:x] || 0
|
5
|
+
y = opts[:y] || 0
|
6
|
+
actor.has_attributes x: x, y: y
|
5
7
|
director.when :update do |time|
|
6
8
|
if @x_dirty || @y_dirty
|
7
9
|
actor.react_to :position_changed
|
data/lib/gamebox/core/actor.rb
CHANGED
@@ -3,26 +3,31 @@
|
|
3
3
|
# They are created and hooked up to their optional View class in Stage#create_actor.
|
4
4
|
class Actor
|
5
5
|
extend Publisher
|
6
|
-
include
|
6
|
+
include ObservableAttributes
|
7
7
|
include Gamebox::Extensions::Object::Yoda
|
8
8
|
can_fire_anything
|
9
9
|
construct_with :this_object_context
|
10
10
|
public :this_object_context
|
11
11
|
|
12
12
|
def initialize
|
13
|
-
has_attribute :alive
|
13
|
+
has_attribute :alive, true
|
14
14
|
@behaviors = {}
|
15
15
|
end
|
16
16
|
|
17
17
|
def configure(opts={}) # :nodoc:
|
18
18
|
has_attributes opts
|
19
19
|
self.actor_type = opts[:actor_type]
|
20
|
-
self.alive = true
|
21
20
|
end
|
22
21
|
|
23
22
|
def add_behavior(name, behavior)
|
24
23
|
@behaviors[name] = behavior
|
25
24
|
end
|
25
|
+
|
26
|
+
def remove_behavior(name)
|
27
|
+
@behaviors.delete(name).tap do |behavior|
|
28
|
+
behavior.react_to :remove if behavior
|
29
|
+
end
|
30
|
+
end
|
26
31
|
|
27
32
|
def react_to(message, *opts)
|
28
33
|
# TODO cache the values array?
|
@@ -61,7 +66,11 @@ class Actor
|
|
61
66
|
|
62
67
|
def define(actor_type, opts={}, &blk)
|
63
68
|
@definitions ||= {}
|
69
|
+
raise "Actor [#{actor_type}] already defined at #{@definitions[actor_type].source}" if @definitions[actor_type]
|
70
|
+
|
64
71
|
definition = ActorDefinition.new
|
72
|
+
# TODO evaluate the perf of doing this
|
73
|
+
definition.source = caller.detect{|c|!c.match /core/}
|
65
74
|
definition.instance_eval &blk if block_given?
|
66
75
|
@definitions[actor_type] = definition
|
67
76
|
|
@@ -84,13 +93,24 @@ class Actor
|
|
84
93
|
end
|
85
94
|
|
86
95
|
class ActorDefinition
|
87
|
-
attr_accessor :behaviors, :attributes, :view_blk, :behavior_blk
|
96
|
+
attr_accessor :behaviors, :attributes, :view_blk, :behavior_blk, :source
|
88
97
|
def initialize
|
89
98
|
@behaviors = []
|
90
99
|
@attributes = []
|
91
100
|
end
|
92
101
|
|
93
|
-
def has_behaviors(*behaviors)
|
102
|
+
def has_behaviors(*behaviors, &blk)
|
103
|
+
if block_given?
|
104
|
+
collector = MethodMissingCollector.new
|
105
|
+
collector.instance_eval &blk
|
106
|
+
collector.calls.each do |name, args|
|
107
|
+
if args.empty?
|
108
|
+
@behaviors << name
|
109
|
+
else
|
110
|
+
@behaviors << {name => args.first}
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
94
114
|
behaviors.each do |beh|
|
95
115
|
@behaviors << beh
|
96
116
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# Behavior is any type of behavior an actor can exibit.
|
2
2
|
class Behavior
|
3
|
-
construct_with :actor
|
3
|
+
construct_with :actor, :behavior_factory
|
4
4
|
|
5
5
|
attr_accessor :opts
|
6
6
|
|
@@ -23,6 +23,10 @@ class Behavior
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
+
def add_behavior(behavior_name, opts = {})
|
27
|
+
behavior_factory.add_behavior actor, behavior_name, opts
|
28
|
+
end
|
29
|
+
|
26
30
|
class << self
|
27
31
|
|
28
32
|
def define(behavior_type, &blk)
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'publisher'
|
2
1
|
module GosuWindowAPI
|
3
2
|
def initialize(width, height, fullscreen)
|
4
3
|
super(width, height, fullscreen)
|
@@ -29,8 +28,8 @@ module GosuWindowAPI
|
|
29
28
|
end
|
30
29
|
|
31
30
|
class HookedGosuWindow < Window
|
32
|
-
include GosuWindowAPI
|
33
31
|
extend Publisher
|
32
|
+
include GosuWindowAPI
|
34
33
|
can_fire :update, :draw, :button_down, :button_up
|
35
34
|
|
36
35
|
end
|
@@ -24,6 +24,10 @@ class WrappedScreen
|
|
24
24
|
@screen.fullscreen? ? screen_height : @screen.height
|
25
25
|
end
|
26
26
|
|
27
|
+
def record(width, height, &blk)
|
28
|
+
@screen.record width, height, &blk
|
29
|
+
end
|
30
|
+
|
27
31
|
def draw_box(x1,y1,x2,y2,color, z)
|
28
32
|
c = convert_color(color)
|
29
33
|
@screen.draw_line x1, y1, c, x2, y1, c, z
|
@@ -121,5 +125,9 @@ class WrappedScreen
|
|
121
125
|
def print(text, x, y, z, font_style)
|
122
126
|
font_style.font.draw text, x, y, z, font_style.x_scale, font_style.y_scale, convert_color(font_style.color)
|
123
127
|
end
|
128
|
+
|
129
|
+
def draw_image(image, x, y, z, x_scale = 1, y_scale = 1, color = 0xffffffff, mode = :default)
|
130
|
+
image.draw x, y, z, x_scale, y_scale, color, mode
|
131
|
+
end
|
124
132
|
end
|
125
133
|
|
data/lib/gamebox/spec/helper.rb
CHANGED
@@ -3,6 +3,14 @@
|
|
3
3
|
# # nothing for specs!
|
4
4
|
# end
|
5
5
|
include Gamebox
|
6
|
+
class Gosu::Window
|
7
|
+
def initialize(*args, &blk)
|
8
|
+
# TODO not sure how to handle this for travis-ci breakage..
|
9
|
+
# hopefully travis ci starts working again some day...
|
10
|
+
# sometimes causes seg faults if running bundle exec rake
|
11
|
+
# autorelease garbage in output if I don't do this
|
12
|
+
end
|
13
|
+
end
|
6
14
|
|
7
15
|
module GameboxSpecHelpers
|
8
16
|
module ClassMethods
|
@@ -55,7 +63,7 @@ module GameboxSpecHelpers
|
|
55
63
|
end
|
56
64
|
end
|
57
65
|
|
58
|
-
def expects_event(target, event_name, expected_args)
|
66
|
+
def expects_event(target, event_name, expected_args=[[]])
|
59
67
|
args = []
|
60
68
|
target.when event_name do |*event_args|
|
61
69
|
args << event_args
|
@@ -255,6 +263,12 @@ module GameboxAcceptanceSpecHelpers
|
|
255
263
|
act.should have_attrs(attrs)
|
256
264
|
end
|
257
265
|
|
266
|
+
def see_no_actor_attrs(actor_type, *attrs)
|
267
|
+
act = game.actor(actor_type)
|
268
|
+
act.should be
|
269
|
+
act.should have_no_attrs(attrs)
|
270
|
+
end
|
271
|
+
|
258
272
|
def update(time)
|
259
273
|
gosu.update time
|
260
274
|
end
|
@@ -303,6 +317,14 @@ module GameboxAcceptanceSpecHelpers
|
|
303
317
|
end
|
304
318
|
end
|
305
319
|
end
|
320
|
+
|
321
|
+
RSpec::Matchers.define :have_no_attrs do |expected_attributes|
|
322
|
+
match do |actor|
|
323
|
+
expected_attributes.each do |name|
|
324
|
+
actor.has_attribute?(name).should be_false
|
325
|
+
end
|
326
|
+
end
|
327
|
+
end
|
306
328
|
end
|
307
329
|
end
|
308
330
|
|
data/lib/gamebox/version.rb
CHANGED
@@ -27,7 +27,6 @@ describe "The basic life cycle of an actor", acceptance: true do
|
|
27
27
|
|
28
28
|
define_behavior :death_on_d do
|
29
29
|
requires :input_manager
|
30
|
-
# TODO can we rename this to configure?
|
31
30
|
setup do
|
32
31
|
input_manager.reg :up, KbD do
|
33
32
|
actor.remove
|
@@ -35,6 +34,15 @@ describe "The basic life cycle of an actor", acceptance: true do
|
|
35
34
|
end
|
36
35
|
end
|
37
36
|
|
37
|
+
define_behavior :positioned_on_p do
|
38
|
+
requires :input_manager
|
39
|
+
setup do
|
40
|
+
input_manager.reg :up, KbP do
|
41
|
+
add_behavior :positioned, x: 500, y:30
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
38
46
|
define_actor_view :mc_bane_view do
|
39
47
|
requires :resource_manager # needs these injected
|
40
48
|
configure do
|
@@ -43,32 +51,23 @@ describe "The basic life cycle of an actor", acceptance: true do
|
|
43
51
|
|
44
52
|
draw do |target, x_off, y_off, z|
|
45
53
|
# TODO TRACK THESE DRAWINGS
|
46
|
-
@image
|
54
|
+
target.draw_image @image, 1, 2, 3
|
47
55
|
end
|
48
56
|
end
|
49
57
|
|
50
58
|
# no code is allowed in the actor!
|
51
59
|
# all done through behaviors
|
52
60
|
define_actor :mc_bane do
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
# actor.has_view do |view|
|
59
|
-
# view.uses :resource_manager
|
60
|
-
# view.configure do
|
61
|
-
# end
|
62
|
-
|
63
|
-
# view.draw do |target, x_off, y_off, z|
|
64
|
-
# end
|
65
|
-
# end
|
61
|
+
has_behaviors do
|
62
|
+
shooty bullets: 50
|
63
|
+
death_on_d
|
64
|
+
positioned_on_p
|
65
|
+
end
|
66
66
|
end
|
67
67
|
|
68
68
|
|
69
69
|
it 'creates an actor from within stage with the correct behaviors and updates' do
|
70
|
-
|
71
|
-
game.stage do |stage| # instance of TestingStage
|
70
|
+
game.stage do |stage|
|
72
71
|
create_actor :mc_bane, x: 250, y: 400
|
73
72
|
end
|
74
73
|
see_actor_attrs :mc_bane, bullets: 50
|
@@ -89,6 +88,16 @@ describe "The basic life cycle of an actor", acceptance: true do
|
|
89
88
|
|
90
89
|
end
|
91
90
|
|
91
|
+
it 'can dynamically add behaviors' do
|
92
|
+
game.stage do |stage|
|
93
|
+
create_actor :mc_bane
|
94
|
+
end
|
95
|
+
see_no_actor_attrs :mc_bane, :x, :y
|
96
|
+
|
97
|
+
release_key KbP
|
98
|
+
see_actor_attrs :mc_bane, x: 500, y: 30
|
99
|
+
end
|
100
|
+
|
92
101
|
it 'uses default values from actor definition'
|
93
102
|
end
|
94
103
|
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe "Using input stater", acceptance: true do
|
4
|
+
|
5
|
+
|
6
|
+
define_actor :foxy do
|
7
|
+
has_behavior input_stater: {
|
8
|
+
[KbLeft] => :move_left,
|
9
|
+
[KbRight, KbD] => :move_right
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'sets actor state based on input' do
|
14
|
+
game.stage do |stage| # instance of TestingStage
|
15
|
+
create_actor :foxy
|
16
|
+
end
|
17
|
+
|
18
|
+
see_actor_attrs :foxy,
|
19
|
+
move_left: false
|
20
|
+
see_actor_attrs :foxy,
|
21
|
+
move_right: false
|
22
|
+
|
23
|
+
press_key KbLeft
|
24
|
+
press_key KbD
|
25
|
+
|
26
|
+
see_actor_attrs :foxy,
|
27
|
+
move_left: true
|
28
|
+
|
29
|
+
see_actor_attrs :foxy,
|
30
|
+
move_right: true
|
31
|
+
|
32
|
+
release_key KbD
|
33
|
+
see_actor_attrs :foxy,
|
34
|
+
move_right: false
|
35
|
+
|
36
|
+
press_key KbRight
|
37
|
+
|
38
|
+
see_actor_attrs :foxy,
|
39
|
+
move_right: true
|
40
|
+
|
41
|
+
release_key KbRight
|
42
|
+
|
43
|
+
see_actor_attrs :foxy,
|
44
|
+
move_right: false
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
@@ -16,7 +16,7 @@ describe "pausing in gamebox", acceptance: true do
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
define_actor :
|
19
|
+
define_actor :mountain do
|
20
20
|
has_behavior :shoot_rock
|
21
21
|
end
|
22
22
|
|
@@ -27,34 +27,50 @@ describe "pausing in gamebox", acceptance: true do
|
|
27
27
|
timer_manager.add_timer 'stage_timer', 2000 do
|
28
28
|
@counter += 1
|
29
29
|
end
|
30
|
-
create_actor :
|
30
|
+
create_actor :mountain
|
31
|
+
|
32
|
+
input_manager.reg :down, KbP do
|
33
|
+
pause
|
34
|
+
end
|
35
|
+
|
36
|
+
on_pause do
|
37
|
+
@pause_label = create_actor :label, text: "pause"
|
38
|
+
input_manager.reg :down, KbP do
|
39
|
+
unpause
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
on_unpause do
|
44
|
+
@pause_label.remove
|
45
|
+
end
|
31
46
|
end
|
32
|
-
|
47
|
+
game.should_not have_actor(:label)
|
48
|
+
see_actor_attrs :mountain, rocks_shot: 0
|
33
49
|
see_stage_ivars counter: 0
|
34
50
|
|
35
51
|
update 100
|
36
|
-
see_actor_attrs :
|
52
|
+
see_actor_attrs :mountain, rocks_shot: 0
|
37
53
|
see_stage_ivars counter: 0
|
38
54
|
|
39
55
|
update 901
|
40
|
-
see_actor_attrs :
|
56
|
+
see_actor_attrs :mountain, rocks_shot: 1
|
41
57
|
see_stage_ivars counter: 0
|
42
58
|
|
43
|
-
|
59
|
+
press_key KbP
|
60
|
+
game.should have_actor(:label)
|
44
61
|
update 2001
|
45
|
-
see_actor_attrs :
|
62
|
+
see_actor_attrs :mountain, rocks_shot: 1
|
46
63
|
see_stage_ivars counter: 0
|
47
64
|
|
48
65
|
update 2001
|
49
|
-
see_actor_attrs :
|
66
|
+
see_actor_attrs :mountain, rocks_shot: 1
|
50
67
|
see_stage_ivars counter: 0
|
51
68
|
|
52
|
-
|
69
|
+
press_key KbP
|
70
|
+
game.should_not have_actor(:label)
|
53
71
|
update 2001
|
54
|
-
see_actor_attrs :
|
72
|
+
see_actor_attrs :mountain, rocks_shot: 2
|
55
73
|
see_stage_ivars counter: 1
|
56
|
-
|
57
|
-
pending "add more actors _during_ the pause"
|
58
74
|
end
|
59
75
|
|
60
76
|
end
|
data/spec/core/actor_spec.rb
CHANGED
@@ -2,16 +2,17 @@ require 'helper'
|
|
2
2
|
describe Actor do
|
3
3
|
|
4
4
|
subject { create_actor :actor }
|
5
|
+
let(:behavior) { stub(react_to: nil) }
|
5
6
|
|
6
|
-
it '
|
7
|
-
subject.
|
7
|
+
it 'is alive' do
|
8
|
+
subject.should be_alive
|
8
9
|
end
|
9
10
|
|
10
|
-
it '
|
11
|
+
it 'has the correct type' do
|
11
12
|
subject.actor_type.should == :actor
|
12
13
|
end
|
13
14
|
|
14
|
-
it '
|
15
|
+
it 'fires anything' do
|
15
16
|
Proc.new {
|
16
17
|
subject.when :foofoo_bar do
|
17
18
|
"blah"
|
@@ -19,60 +20,128 @@ describe Actor do
|
|
19
20
|
}.should_not raise_error
|
20
21
|
end
|
21
22
|
|
22
|
-
#
|
23
|
-
|
24
|
-
|
25
|
-
|
23
|
+
describe "#add_behavior" do
|
24
|
+
it 'adds a behavior to the actors list of behaviors' do
|
25
|
+
subject.add_behavior :foo, :bar
|
26
|
+
subject.has_behavior?(:foo).should be_true
|
27
|
+
end
|
28
|
+
end
|
26
29
|
|
27
|
-
#
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
# end
|
30
|
+
describe "#remove_behavior" do
|
31
|
+
it 'removes a behavior to the actors list of behaviors' do
|
32
|
+
subject.add_behavior :foo, behavior
|
33
|
+
subject.has_behavior?(:foo).should be_true
|
32
34
|
|
33
|
-
|
34
|
-
|
35
|
+
subject.remove_behavior :foo
|
36
|
+
subject.has_behavior?(:foo).should be_false
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'doesnt raise if behavior already exists' do
|
40
|
+
subject.remove_behavior :foo
|
41
|
+
subject.has_behavior?(:foo).should be_false
|
42
|
+
end
|
35
43
|
end
|
36
44
|
|
37
45
|
describe "#has_attribute" do
|
38
|
-
it 'adds an evented attribute'
|
46
|
+
it 'adds an evented attribute' do
|
47
|
+
subject.has_attribute :foo, :default_value
|
48
|
+
subject.foo.should == :default_value
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'ignores default value if the attribute already exists' do
|
52
|
+
subject.has_attribute :foo, :first_value
|
53
|
+
subject.has_attribute :foo, :second_value
|
54
|
+
subject.foo.should == :first_value
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'adds attr w/o default' do
|
58
|
+
subject.has_attribute :foo
|
59
|
+
subject.foo.should be_nil
|
60
|
+
subject.foo?.should be_false
|
61
|
+
end
|
39
62
|
end
|
40
63
|
|
41
64
|
describe "#has_attribute?" do
|
42
|
-
it 'returns true if the actor has the attribute'
|
43
|
-
|
65
|
+
it 'returns true if the actor has the attribute' do
|
66
|
+
subject.has_attribute :foo
|
67
|
+
subject.has_attribute?(:foo).should be_true
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'returns false if the actor does not have the attribute' do
|
71
|
+
subject.has_attribute?(:foo).should be_false
|
72
|
+
end
|
44
73
|
end
|
45
74
|
|
46
75
|
describe "#has_behavior?" do
|
47
|
-
it 'returns true if the actor has the behavior'
|
48
|
-
|
76
|
+
it 'returns true if the actor has the behavior' do
|
77
|
+
subject.add_behavior :jumper, behavior
|
78
|
+
subject.has_behavior?(:jumper).should be_true
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'returns false if the actor does not have the behavior' do
|
82
|
+
subject.has_behavior?(:jumper).should be_false
|
83
|
+
end
|
49
84
|
end
|
50
85
|
|
51
86
|
describe "#emit" do
|
52
|
-
it 'allows firing of events w/ the actor as the source'
|
87
|
+
it 'allows firing of events w/ the actor as the source' do
|
88
|
+
expects_event(subject, :foopy, [[87]]) do
|
89
|
+
subject.emit :foopy, 87
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "#react_to" do
|
95
|
+
let(:foo) { mock }
|
96
|
+
let(:bar) { mock }
|
97
|
+
it 'sends the message to all its behaviors' do
|
98
|
+
foo.expects(:react_to).with(:hello, :world)
|
99
|
+
bar.expects(:react_to).with(:hello, :world)
|
100
|
+
subject.add_behavior :foo, foo
|
101
|
+
subject.add_behavior :bar, bar
|
102
|
+
|
103
|
+
subject.react_to :hello, :world
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "#remove" do
|
108
|
+
let(:foo) { mock }
|
109
|
+
|
110
|
+
it 'kills the actor' do
|
111
|
+
subject.remove
|
112
|
+
subject.should_not be_alive
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'sends :remove to behaviors' do
|
116
|
+
foo.expects(:react_to).with(:remove)
|
117
|
+
subject.add_behavior :foo, foo
|
118
|
+
|
119
|
+
subject.remove
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'fires :remove me' do
|
123
|
+
foo.expects(:react_to).with(:remove)
|
124
|
+
subject.add_behavior :foo, foo
|
125
|
+
|
126
|
+
expects_event(subject, :remove_me) do
|
127
|
+
subject.remove
|
128
|
+
end
|
129
|
+
end
|
53
130
|
end
|
54
131
|
|
132
|
+
|
55
133
|
describe ".define" do
|
56
134
|
it 'adds an actor definition' do
|
57
|
-
Actor.define :
|
135
|
+
Actor.define :mc_bane2 do |act|
|
58
136
|
act.has_behavior shooty: { bullets: 50 }
|
59
137
|
act.has_behavior :death_on_d
|
60
138
|
end
|
61
139
|
|
62
|
-
definition = Actor.definitions[:
|
140
|
+
definition = Actor.definitions[:mc_bane2]
|
63
141
|
definition.should be
|
64
142
|
definition.behaviors.should == [{shooty: {bullets:50}}, :death_on_d]
|
65
143
|
end
|
66
144
|
end
|
67
145
|
|
146
|
+
|
68
147
|
end
|
69
|
-
#
|
70
|
-
# class Cool < Behavior; end
|
71
|
-
# class Smart < Behavior; end
|
72
|
-
# class Coder < Actor
|
73
|
-
# has_behavior :smart, :cool
|
74
|
-
# end
|
75
|
-
# class Shawn < Coder; end
|
76
|
-
# class JamesKilton < Coder
|
77
|
-
# has_behavior :smart => {:really => true}
|
78
|
-
# end
|
data/spec/core/behavior_spec.rb
CHANGED
@@ -1,15 +1,6 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
3
|
describe HookedGosuWindow do
|
4
|
-
class Gosu::Window
|
5
|
-
def initialize(*args)
|
6
|
-
# TODO not sure how to handle this for travis-ci breakage..
|
7
|
-
# hopefully travis ci starts working again some day...
|
8
|
-
# sometimes causes seg faults if running bundle exec rake
|
9
|
-
# autorelease garbage in output if I don't do this
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
4
|
subject { HookedGosuWindow.new 2, 3, false }
|
14
5
|
|
15
6
|
it 'should inherit from Gosu::Window' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gamebox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.0.
|
4
|
+
version: 0.4.0.rc3
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2012-05-
|
14
|
+
date: 2012-05-25 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: gosu
|
@@ -341,7 +341,7 @@ extensions: []
|
|
341
341
|
extra_rdoc_files: []
|
342
342
|
files:
|
343
343
|
- Gemfile
|
344
|
-
- README.
|
344
|
+
- README.md
|
345
345
|
- Rakefile
|
346
346
|
- TODO.txt
|
347
347
|
- app_generators/gamebox_generator.rb
|
@@ -371,7 +371,6 @@ files:
|
|
371
371
|
- docs/CODE_REVIEW
|
372
372
|
- docs/REFACTOR_NOTES.txt
|
373
373
|
- docs/gamebox.bat
|
374
|
-
- docs/getting_started.rdoc
|
375
374
|
- docs/logo.ico
|
376
375
|
- docs/logo.png
|
377
376
|
- gamebox.gemspec
|
@@ -393,6 +392,7 @@ files:
|
|
393
392
|
- lib/gamebox/behaviors/collidable/polygon_collidable.rb
|
394
393
|
- lib/gamebox/behaviors/emitting.rb
|
395
394
|
- lib/gamebox/behaviors/graphical.rb
|
395
|
+
- lib/gamebox/behaviors/input_stater.rb
|
396
396
|
- lib/gamebox/behaviors/layered.rb
|
397
397
|
- lib/gamebox/behaviors/physical.rb
|
398
398
|
- lib/gamebox/behaviors/positioned.rb
|
@@ -442,13 +442,14 @@ files:
|
|
442
442
|
- lib/gamebox/gamebox_application.rb
|
443
443
|
- lib/gamebox/lib/aliasing.rb
|
444
444
|
- lib/gamebox/lib/code_statistics.rb
|
445
|
-
- lib/gamebox/lib/evented_attributes.rb
|
446
445
|
- lib/gamebox/lib/ftor.rb
|
447
446
|
- lib/gamebox/lib/inflections.rb
|
448
447
|
- lib/gamebox/lib/inflector.rb
|
449
448
|
- lib/gamebox/lib/linked_list.rb
|
450
449
|
- lib/gamebox/lib/metaclass.rb
|
450
|
+
- lib/gamebox/lib/method_missing_collector.rb
|
451
451
|
- lib/gamebox/lib/min_max_helpers.rb
|
452
|
+
- lib/gamebox/lib/observable_attributes.rb
|
452
453
|
- lib/gamebox/lib/platform.rb
|
453
454
|
- lib/gamebox/lib/publisher_ext.rb
|
454
455
|
- lib/gamebox/lib/range_ext.rb
|
@@ -472,6 +473,7 @@ files:
|
|
472
473
|
- spec/acceptance/built_in_collision_handling_spec.rb
|
473
474
|
- spec/acceptance/chipmunk_collision_handling_spec.rb
|
474
475
|
- spec/acceptance/fps_actor_spec.rb
|
476
|
+
- spec/acceptance/input_stater_spec.rb
|
475
477
|
- spec/acceptance/pausing_spec.rb
|
476
478
|
- spec/acceptance/timer_usage_spec.rb
|
477
479
|
- spec/actors/emitter_spec.rb
|
@@ -541,6 +543,7 @@ test_files:
|
|
541
543
|
- spec/acceptance/built_in_collision_handling_spec.rb
|
542
544
|
- spec/acceptance/chipmunk_collision_handling_spec.rb
|
543
545
|
- spec/acceptance/fps_actor_spec.rb
|
546
|
+
- spec/acceptance/input_stater_spec.rb
|
544
547
|
- spec/acceptance/pausing_spec.rb
|
545
548
|
- spec/acceptance/timer_usage_spec.rb
|
546
549
|
- spec/actors/emitter_spec.rb
|
data/README.rdoc
DELETED
@@ -1,38 +0,0 @@
|
|
1
|
-
= gamebox
|
2
|
-
|
3
|
-
* http://shawn42.github.com/gamebox/
|
4
|
-
|
5
|
-
== DESCRIPTION:
|
6
|
-
|
7
|
-
A game template for building and distributing Gosu games. See docs/getting_started.rdoc for help getting started.
|
8
|
-
|
9
|
-
== FEATURES/PROBLEMS:
|
10
|
-
|
11
|
-
* Quickly generate a game and have it up and running.
|
12
|
-
|
13
|
-
== SYNOPSIS:
|
14
|
-
|
15
|
-
A game template for building and distributing Gosu games.
|
16
|
-
|
17
|
-
== REQUIREMENTS:
|
18
|
-
|
19
|
-
* Gosu
|
20
|
-
* conject gem
|
21
|
-
* publisher gem
|
22
|
-
* bundler
|
23
|
-
* rspec (for gamebox tests)
|
24
|
-
* algorithms gem (optional for line of site and A*)
|
25
|
-
|
26
|
-
== INSTALL:
|
27
|
-
|
28
|
-
* gem install gamebox; gamebox my_cool_game
|
29
|
-
|
30
|
-
== Build Status {<img src="https://secure.travis-ci.org/shawn42/gamebox.png"/>}[http://travis-ci.org/shawn42/gamebox]
|
31
|
-
|
32
|
-
== Dependency Status {<img src="https://gemnasium.com/shawn42/gamebox.png?travis"/>}[https://gemnasium.com/shawn42/gamebox]
|
33
|
-
|
34
|
-
== LICENSE:
|
35
|
-
|
36
|
-
(MIT)
|
37
|
-
|
38
|
-
Copyright (c) 2009 Shawn Anderson
|