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,166 @@
|
|
1
|
+
###*
|
2
|
+
The <code>Selector</code> module provides methods to query the engine to find game objects.
|
3
|
+
|
4
|
+
@name Selector
|
5
|
+
@fieldOf Engine
|
6
|
+
@module
|
7
|
+
@param {Object} I Instance variables
|
8
|
+
@param {Object} self Reference to the engine
|
9
|
+
###
|
10
|
+
Engine.Selector = (I, self) ->
|
11
|
+
|
12
|
+
instanceMethods =
|
13
|
+
set: (attr, value) ->
|
14
|
+
this.each (item) ->
|
15
|
+
item.I[attr] = value
|
16
|
+
|
17
|
+
###*
|
18
|
+
Get the game object matching the given selector that is closest to the given position.
|
19
|
+
|
20
|
+
player = engine.add
|
21
|
+
x: 0
|
22
|
+
y: 0
|
23
|
+
|
24
|
+
enemy1 = engine.add
|
25
|
+
enemy: true
|
26
|
+
x: 10
|
27
|
+
y: 0
|
28
|
+
|
29
|
+
enemy2 = engine.add
|
30
|
+
enemy: true
|
31
|
+
x: 0
|
32
|
+
y: 15
|
33
|
+
|
34
|
+
player2 = engine.add
|
35
|
+
x: 0
|
36
|
+
y: 10
|
37
|
+
|
38
|
+
equals engine.closest(".enemy", player.position()), enemy1
|
39
|
+
equals engine.closest(".enemy", player2.position()), enemy2
|
40
|
+
|
41
|
+
@name closest
|
42
|
+
@methodOf Engine.selector
|
43
|
+
@param {String} selector
|
44
|
+
@param {Point} position
|
45
|
+
###
|
46
|
+
closest: (selector, position) ->
|
47
|
+
self.find(selector).sort (a, b) ->
|
48
|
+
Point.distanceSquared(position, a.position()) - Point.distanceSquared(position, b.position())
|
49
|
+
.first()
|
50
|
+
|
51
|
+
###*
|
52
|
+
Get a selection of GameObjects that match the specified selector criteria. The selector language
|
53
|
+
can select objects by id, class, or attributes. Note that this method always returns an Array,
|
54
|
+
so if you are trying to find only one object you will need something like <code>engine.find("Enemy").first()</code>.
|
55
|
+
|
56
|
+
player = engine.add
|
57
|
+
class: "Player"
|
58
|
+
|
59
|
+
enemy = engine.add
|
60
|
+
class: "Enemy"
|
61
|
+
speed: 5
|
62
|
+
x: 0
|
63
|
+
|
64
|
+
distantEnemy = engine.add
|
65
|
+
class "Enemy"
|
66
|
+
x: 500
|
67
|
+
|
68
|
+
boss = engine.add
|
69
|
+
class: "Enemy"
|
70
|
+
id: "Boss"
|
71
|
+
x: 0
|
72
|
+
|
73
|
+
# to select an object by id use "#anId"
|
74
|
+
engine.find "#Boss"
|
75
|
+
# => [boss]
|
76
|
+
|
77
|
+
# to select an object by class use "MyClass"
|
78
|
+
engine.find "Enemy"
|
79
|
+
# => [enemy, distantEnemy, boss]
|
80
|
+
|
81
|
+
# to select an object by properties use ".someProperty" or ".someProperty=someValue"
|
82
|
+
engine.find ".speed=5"
|
83
|
+
# => [enemy]
|
84
|
+
|
85
|
+
# You may mix and match selectors.
|
86
|
+
engine.find "Enemy.x=0"
|
87
|
+
# => [enemy, boss] # doesn't return distantEnemy
|
88
|
+
|
89
|
+
@name find
|
90
|
+
@methodOf Engine#
|
91
|
+
@param {String} selector
|
92
|
+
@returns {Array} An array of the objects found
|
93
|
+
###
|
94
|
+
each: (selector, fn) ->
|
95
|
+
self.find(selector).each (obj, index) ->
|
96
|
+
fn(obj, index)
|
97
|
+
|
98
|
+
###*
|
99
|
+
Find all game objects that match the given selector.
|
100
|
+
|
101
|
+
@name find
|
102
|
+
@methodOf Engine.selector
|
103
|
+
|
104
|
+
@param {String} selector
|
105
|
+
###
|
106
|
+
find: (selector) ->
|
107
|
+
results = []
|
108
|
+
|
109
|
+
matcher = Engine.Selector.generate(selector)
|
110
|
+
|
111
|
+
self.objects().each (object) ->
|
112
|
+
results.push object if matcher.match object
|
113
|
+
|
114
|
+
Object.extend results, instanceMethods
|
115
|
+
|
116
|
+
###*
|
117
|
+
Find the first game object that matches the given selector.
|
118
|
+
|
119
|
+
@name find
|
120
|
+
@methodOf Engine.selector
|
121
|
+
|
122
|
+
@param {String} selector
|
123
|
+
###
|
124
|
+
first: (selector) ->
|
125
|
+
self.find(selector).first()
|
126
|
+
|
127
|
+
Object.extend Engine.Selector,
|
128
|
+
parse: (selector) ->
|
129
|
+
selector.split(",").invoke("trim")
|
130
|
+
|
131
|
+
process: (item) ->
|
132
|
+
result = /^(\w+)?#?([\w\-]+)?\.?([\w\-]+)?=?([\w\-]+)?/.exec(item)
|
133
|
+
|
134
|
+
if result
|
135
|
+
result[4] = result[4].parse() if result[4]
|
136
|
+
|
137
|
+
result.splice(1)
|
138
|
+
else
|
139
|
+
[]
|
140
|
+
|
141
|
+
generate: (selector) ->
|
142
|
+
components = Engine.Selector.parse(selector).map (piece) ->
|
143
|
+
Engine.Selector.process(piece)
|
144
|
+
|
145
|
+
TYPE = 0
|
146
|
+
ID = 1
|
147
|
+
ATTR = 2
|
148
|
+
ATTR_VALUE = 3
|
149
|
+
|
150
|
+
match: (object) ->
|
151
|
+
for component in components
|
152
|
+
idMatch = (component[ID] == object.I.id) || !component[ID]
|
153
|
+
typeMatch = (component[TYPE] == object.I.class) || !component[TYPE]
|
154
|
+
|
155
|
+
if attr = component[ATTR]
|
156
|
+
if (value = component[ATTR_VALUE])?
|
157
|
+
attrMatch = (object.I[attr] == value)
|
158
|
+
else
|
159
|
+
attrMatch = object.I[attr]
|
160
|
+
else
|
161
|
+
attrMatch = true
|
162
|
+
|
163
|
+
return true if idMatch && typeMatch && attrMatch
|
164
|
+
|
165
|
+
return false
|
166
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
###*
|
2
|
+
The <code>Stats</code> module provides methods to query the engine to find game objects.
|
3
|
+
|
4
|
+
@name Stats
|
5
|
+
@fieldOf Engine
|
6
|
+
@module
|
7
|
+
@param {Object} I Instance variables
|
8
|
+
@param {Object} self Reference to the engine
|
9
|
+
###
|
10
|
+
Engine.Stats = (I, self) ->
|
11
|
+
measure: (objects, field, frequency=30) ->
|
12
|
+
; #TODO
|
13
|
+
|
14
|
+
gatherData: ->
|
15
|
+
self.find()
|
16
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
###*
|
2
|
+
The <code>Tilemap</code> module provides a way to load tilemaps in the engine.
|
3
|
+
|
4
|
+
@name Tilemap
|
5
|
+
@fieldOf Engine
|
6
|
+
@module
|
7
|
+
|
8
|
+
@param {Object} I Instance variables
|
9
|
+
@param {Object} self Reference to the engine
|
10
|
+
###
|
11
|
+
Engine.Tilemap = (I, self) ->
|
12
|
+
Object.extend I,
|
13
|
+
map: null
|
14
|
+
|
15
|
+
updating = false
|
16
|
+
clearObjects = false
|
17
|
+
|
18
|
+
self.bind "update", ->
|
19
|
+
updating = true
|
20
|
+
|
21
|
+
self.bind "afterUpdate", ->
|
22
|
+
updating = false
|
23
|
+
|
24
|
+
if clearObjects
|
25
|
+
#TODO: Clear these out in a more graceful way, triggering unload events
|
26
|
+
self.objects().clear()
|
27
|
+
clearObjects = false
|
28
|
+
|
29
|
+
###*
|
30
|
+
Loads a new may and unloads any existing map or entities.
|
31
|
+
|
32
|
+
@name loadMap
|
33
|
+
@methodOf Engine#
|
34
|
+
###
|
35
|
+
loadMap: (name, complete) ->
|
36
|
+
clearObjects = updating
|
37
|
+
|
38
|
+
I.map = Tilemap.load
|
39
|
+
name: name
|
40
|
+
complete: complete
|
41
|
+
entity: self.add
|
@@ -0,0 +1,32 @@
|
|
1
|
+
###*
|
2
|
+
This module clears or fills the canvas before drawing the scene.
|
3
|
+
|
4
|
+
@name Clear
|
5
|
+
@fieldOf Engine
|
6
|
+
@module
|
7
|
+
@param {Object} I Instance variables
|
8
|
+
@param {Object} self Reference to the engine
|
9
|
+
###
|
10
|
+
|
11
|
+
Engine.Background = (I, self) ->
|
12
|
+
Object.reverseMerge I,
|
13
|
+
background: null
|
14
|
+
backgroundColor: "#00010D"
|
15
|
+
clear: false
|
16
|
+
|
17
|
+
self.attrAccessor "clear", "backgroundColor"
|
18
|
+
|
19
|
+
self.bind "init", ->
|
20
|
+
if I.background?.isString?()
|
21
|
+
I.background = Sprite.loadByName I.background
|
22
|
+
|
23
|
+
self.bind "beforeDraw", ->
|
24
|
+
if I.clear
|
25
|
+
I.canvas.clear()
|
26
|
+
else if I.background
|
27
|
+
I.background.fill(I.canvas, 0, 0, App.width, App.height)
|
28
|
+
else if I.backgroundColor
|
29
|
+
I.canvas.fill(I.backgroundColor)
|
30
|
+
|
31
|
+
# No public methods
|
32
|
+
return {}
|
@@ -0,0 +1,47 @@
|
|
1
|
+
###*
|
2
|
+
The Expirable module deactivates a <code>GameObject</code> after a specified duration.
|
3
|
+
If a duration is specified the object will update that many times. If -1 is
|
4
|
+
specified the object will have an unlimited duration.
|
5
|
+
|
6
|
+
This module is included by default in <code>GameObjects</code>
|
7
|
+
|
8
|
+
enemy = GameObject
|
9
|
+
x: 50
|
10
|
+
y: 30
|
11
|
+
duration: 5
|
12
|
+
|
13
|
+
enemy.include Expirable
|
14
|
+
|
15
|
+
enemy.I.active
|
16
|
+
# => true
|
17
|
+
|
18
|
+
5.times ->
|
19
|
+
enemy.update(1)
|
20
|
+
|
21
|
+
enemy.I.active
|
22
|
+
# => false
|
23
|
+
|
24
|
+
@name Expirable
|
25
|
+
@module
|
26
|
+
@constructor
|
27
|
+
@param {Object} I Instance variables
|
28
|
+
@param {Core} self Reference to including object
|
29
|
+
###
|
30
|
+
Expirable = (I={}, self) ->
|
31
|
+
Object.reverseMerge I,
|
32
|
+
duration: -1
|
33
|
+
alpha: 1
|
34
|
+
fadeOut: false
|
35
|
+
|
36
|
+
startingAlpha = I.alpha
|
37
|
+
|
38
|
+
self.bind "update", (dt) ->
|
39
|
+
if I.fadeOut
|
40
|
+
I.alpha = startingAlpha * (1 - (I.age / I.duration))
|
41
|
+
|
42
|
+
if I.duration != -1 && I.age >= I.duration
|
43
|
+
I.active = false
|
44
|
+
|
45
|
+
I.alpha = I.alpha.clamp(0, 1)
|
46
|
+
|
47
|
+
return {}
|
@@ -0,0 +1,78 @@
|
|
1
|
+
###*
|
2
|
+
The `Flickerable` module provides a method to flicker a sprite between its current opacity (alpha) and a given opacity.
|
3
|
+
|
4
|
+
player = GameObject
|
5
|
+
alpha: 0.9
|
6
|
+
|
7
|
+
player.include 'Flickerable'
|
8
|
+
|
9
|
+
# called with no arguments, flicker will toggle the player's alpha
|
10
|
+
# value between 0.9 (value provided above) and 0.5 (flickerable default)
|
11
|
+
# every 0.1 second, for a total of 2 seconds
|
12
|
+
player.flicker()
|
13
|
+
|
14
|
+
@name Flickerable
|
15
|
+
@module
|
16
|
+
@constructor
|
17
|
+
@param {Object} I Instance variables
|
18
|
+
@param {Core} self Reference to including object
|
19
|
+
###
|
20
|
+
Flickerable = (I={}, self) ->
|
21
|
+
Object.reverseMerge I,
|
22
|
+
flickerAlpha: 0.5
|
23
|
+
flickerDuration: 0
|
24
|
+
flickerFrequency: 0.1
|
25
|
+
|
26
|
+
originalAlpha = I.alpha
|
27
|
+
frequencyLength = 0
|
28
|
+
|
29
|
+
self.bind 'update', (elapsedTime) ->
|
30
|
+
I.flickerDuration = I.flickerDuration.approach(0, elapsedTime)
|
31
|
+
|
32
|
+
frequencyLength += elapsedTime
|
33
|
+
|
34
|
+
if I.flickerDuration > 0
|
35
|
+
if frequencyLength >= I.flickerFrequency
|
36
|
+
frequencyLength = 0
|
37
|
+
|
38
|
+
if I.alpha is I.flickerAlpha
|
39
|
+
I.alpha = originalAlpha
|
40
|
+
else
|
41
|
+
I.alpha = I.flickerAlpha
|
42
|
+
else
|
43
|
+
I.alpha = originalAlpha
|
44
|
+
|
45
|
+
###*
|
46
|
+
A convenient way to set the flicker instance variables on a sprite. You can modify the
|
47
|
+
instance variables by hand but the suggested way to do it is through this method.
|
48
|
+
|
49
|
+
player = GameObject()
|
50
|
+
|
51
|
+
player.include(Flickerable)
|
52
|
+
|
53
|
+
player.flicker
|
54
|
+
duration: 5
|
55
|
+
frequency: 0.2
|
56
|
+
alpha: 0.3
|
57
|
+
|
58
|
+
# => This causes the sprite to flicker between full opacity
|
59
|
+
# => and 30% opacity every 0.2 seconds for 5 seconds
|
60
|
+
|
61
|
+
@name flicker
|
62
|
+
@methodOf Flickerable#
|
63
|
+
@param {Number} [duration=2] How long the effect lasts in seconds
|
64
|
+
@param {Number} [frequency=0.1] Number of seconds in between opacity changes
|
65
|
+
@param {Number} [alpha=0.5] Alpha value to toggle between
|
66
|
+
@returns {GameObject} The calling object
|
67
|
+
###
|
68
|
+
flicker: (options={}) ->
|
69
|
+
Object.reverseMerge options,
|
70
|
+
duration: 2
|
71
|
+
frequency: 0.1
|
72
|
+
alpha: 0.5
|
73
|
+
|
74
|
+
I.flickerDuration = options.duration
|
75
|
+
I.flickerFrequency = options.frequency
|
76
|
+
I.flickerAlpha = options.alpha
|
77
|
+
|
78
|
+
return self
|
@@ -0,0 +1,65 @@
|
|
1
|
+
###*
|
2
|
+
The Follow module provides a simple method to set an object's
|
3
|
+
direction so that it is pointed at another object.
|
4
|
+
|
5
|
+
The calculated direction is based on the center point of
|
6
|
+
each object.
|
7
|
+
|
8
|
+
This method relies on both objects having <code>position</code> methods.
|
9
|
+
|
10
|
+
Include this module by calling <code>self.include Follow</code>
|
11
|
+
|
12
|
+
player = GameObject
|
13
|
+
x: 50
|
14
|
+
y: 50
|
15
|
+
width: 10
|
16
|
+
height: 10
|
17
|
+
|
18
|
+
enemy = GameObject
|
19
|
+
x: 100
|
20
|
+
y: 50
|
21
|
+
width: 10
|
22
|
+
height: 10
|
23
|
+
velocity: Point(0, 0)
|
24
|
+
speed: 2
|
25
|
+
|
26
|
+
enemy.include Follow
|
27
|
+
|
28
|
+
# Make an enemy follow the player
|
29
|
+
enemy.follow(player)
|
30
|
+
|
31
|
+
# now the enemy's direction will point toward the player
|
32
|
+
enemy.I.direction
|
33
|
+
# => Point(-1, 0)
|
34
|
+
|
35
|
+
# you can use this direction to set a velocity for your object.
|
36
|
+
enemy.I.velocity = enemy.I.direction.scale(I.speed)
|
37
|
+
|
38
|
+
|
39
|
+
@name Follow
|
40
|
+
@module
|
41
|
+
@constructor
|
42
|
+
@param {Object} I Instance variables
|
43
|
+
@param {Core} self Reference to including object
|
44
|
+
###
|
45
|
+
Follow = (I={}, self) ->
|
46
|
+
Object.reverseMerge I,
|
47
|
+
velocity: Point(0, 0)
|
48
|
+
speed: 1
|
49
|
+
|
50
|
+
###*
|
51
|
+
Set your velocity to follow another object.
|
52
|
+
|
53
|
+
enemy.follow(player)
|
54
|
+
|
55
|
+
# => The enemy now has it's velocity attribute set in
|
56
|
+
# the direction of the player, with magnitude equal to
|
57
|
+
# the enemy's speed
|
58
|
+
|
59
|
+
@name follow
|
60
|
+
@methodOf Follow#
|
61
|
+
@param {GameObject} obj The object you want to follow
|
62
|
+
###
|
63
|
+
follow: (obj) ->
|
64
|
+
if obj
|
65
|
+
I.velocity = obj.position().subtract(self.position()).norm(I.speed)
|
@@ -0,0 +1,42 @@
|
|
1
|
+
###*
|
2
|
+
This object keeps track of framerate and displays it by creating and appending an
|
3
|
+
html element to the DOM.
|
4
|
+
|
5
|
+
Once created you call snapshot at the end of every rendering cycle.
|
6
|
+
|
7
|
+
@name Framerate
|
8
|
+
@constructor
|
9
|
+
###
|
10
|
+
Framerate = (options={}) ->
|
11
|
+
numFramerates = 15
|
12
|
+
framerateUpdateInterval = 250
|
13
|
+
|
14
|
+
renderTime = -1
|
15
|
+
framerates = [ ]
|
16
|
+
|
17
|
+
updateFramerate = ->
|
18
|
+
self.fps = framerates.average().round()
|
19
|
+
|
20
|
+
setInterval(updateFramerate, framerateUpdateInterval)
|
21
|
+
|
22
|
+
###*
|
23
|
+
Call this method everytime you render.
|
24
|
+
|
25
|
+
@name rendered
|
26
|
+
@methodOf Framerate#
|
27
|
+
###
|
28
|
+
self =
|
29
|
+
rendered: ->
|
30
|
+
if renderTime < 0
|
31
|
+
renderTime = new Date().getTime()
|
32
|
+
else
|
33
|
+
newTime = new Date().getTime()
|
34
|
+
t = newTime - renderTime
|
35
|
+
|
36
|
+
framerate = 1000 / t
|
37
|
+
framerates.push(framerate)
|
38
|
+
|
39
|
+
while (framerates.length > numFramerates)
|
40
|
+
framerates.shift()
|
41
|
+
|
42
|
+
renderTime = newTime
|
@@ -0,0 +1,181 @@
|
|
1
|
+
###*
|
2
|
+
The default base class for all objects you can add to the engine.
|
3
|
+
|
4
|
+
GameObjects fire events that you may bind listeners to. Event listeners
|
5
|
+
may be bound with <code>object.bind(eventName, callback)</code>
|
6
|
+
|
7
|
+
@name GameObject
|
8
|
+
@extends Core
|
9
|
+
@constructor
|
10
|
+
@instanceVariables age, active, created, destroyed, solid, includedModules, excludedModules
|
11
|
+
###
|
12
|
+
|
13
|
+
###*
|
14
|
+
Triggered when the object is created.
|
15
|
+
|
16
|
+
enemyCount = 0
|
17
|
+
|
18
|
+
enemy = engine.add
|
19
|
+
class: "Enemy"
|
20
|
+
|
21
|
+
enemy.bind 'create', ->
|
22
|
+
enemyCount++
|
23
|
+
|
24
|
+
@name create
|
25
|
+
@methodOf GameObject#
|
26
|
+
@event
|
27
|
+
###
|
28
|
+
|
29
|
+
###*
|
30
|
+
Triggered when object is destroyed. Use
|
31
|
+
the destroy event to add particle effects, play sounds, etc.
|
32
|
+
|
33
|
+
bomb = GameObject()
|
34
|
+
|
35
|
+
bomb.bind 'destroy', ->
|
36
|
+
bomb.explode()
|
37
|
+
Sound.play "Kaboom"
|
38
|
+
|
39
|
+
@name destroy
|
40
|
+
@methodOf GameObject#
|
41
|
+
@event
|
42
|
+
###
|
43
|
+
|
44
|
+
###*
|
45
|
+
Triggered during every update step.
|
46
|
+
|
47
|
+
player = GameObject()
|
48
|
+
|
49
|
+
player.bind 'step', ->
|
50
|
+
# check to see if keys are being pressed and
|
51
|
+
# change the player's velocity
|
52
|
+
if keydown.left
|
53
|
+
player.velocity(Point(-1, 0))
|
54
|
+
else if keydown.right
|
55
|
+
player.velocity(Point(1, 0))
|
56
|
+
else
|
57
|
+
player.velocity(Point(0, 0))
|
58
|
+
|
59
|
+
@name step
|
60
|
+
@methodOf GameObject#
|
61
|
+
@event
|
62
|
+
###
|
63
|
+
|
64
|
+
###*
|
65
|
+
Triggered every update after the <code>step</code> event is triggered.
|
66
|
+
|
67
|
+
player = GameObject()
|
68
|
+
|
69
|
+
# we can really use the update and
|
70
|
+
# step events almost interchangebly
|
71
|
+
player.bind 'update', ->
|
72
|
+
# check to see if keys are being pressed and
|
73
|
+
# change the player's velocity
|
74
|
+
if keydown.left
|
75
|
+
player.velocity(Point(-1, 0))
|
76
|
+
else if keydown.right
|
77
|
+
player.velocity(Point(1, 0))
|
78
|
+
else
|
79
|
+
player.velocity(Point(0, 0))
|
80
|
+
|
81
|
+
@name update
|
82
|
+
@methodOf GameObject#
|
83
|
+
@event
|
84
|
+
###
|
85
|
+
|
86
|
+
###*
|
87
|
+
Triggered when the object is removed from
|
88
|
+
the engine. Use the remove event to handle any clean up.
|
89
|
+
|
90
|
+
boss = GameObject()
|
91
|
+
|
92
|
+
boss.bind 'remove', ->
|
93
|
+
unlockDoorToLevel2()
|
94
|
+
|
95
|
+
@name remove
|
96
|
+
@methodOf GameObject#
|
97
|
+
@event
|
98
|
+
###
|
99
|
+
|
100
|
+
GameObject = (I) ->
|
101
|
+
I ||= {}
|
102
|
+
|
103
|
+
###*
|
104
|
+
@name {Object} I Instance variables
|
105
|
+
@memberOf GameObject#
|
106
|
+
###
|
107
|
+
Object.reverseMerge I,
|
108
|
+
active: true
|
109
|
+
created: false
|
110
|
+
destroyed: false
|
111
|
+
|
112
|
+
self = Core(I).extend {
|
113
|
+
###*
|
114
|
+
Update the game object. This is generally called by the engine.
|
115
|
+
|
116
|
+
@name update
|
117
|
+
@methodOf GameObject#
|
118
|
+
###
|
119
|
+
update: (elapsedTime) ->
|
120
|
+
#TODO Extract this I.active check out into an engine gameObject remove processor or something
|
121
|
+
if I.active
|
122
|
+
self.trigger 'update', elapsedTime
|
123
|
+
|
124
|
+
I.active
|
125
|
+
|
126
|
+
###*
|
127
|
+
Triggers the create event if the object has not already been created.
|
128
|
+
|
129
|
+
@name create
|
130
|
+
@methodOf GameObject#
|
131
|
+
###
|
132
|
+
create: ->
|
133
|
+
self.trigger('create') unless I.created
|
134
|
+
I.created = true
|
135
|
+
|
136
|
+
###*
|
137
|
+
Destroys the object and triggers the destroyed event.
|
138
|
+
|
139
|
+
@name destroy
|
140
|
+
@methodOf GameObject#
|
141
|
+
###
|
142
|
+
destroy: ->
|
143
|
+
self.trigger('destroy') unless I.destroyed
|
144
|
+
|
145
|
+
I.destroyed = true
|
146
|
+
I.active = false
|
147
|
+
}
|
148
|
+
|
149
|
+
GameObject.defaultModules.each (moduleName) ->
|
150
|
+
self.include moduleName
|
151
|
+
|
152
|
+
self
|
153
|
+
|
154
|
+
GameObject.defaultModules = [
|
155
|
+
"Ageable"
|
156
|
+
"Bounded"
|
157
|
+
"Clampable"
|
158
|
+
"Cooldown"
|
159
|
+
"Drawable"
|
160
|
+
"Expirable"
|
161
|
+
"Follow"
|
162
|
+
"GameObject.Meter"
|
163
|
+
"Movable"
|
164
|
+
"Rotatable"
|
165
|
+
"TimedEvents"
|
166
|
+
"Tween"
|
167
|
+
"GameObject.Effect"
|
168
|
+
]
|
169
|
+
|
170
|
+
###*
|
171
|
+
Construct an object instance from the given entity data.
|
172
|
+
@name construct
|
173
|
+
@memberOf GameObject
|
174
|
+
@param {Object} entityData
|
175
|
+
###
|
176
|
+
GameObject.construct = (entityData) ->
|
177
|
+
if entityData.class
|
178
|
+
entityData.class.constantize()(entityData)
|
179
|
+
else
|
180
|
+
GameObject(entityData)
|
181
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
###*
|
2
|
+
A collection of effects to make your game juicy.
|
3
|
+
|
4
|
+
@name Effect
|
5
|
+
@fieldOf GameObject
|
6
|
+
@module
|
7
|
+
@constructor
|
8
|
+
@param {Object} I Instance variables
|
9
|
+
@param {Core} self Reference to including object
|
10
|
+
###
|
11
|
+
GameObject.Effect = (I={}, self) ->
|
12
|
+
|
13
|
+
###*
|
14
|
+
A convenient way to fade out this object over time.
|
15
|
+
|
16
|
+
player = GameObject()
|
17
|
+
|
18
|
+
# Fade the player object out over the next 2 seconds.
|
19
|
+
player.fadeOut 2
|
20
|
+
|
21
|
+
# Fade out and then destroy
|
22
|
+
player.fadeOut, 0.25, ->
|
23
|
+
self.destroy()
|
24
|
+
|
25
|
+
@name fadeOut
|
26
|
+
@methodOf GameObject#
|
27
|
+
@param {Number} [duration=1] Time to fade out in seconds
|
28
|
+
@param {Function} [complete=null] The function to execute when fade out completes.
|
29
|
+
###
|
30
|
+
fadeOut: (duration=1, complete) ->
|
31
|
+
self.tween duration,
|
32
|
+
alpha: 0
|
33
|
+
complete: complete
|