pixie_dust 0.0.1
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.
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README +16 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/game.js +9200 -0
- data/lib/corelib.js +3331 -0
- data/lib/pixie_dust/version.rb +3 -0
- data/lib/pixie_dust.rb +14 -0
- data/pixie.json +15 -0
- data/pixie_dust.gemspec +29 -0
- data/source/active_bounds.coffee +48 -0
- data/source/ageable.coffee +23 -0
- data/source/bounded.coffee +282 -0
- data/source/camera.coffee +138 -0
- data/source/camera.fade.coffee +69 -0
- data/source/camera.flash.coffee +69 -0
- data/source/camera.rotate.coffee +11 -0
- data/source/camera.shake.coffee +27 -0
- data/source/camera.zoom.coffee +25 -0
- data/source/camera.zsort.coffee +13 -0
- data/source/clampable.coffee +61 -0
- data/source/collidable.coffee +126 -0
- data/source/collision.coffee +272 -0
- data/source/collision_response.coffee +28 -0
- data/source/color.coffee +1113 -0
- data/source/color_table.coffee +2534 -0
- data/source/controllable.coffee +66 -0
- data/source/cooldown.coffee +82 -0
- data/source/debuggable.coffee +253 -0
- data/source/drawable.coffee +167 -0
- data/source/dust_emitter.coffee +36 -0
- data/source/easing.coffee +38 -0
- data/source/emitter.coffee +7 -0
- data/source/emitterable.coffee +68 -0
- data/source/engine.coffee +274 -0
- data/source/engine.collision.coffee +77 -0
- data/source/engine.data.coffee +23 -0
- data/source/engine.delay.coffee +41 -0
- data/source/engine.fps_counter.coffee +32 -0
- data/source/engine.game_state.coffee +86 -0
- data/source/engine.joysticks.coffee +47 -0
- data/source/engine.keyboard.coffee +17 -0
- data/source/engine.levels.coffee +69 -0
- data/source/engine.mouse.coffee +16 -0
- data/source/engine.selector.coffee +166 -0
- data/source/engine.stats.coffee +16 -0
- data/source/engine.tilemap.coffee +41 -0
- data/source/engine_background.coffee +32 -0
- data/source/expirable.coffee +47 -0
- data/source/flickerable.coffee +78 -0
- data/source/follow.coffee +65 -0
- data/source/framerate.coffee +42 -0
- data/source/game_object.coffee +181 -0
- data/source/game_object.effect.coffee +33 -0
- data/source/game_object.meter.coffee +191 -0
- data/source/game_over.coffee +40 -0
- data/source/game_state.coffee +67 -0
- data/source/game_state.save_state.coffee +76 -0
- data/source/game_state.single_camera.coffee +40 -0
- data/source/game_state_cameras.coffee +33 -0
- data/source/level_state.coffee +32 -0
- data/source/movable.coffee +57 -0
- data/source/oscillator.coffee +18 -0
- data/source/pixie_dust.coffee +2 -0
- data/source/resource_loader.coffee +35 -0
- data/source/rotatable.coffee +38 -0
- data/source/sprite.coffee +181 -0
- data/source/text_effect.coffee +74 -0
- data/source/text_effect.floating.coffee +22 -0
- data/source/text_screen.coffee +38 -0
- data/source/tilemap.coffee +56 -0
- data/source/timed_events.coffee +78 -0
- data/source/title_screen.coffee +38 -0
- data/source/tween.coffee +70 -0
- data/test/active_bounds.coffee +67 -0
- data/test/bounded.coffee +98 -0
- data/test/camera.coffee +29 -0
- data/test/clampable.coffee +18 -0
- data/test/collidable.coffee +51 -0
- data/test/collision.coffee +70 -0
- data/test/color.coffee +533 -0
- data/test/controllable.coffee +108 -0
- data/test/cooldown.coffee +116 -0
- data/test/debuggable.coffee +71 -0
- data/test/drawable.coffee +31 -0
- data/test/emitter.coffee +0 -0
- data/test/emitterable.coffee +15 -0
- data/test/engine.coffee +228 -0
- data/test/engine_data.coffee +12 -0
- data/test/engine_delay.coffee +14 -0
- data/test/engine_selector.coffee +100 -0
- data/test/expirable.coffee +35 -0
- data/test/flickerable.coffee +51 -0
- data/test/follow.coffee +34 -0
- data/test/game_object.coffee +78 -0
- data/test/game_object_effect.coffee +17 -0
- data/test/metered.coffee +33 -0
- data/test/movable.coffee +46 -0
- data/test/oscillator.coffee +28 -0
- data/test/resource_loader.coffee +7 -0
- data/test/rotatable.coffee +20 -0
- data/test/sprite.coffee +21 -0
- data/test/text.coffee +25 -0
- data/test/timed_events.coffee +23 -0
- data/test/tweening.coffee +18 -0
- metadata +233 -0
@@ -0,0 +1,274 @@
|
|
1
|
+
( ->
|
2
|
+
###*
|
3
|
+
The Engine controls the game world and manages game state. Once you
|
4
|
+
set it up and let it run it pretty much takes care of itself.
|
5
|
+
|
6
|
+
You can use the engine to add or remove objects from the game world.
|
7
|
+
|
8
|
+
There are several modules that can include to add additional capabilities
|
9
|
+
to the engine.
|
10
|
+
|
11
|
+
The engine fires events that you may bind listeners to. Event listeners
|
12
|
+
may be bound with <code>engine.bind(eventName, callback)</code>
|
13
|
+
|
14
|
+
@name Engine
|
15
|
+
@constructor
|
16
|
+
@param {Object} I Instance variables of the engine
|
17
|
+
###
|
18
|
+
|
19
|
+
###*
|
20
|
+
Observe or modify the
|
21
|
+
entity data before it is added to the engine.
|
22
|
+
@name beforeAdd
|
23
|
+
@methodOf Engine#
|
24
|
+
@event
|
25
|
+
@param {Object} entityData
|
26
|
+
###
|
27
|
+
|
28
|
+
###*
|
29
|
+
Observe or configure a <code>gameObject</code> that has been added
|
30
|
+
to the engine.
|
31
|
+
@name afterAdd
|
32
|
+
@methodOf Engine#
|
33
|
+
@event
|
34
|
+
@param {GameObject} object The object that has just been added to the
|
35
|
+
engine.
|
36
|
+
###
|
37
|
+
|
38
|
+
###*
|
39
|
+
Called when the engine updates all the game objects.
|
40
|
+
|
41
|
+
@name update
|
42
|
+
@methodOf Engine#
|
43
|
+
@event
|
44
|
+
@param {Number} elapsedTime The time in seconds that has elapsed since the last update.
|
45
|
+
###
|
46
|
+
|
47
|
+
###*
|
48
|
+
Called after the engine completes an update. Here it is
|
49
|
+
safe to modify the game objects array.
|
50
|
+
|
51
|
+
@name afterUpdate
|
52
|
+
@methodOf Engine#
|
53
|
+
@event
|
54
|
+
###
|
55
|
+
|
56
|
+
###*
|
57
|
+
Called before the engine draws the game objects on the canvas. The current camera transform is applied.
|
58
|
+
|
59
|
+
@name beforeDraw
|
60
|
+
@methodOf Engine#
|
61
|
+
@event
|
62
|
+
@params {PixieCanvas} canvas A reference to the canvas to draw on.
|
63
|
+
###
|
64
|
+
|
65
|
+
###*
|
66
|
+
Called after the engine draws on the canvas. The current camera transform is applied.
|
67
|
+
|
68
|
+
engine.bind "draw", (canvas) ->
|
69
|
+
# print some directions for the player
|
70
|
+
canvas.drawText
|
71
|
+
text: "Go this way =>"
|
72
|
+
x: 200
|
73
|
+
y: 200
|
74
|
+
|
75
|
+
@name draw
|
76
|
+
@methodOf Engine#
|
77
|
+
@event
|
78
|
+
@params {PixieCanvas} canvas A reference to the canvas to draw on.
|
79
|
+
###
|
80
|
+
|
81
|
+
###*
|
82
|
+
Called after the engine draws.
|
83
|
+
|
84
|
+
The current camera transform is not applied. This is great for
|
85
|
+
adding overlays.
|
86
|
+
|
87
|
+
engine.bind "overlay", (canvas) ->
|
88
|
+
# print the player's health. This will be
|
89
|
+
# positioned absolutely according to the viewport.
|
90
|
+
canvas.drawText
|
91
|
+
text: "HEALTH:"
|
92
|
+
position: Point(20, 20)
|
93
|
+
|
94
|
+
canvas.drawText
|
95
|
+
text: player.health()
|
96
|
+
position: Point(50, 20)
|
97
|
+
|
98
|
+
@name overlay
|
99
|
+
@methodOf Engine#
|
100
|
+
@event
|
101
|
+
@params {PixieCanvas} canvas A reference to the canvas to draw on.
|
102
|
+
###
|
103
|
+
|
104
|
+
Engine = (I={}) ->
|
105
|
+
Object.reverseMerge I,
|
106
|
+
FPS: 60
|
107
|
+
paused: false
|
108
|
+
|
109
|
+
frameAdvance = false
|
110
|
+
|
111
|
+
running = false
|
112
|
+
startTime = +new Date()
|
113
|
+
lastStepTime = -Infinity
|
114
|
+
animLoop = (timestamp) ->
|
115
|
+
timestamp ||= +new Date()
|
116
|
+
msPerFrame = (1000 / I.FPS)
|
117
|
+
|
118
|
+
delta = timestamp - lastStepTime
|
119
|
+
remainder = delta - msPerFrame
|
120
|
+
|
121
|
+
if remainder > 0
|
122
|
+
lastStepTime = timestamp - Math.min(remainder, msPerFrame)
|
123
|
+
step()
|
124
|
+
|
125
|
+
if running
|
126
|
+
window.requestAnimationFrame(animLoop)
|
127
|
+
|
128
|
+
update = (elapsedTime) ->
|
129
|
+
self.trigger "beforeUpdate", elapsedTime
|
130
|
+
self.trigger "update", elapsedTime
|
131
|
+
self.trigger "afterUpdate", elapsedTime
|
132
|
+
|
133
|
+
draw = ->
|
134
|
+
return unless canvas = I.canvas
|
135
|
+
|
136
|
+
self.trigger "beforeDraw", canvas
|
137
|
+
self.trigger "draw", canvas
|
138
|
+
self.trigger "overlay", canvas
|
139
|
+
|
140
|
+
step = ->
|
141
|
+
if !I.paused || frameAdvance
|
142
|
+
elapsedTime = (1 / I.FPS)
|
143
|
+
update(elapsedTime)
|
144
|
+
|
145
|
+
draw()
|
146
|
+
|
147
|
+
self = Core(I).extend {
|
148
|
+
###*
|
149
|
+
Start the game simulation.
|
150
|
+
|
151
|
+
engine.start()
|
152
|
+
|
153
|
+
@methodOf Engine#
|
154
|
+
@name start
|
155
|
+
###
|
156
|
+
start: ->
|
157
|
+
unless running
|
158
|
+
running = true
|
159
|
+
window.requestAnimationFrame(animLoop)
|
160
|
+
|
161
|
+
###*
|
162
|
+
Stop the simulation.
|
163
|
+
|
164
|
+
engine.stop()
|
165
|
+
|
166
|
+
@methodOf Engine#
|
167
|
+
@name stop
|
168
|
+
###
|
169
|
+
stop: ->
|
170
|
+
running = false
|
171
|
+
|
172
|
+
###*
|
173
|
+
Pause the game and step through 1 update of the engine.
|
174
|
+
|
175
|
+
engine.frameAdvance()
|
176
|
+
|
177
|
+
@methodOf Engine#
|
178
|
+
@name frameAdvance
|
179
|
+
###
|
180
|
+
frameAdvance: ->
|
181
|
+
I.paused = true
|
182
|
+
frameAdvance = true
|
183
|
+
step()
|
184
|
+
frameAdvance = false
|
185
|
+
|
186
|
+
###*
|
187
|
+
Resume the game.
|
188
|
+
|
189
|
+
engine.play()
|
190
|
+
|
191
|
+
@methodOf Engine#
|
192
|
+
@name play
|
193
|
+
###
|
194
|
+
play: ->
|
195
|
+
I.paused = false
|
196
|
+
|
197
|
+
###*
|
198
|
+
Toggle the paused state of the simulation.
|
199
|
+
|
200
|
+
engine.pause()
|
201
|
+
|
202
|
+
@methodOf Engine#
|
203
|
+
@name pause
|
204
|
+
@param {Boolean} [setTo] Force to pause by passing true or unpause by passing false.
|
205
|
+
###
|
206
|
+
pause: (setTo) ->
|
207
|
+
if setTo?
|
208
|
+
I.paused = setTo
|
209
|
+
else
|
210
|
+
I.paused = !I.paused
|
211
|
+
|
212
|
+
###*
|
213
|
+
Query the engine to see if it is paused.
|
214
|
+
|
215
|
+
engine.pause()
|
216
|
+
|
217
|
+
engine.paused()
|
218
|
+
# true
|
219
|
+
|
220
|
+
engine.play()
|
221
|
+
|
222
|
+
engine.paused()
|
223
|
+
# false
|
224
|
+
|
225
|
+
@methodOf Engine#
|
226
|
+
@name paused
|
227
|
+
###
|
228
|
+
paused: ->
|
229
|
+
I.paused
|
230
|
+
|
231
|
+
###*
|
232
|
+
Change the framerate of the game. The default framerate is 30 fps.
|
233
|
+
|
234
|
+
engine.setFramerate(60)
|
235
|
+
|
236
|
+
@methodOf Engine#
|
237
|
+
@name setFramerate
|
238
|
+
###
|
239
|
+
setFramerate: (newFPS) ->
|
240
|
+
I.FPS = newFPS
|
241
|
+
self.stop()
|
242
|
+
self.start()
|
243
|
+
|
244
|
+
update: update
|
245
|
+
draw: draw
|
246
|
+
}
|
247
|
+
|
248
|
+
self.include Ageable
|
249
|
+
|
250
|
+
Engine.defaultModules.each (moduleName) ->
|
251
|
+
fullModuleName = "Engine.#{moduleName}"
|
252
|
+
throw "##{fullModuleName} is not a valid engine module" unless Engine[moduleName]
|
253
|
+
|
254
|
+
self.include fullModuleName
|
255
|
+
|
256
|
+
self.trigger "init"
|
257
|
+
|
258
|
+
return self
|
259
|
+
|
260
|
+
Engine.defaultModules = [
|
261
|
+
"Data"
|
262
|
+
"Keyboard"
|
263
|
+
"Mouse"
|
264
|
+
"Background"
|
265
|
+
"Delay"
|
266
|
+
"GameState"
|
267
|
+
"Selector"
|
268
|
+
"Collision"
|
269
|
+
"Tilemap"
|
270
|
+
"Levels"
|
271
|
+
]
|
272
|
+
|
273
|
+
(exports ? this)["Engine"] = Engine
|
274
|
+
)()
|
@@ -0,0 +1,77 @@
|
|
1
|
+
###*
|
2
|
+
The <code>Collision</code> module provides some simple collision detection methods to engine.
|
3
|
+
|
4
|
+
@name Collision
|
5
|
+
@fieldOf Engine
|
6
|
+
@module
|
7
|
+
@param {Object} I Instance variables
|
8
|
+
@param {Object} self Reference to the engine
|
9
|
+
###
|
10
|
+
Engine.Collision = (I, self) ->
|
11
|
+
###*
|
12
|
+
Detects collisions between a bounds and the game objects.
|
13
|
+
|
14
|
+
@name collides
|
15
|
+
@methodOf Engine#
|
16
|
+
@param bounds The bounds to check collisions with.
|
17
|
+
@param [sourceObject] An object to exclude from the results.
|
18
|
+
@returns {Boolean} true if the bounds object collides with any of the game objects, false otherwise.
|
19
|
+
###
|
20
|
+
collides: (bounds, sourceObject, selector=".solid") ->
|
21
|
+
self.find(selector).inject false, (collided, object) ->
|
22
|
+
collided or (object != sourceObject) and object.collides(bounds)
|
23
|
+
|
24
|
+
###*
|
25
|
+
Detects collisions between a bounds and the game objects.
|
26
|
+
Returns an array of objects colliding with the bounds provided.
|
27
|
+
|
28
|
+
@name collidesWith
|
29
|
+
@methodOf Engine#
|
30
|
+
@param bounds The bounds to check collisions with.
|
31
|
+
@param [sourceObject] An object to exclude from the results.
|
32
|
+
@returns {Array} An array of objects that collide with the given bounds.
|
33
|
+
###
|
34
|
+
collidesWith: (bounds, sourceObject, selector=".solid") ->
|
35
|
+
self.find(selector).select (object) ->
|
36
|
+
object != sourceObject and object.collides(bounds)
|
37
|
+
|
38
|
+
###*
|
39
|
+
Detects collisions between a ray and the game objects.
|
40
|
+
|
41
|
+
@name rayCollides
|
42
|
+
@methodOf Engine#
|
43
|
+
@param source The origin point
|
44
|
+
@param direction A point representing the direction of the ray
|
45
|
+
@param [sourceObject] An object to exclude from the results.
|
46
|
+
@param [selector] A selector to choos which objects in the engine to collide with
|
47
|
+
###
|
48
|
+
rayCollides: ({source, direction, sourceObject, selector}) ->
|
49
|
+
selector ?= ""
|
50
|
+
|
51
|
+
hits = self.find(selector).map (object) ->
|
52
|
+
hit = (object != sourceObject) and Collision.rayRectangle(source, direction, object.centeredBounds())
|
53
|
+
hit.object = object if hit
|
54
|
+
|
55
|
+
hit
|
56
|
+
|
57
|
+
nearestDistance = Infinity
|
58
|
+
nearestHit = null
|
59
|
+
|
60
|
+
hits.each (hit) ->
|
61
|
+
if hit && (d = hit.distance(source)) < nearestDistance
|
62
|
+
nearestDistance = d
|
63
|
+
nearestHit = hit
|
64
|
+
|
65
|
+
nearestHit
|
66
|
+
|
67
|
+
# TODO Allow specification of collision type (i.e. circular)
|
68
|
+
objectsUnderPoint: (point, selector="") ->
|
69
|
+
bounds = {
|
70
|
+
x: point.x
|
71
|
+
y: point.y
|
72
|
+
width: 0
|
73
|
+
height: 0
|
74
|
+
}
|
75
|
+
|
76
|
+
self.find(selector).select (object) ->
|
77
|
+
object.collides(bounds)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
###*
|
2
|
+
The <code>Data</code> module provides methods to store global and persistent data in the engine.
|
3
|
+
|
4
|
+
engine.data.score = 0
|
5
|
+
engine.data.score += 10
|
6
|
+
|
7
|
+
engine.data.score # => 10
|
8
|
+
|
9
|
+
@name Data
|
10
|
+
@fieldOf Engine
|
11
|
+
@module
|
12
|
+
@param {Object} I Instance variables
|
13
|
+
@param {Object} self Reference to the engine
|
14
|
+
###
|
15
|
+
Engine.Data = (I={}, self) ->
|
16
|
+
Object.reverseMerge I,
|
17
|
+
data: {}
|
18
|
+
|
19
|
+
Object.defineProperty self, 'data',
|
20
|
+
get: ->
|
21
|
+
I.data
|
22
|
+
|
23
|
+
{}
|
@@ -0,0 +1,41 @@
|
|
1
|
+
###*
|
2
|
+
The <code>Delay</code> module provides methods to trigger events after a number of steps have passed.
|
3
|
+
|
4
|
+
@name Delay
|
5
|
+
@fieldOf Engine
|
6
|
+
@module
|
7
|
+
@param {Object} I Instance variables
|
8
|
+
@param {Object} self Reference to the engine
|
9
|
+
###
|
10
|
+
Engine.Delay = (I, self) ->
|
11
|
+
delayedEvents = []
|
12
|
+
|
13
|
+
self.bind 'afterUpdate', (elapsedTime) ->
|
14
|
+
[delayedEvents, firingEvents] = delayedEvents.partition (event) ->
|
15
|
+
(event.delay -= elapsedTime) >= 0
|
16
|
+
|
17
|
+
firingEvents.each (event) ->
|
18
|
+
event.callback()
|
19
|
+
|
20
|
+
return
|
21
|
+
|
22
|
+
###*
|
23
|
+
Execute a callback after a number of seconds have passed.
|
24
|
+
|
25
|
+
engine.delay 5, ->
|
26
|
+
engine.add
|
27
|
+
class: "Ghost"
|
28
|
+
|
29
|
+
@name delay
|
30
|
+
@methodOf Engine#
|
31
|
+
@param {Number} seconds The number of steps to wait before executing the callback
|
32
|
+
@param {Function} callback The callback to be executed.
|
33
|
+
|
34
|
+
@returns {Engine} self
|
35
|
+
###
|
36
|
+
delay: (seconds, callback) ->
|
37
|
+
delayedEvents.push
|
38
|
+
delay: seconds
|
39
|
+
callback: callback
|
40
|
+
|
41
|
+
return self
|
@@ -0,0 +1,32 @@
|
|
1
|
+
###*
|
2
|
+
The <code>FPSCounter</code> module tracks and displays the framerate.
|
3
|
+
|
4
|
+
window.engine = Engine
|
5
|
+
...
|
6
|
+
includedModules: ["FPSCounter"]
|
7
|
+
FPSColor: "#080"
|
8
|
+
|
9
|
+
@name FPSCounter
|
10
|
+
@fieldOf Engine
|
11
|
+
@module
|
12
|
+
|
13
|
+
@param {Object} I Instance variables
|
14
|
+
@param {Object} self Reference to the engine
|
15
|
+
###
|
16
|
+
Engine.FPSCounter = (I, self) ->
|
17
|
+
Object.reverseMerge I,
|
18
|
+
showFPS: true
|
19
|
+
FPSColor: "#FFF"
|
20
|
+
|
21
|
+
framerate = Framerate()
|
22
|
+
|
23
|
+
self.bind "overlay", (canvas) ->
|
24
|
+
if I.showFPS
|
25
|
+
canvas.font("bold 9pt consolas, 'Courier New', 'andale mono', 'lucida console', monospace")
|
26
|
+
|
27
|
+
canvas.drawText
|
28
|
+
color: I.FPSColor
|
29
|
+
position: Point(6, 18)
|
30
|
+
text: "fps: #{framerate.fps}"
|
31
|
+
|
32
|
+
framerate.rendered()
|
@@ -0,0 +1,86 @@
|
|
1
|
+
Engine.GameState = (I, self) ->
|
2
|
+
Object.reverseMerge I,
|
3
|
+
currentState: GameState()
|
4
|
+
|
5
|
+
requestedState = null
|
6
|
+
|
7
|
+
# The idea is that all the engine#beforeUpdate triggers happen
|
8
|
+
# before the state beforeUpdate triggers, then the state update
|
9
|
+
# then the state after update, then the engine after update
|
10
|
+
# like a layered cake with states in the middle.
|
11
|
+
self.bind "update", (elapsedTime) ->
|
12
|
+
I.currentState.trigger "beforeUpdate", elapsedTime
|
13
|
+
I.currentState.trigger "update", elapsedTime
|
14
|
+
I.currentState.trigger "afterUpdate", elapsedTime
|
15
|
+
|
16
|
+
self.bind "afterUpdate", ->
|
17
|
+
# Handle state change
|
18
|
+
if requestedState?
|
19
|
+
I.currentState.trigger "exit", requestedState
|
20
|
+
self.trigger 'stateExited', I.currentState
|
21
|
+
|
22
|
+
previousState = I.currentState
|
23
|
+
I.currentState = requestedState
|
24
|
+
|
25
|
+
I.currentState.trigger "enter", previousState
|
26
|
+
self.trigger 'stateEntered', I.currentState
|
27
|
+
|
28
|
+
requestedState = null
|
29
|
+
|
30
|
+
self.bind "draw", (canvas) ->
|
31
|
+
I.currentState.trigger "beforeDraw", canvas
|
32
|
+
I.currentState.trigger "draw", canvas
|
33
|
+
I.currentState.trigger "overlay", canvas
|
34
|
+
|
35
|
+
|
36
|
+
# Just pass through to the current state
|
37
|
+
add: (classNameOrEntityData, entityData={}) ->
|
38
|
+
# Allow optional add "Class", data form
|
39
|
+
if classNameOrEntityData.isString?()
|
40
|
+
entityData.class = classNameOrEntityData
|
41
|
+
else
|
42
|
+
entityData = classNameOrEntityData
|
43
|
+
|
44
|
+
self.trigger "beforeAdd", entityData
|
45
|
+
object = I.currentState.add(entityData)
|
46
|
+
self.trigger "afterAdd", object
|
47
|
+
|
48
|
+
return object
|
49
|
+
|
50
|
+
camera: (n=0) ->
|
51
|
+
self.cameras()[n]
|
52
|
+
|
53
|
+
cameras: (newCameras) ->
|
54
|
+
if newCameras?
|
55
|
+
I.currentState.cameras(newCameras)
|
56
|
+
|
57
|
+
return self
|
58
|
+
else
|
59
|
+
I.currentState.cameras()
|
60
|
+
|
61
|
+
fadeIn: (options={}) ->
|
62
|
+
self.cameras().invoke('fadeIn', options)
|
63
|
+
|
64
|
+
fadeOut: (options={}) ->
|
65
|
+
self.cameras().invoke('fadeOut', options)
|
66
|
+
|
67
|
+
flash: (options={}) ->
|
68
|
+
self.camera(options.camera).flash(options)
|
69
|
+
|
70
|
+
objects: ->
|
71
|
+
I.currentState.objects()
|
72
|
+
|
73
|
+
setState: (newState) ->
|
74
|
+
requestedState = newState
|
75
|
+
|
76
|
+
shake: (options={}) ->
|
77
|
+
self.camera(options.camera).shake(options)
|
78
|
+
|
79
|
+
saveState: ->
|
80
|
+
I.currentState.saveState()
|
81
|
+
|
82
|
+
loadState: (newState) ->
|
83
|
+
I.currentState.loadState(newState)
|
84
|
+
|
85
|
+
reload: ->
|
86
|
+
I.currentState.reload()
|
@@ -0,0 +1,47 @@
|
|
1
|
+
###*
|
2
|
+
The <code>Joysticks</code> module gives the engine access to joysticks.
|
3
|
+
|
4
|
+
# First you need to add the joysticks module to the engine
|
5
|
+
window.engine = Engine
|
6
|
+
...
|
7
|
+
includedModules: ["Joysticks"]
|
8
|
+
# Then you need to get a controller reference
|
9
|
+
# id = 0 for player 1, etc.
|
10
|
+
controller = engine.controller(id)
|
11
|
+
|
12
|
+
# Point indicating direction primary axis is held
|
13
|
+
direction = controller.position()
|
14
|
+
|
15
|
+
# Check if buttons are held
|
16
|
+
controller.actionDown("A")
|
17
|
+
controller.actionDown("B")
|
18
|
+
controller.actionDown("X")
|
19
|
+
controller.actionDown("Y")
|
20
|
+
|
21
|
+
@name Joysticks
|
22
|
+
@fieldOf Engine
|
23
|
+
@module
|
24
|
+
|
25
|
+
@param {Object} I Instance variables
|
26
|
+
@param {Object} self Reference to the engine
|
27
|
+
###
|
28
|
+
Engine.Joysticks = (I, self) ->
|
29
|
+
Joysticks.init()
|
30
|
+
|
31
|
+
self.bind "update", ->
|
32
|
+
# Handle hotswapping, does nothing if already initialized
|
33
|
+
Joysticks.init()
|
34
|
+
|
35
|
+
# Update the joysticks, this also fires joystick events to listeners
|
36
|
+
Joysticks.update()
|
37
|
+
|
38
|
+
###*
|
39
|
+
Get a controller for a given joystick id.
|
40
|
+
|
41
|
+
@name controller
|
42
|
+
@methodOf Engine.Joysticks#
|
43
|
+
|
44
|
+
@param {Number} i The joystick id to get the controller of.
|
45
|
+
###
|
46
|
+
controller: (i) ->
|
47
|
+
Joysticks.getController(i)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
###*
|
2
|
+
This module sets up the keyboard inputs for each engine update.
|
3
|
+
|
4
|
+
@name Keyboard
|
5
|
+
@fieldOf Engine
|
6
|
+
@module
|
7
|
+
@param {Object} I Instance variables
|
8
|
+
@param {Object} self Reference to the engine
|
9
|
+
###
|
10
|
+
Engine.Keyboard = (I, self) ->
|
11
|
+
self.bind "beforeUpdate", ->
|
12
|
+
# TODO: Make a Gamepad/Keyboard input module that has web and XNA
|
13
|
+
# implementations
|
14
|
+
updateKeys?()
|
15
|
+
|
16
|
+
return {}
|
17
|
+
|
@@ -0,0 +1,69 @@
|
|
1
|
+
###*
|
2
|
+
This module provides methods for transitioning between levels.
|
3
|
+
|
4
|
+
@name Levels
|
5
|
+
@fieldOf Engine
|
6
|
+
@module
|
7
|
+
@param {Object} I Instance variables
|
8
|
+
@param {Object} self Reference to the engine
|
9
|
+
###
|
10
|
+
Engine.Levels = (I, self) ->
|
11
|
+
Object.reverseMerge I,
|
12
|
+
levels: []
|
13
|
+
currentLevel: -1
|
14
|
+
currentLevelName: null
|
15
|
+
|
16
|
+
I.transitioning = false
|
17
|
+
|
18
|
+
loadLevel = (level) ->
|
19
|
+
unless I.transitioning
|
20
|
+
I.transitioning = true
|
21
|
+
|
22
|
+
levelState = LevelState
|
23
|
+
level: level
|
24
|
+
|
25
|
+
I.currentLevelName = level
|
26
|
+
engine.setState levelState
|
27
|
+
|
28
|
+
###*
|
29
|
+
Load map for the next level.
|
30
|
+
|
31
|
+
engine.nextLevel()
|
32
|
+
|
33
|
+
@name nextLevel
|
34
|
+
@methodOf Engine#
|
35
|
+
###
|
36
|
+
nextLevel: ->
|
37
|
+
unless I.transitioning
|
38
|
+
I.currentLevel += 1
|
39
|
+
|
40
|
+
if level = I.levels[I.currentLevel]
|
41
|
+
loadLevel level
|
42
|
+
else
|
43
|
+
engine.setState GameOver()
|
44
|
+
|
45
|
+
###*
|
46
|
+
Load map named <code>level</code>
|
47
|
+
|
48
|
+
engine.goToLevel 'bossFight'
|
49
|
+
|
50
|
+
@name goToLevel
|
51
|
+
@methodOf Engine#
|
52
|
+
###
|
53
|
+
goToLevel: (level) ->
|
54
|
+
#TODO Handle integer levels?
|
55
|
+
loadLevel level
|
56
|
+
|
57
|
+
###*
|
58
|
+
Reload the current level. Useful for retrying after a player dies.
|
59
|
+
|
60
|
+
engine.reloadLevel()
|
61
|
+
|
62
|
+
@name reloadLevel
|
63
|
+
@methodOf Engine#
|
64
|
+
###
|
65
|
+
restartLevel: ->
|
66
|
+
loadLevel I.currentLevelName
|
67
|
+
|
68
|
+
reloadLevel: ->
|
69
|
+
self.restartLevel()
|
@@ -0,0 +1,16 @@
|
|
1
|
+
###*
|
2
|
+
This module sets up the mouse inputs for each engine update.
|
3
|
+
|
4
|
+
@name Mouse
|
5
|
+
@fieldOf Engine
|
6
|
+
@module
|
7
|
+
@param {Object} I Instance variables
|
8
|
+
@param {Object} self Reference to the engine
|
9
|
+
###
|
10
|
+
Engine.Mouse = (I, self) ->
|
11
|
+
self.bind "beforeUpdate", ->
|
12
|
+
# TODO: Make a Gamepad/Keyboard/Mouse input module that has web and XNA
|
13
|
+
# implementations
|
14
|
+
updateMouse?()
|
15
|
+
|
16
|
+
return {}
|