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.
Files changed (108) hide show
  1. data/.gitignore +18 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE.txt +22 -0
  4. data/README +16 -0
  5. data/README.md +29 -0
  6. data/Rakefile +1 -0
  7. data/game.js +9200 -0
  8. data/lib/corelib.js +3331 -0
  9. data/lib/pixie_dust/version.rb +3 -0
  10. data/lib/pixie_dust.rb +14 -0
  11. data/pixie.json +15 -0
  12. data/pixie_dust.gemspec +29 -0
  13. data/source/active_bounds.coffee +48 -0
  14. data/source/ageable.coffee +23 -0
  15. data/source/bounded.coffee +282 -0
  16. data/source/camera.coffee +138 -0
  17. data/source/camera.fade.coffee +69 -0
  18. data/source/camera.flash.coffee +69 -0
  19. data/source/camera.rotate.coffee +11 -0
  20. data/source/camera.shake.coffee +27 -0
  21. data/source/camera.zoom.coffee +25 -0
  22. data/source/camera.zsort.coffee +13 -0
  23. data/source/clampable.coffee +61 -0
  24. data/source/collidable.coffee +126 -0
  25. data/source/collision.coffee +272 -0
  26. data/source/collision_response.coffee +28 -0
  27. data/source/color.coffee +1113 -0
  28. data/source/color_table.coffee +2534 -0
  29. data/source/controllable.coffee +66 -0
  30. data/source/cooldown.coffee +82 -0
  31. data/source/debuggable.coffee +253 -0
  32. data/source/drawable.coffee +167 -0
  33. data/source/dust_emitter.coffee +36 -0
  34. data/source/easing.coffee +38 -0
  35. data/source/emitter.coffee +7 -0
  36. data/source/emitterable.coffee +68 -0
  37. data/source/engine.coffee +274 -0
  38. data/source/engine.collision.coffee +77 -0
  39. data/source/engine.data.coffee +23 -0
  40. data/source/engine.delay.coffee +41 -0
  41. data/source/engine.fps_counter.coffee +32 -0
  42. data/source/engine.game_state.coffee +86 -0
  43. data/source/engine.joysticks.coffee +47 -0
  44. data/source/engine.keyboard.coffee +17 -0
  45. data/source/engine.levels.coffee +69 -0
  46. data/source/engine.mouse.coffee +16 -0
  47. data/source/engine.selector.coffee +166 -0
  48. data/source/engine.stats.coffee +16 -0
  49. data/source/engine.tilemap.coffee +41 -0
  50. data/source/engine_background.coffee +32 -0
  51. data/source/expirable.coffee +47 -0
  52. data/source/flickerable.coffee +78 -0
  53. data/source/follow.coffee +65 -0
  54. data/source/framerate.coffee +42 -0
  55. data/source/game_object.coffee +181 -0
  56. data/source/game_object.effect.coffee +33 -0
  57. data/source/game_object.meter.coffee +191 -0
  58. data/source/game_over.coffee +40 -0
  59. data/source/game_state.coffee +67 -0
  60. data/source/game_state.save_state.coffee +76 -0
  61. data/source/game_state.single_camera.coffee +40 -0
  62. data/source/game_state_cameras.coffee +33 -0
  63. data/source/level_state.coffee +32 -0
  64. data/source/movable.coffee +57 -0
  65. data/source/oscillator.coffee +18 -0
  66. data/source/pixie_dust.coffee +2 -0
  67. data/source/resource_loader.coffee +35 -0
  68. data/source/rotatable.coffee +38 -0
  69. data/source/sprite.coffee +181 -0
  70. data/source/text_effect.coffee +74 -0
  71. data/source/text_effect.floating.coffee +22 -0
  72. data/source/text_screen.coffee +38 -0
  73. data/source/tilemap.coffee +56 -0
  74. data/source/timed_events.coffee +78 -0
  75. data/source/title_screen.coffee +38 -0
  76. data/source/tween.coffee +70 -0
  77. data/test/active_bounds.coffee +67 -0
  78. data/test/bounded.coffee +98 -0
  79. data/test/camera.coffee +29 -0
  80. data/test/clampable.coffee +18 -0
  81. data/test/collidable.coffee +51 -0
  82. data/test/collision.coffee +70 -0
  83. data/test/color.coffee +533 -0
  84. data/test/controllable.coffee +108 -0
  85. data/test/cooldown.coffee +116 -0
  86. data/test/debuggable.coffee +71 -0
  87. data/test/drawable.coffee +31 -0
  88. data/test/emitter.coffee +0 -0
  89. data/test/emitterable.coffee +15 -0
  90. data/test/engine.coffee +228 -0
  91. data/test/engine_data.coffee +12 -0
  92. data/test/engine_delay.coffee +14 -0
  93. data/test/engine_selector.coffee +100 -0
  94. data/test/expirable.coffee +35 -0
  95. data/test/flickerable.coffee +51 -0
  96. data/test/follow.coffee +34 -0
  97. data/test/game_object.coffee +78 -0
  98. data/test/game_object_effect.coffee +17 -0
  99. data/test/metered.coffee +33 -0
  100. data/test/movable.coffee +46 -0
  101. data/test/oscillator.coffee +28 -0
  102. data/test/resource_loader.coffee +7 -0
  103. data/test/rotatable.coffee +20 -0
  104. data/test/sprite.coffee +21 -0
  105. data/test/text.coffee +25 -0
  106. data/test/timed_events.coffee +23 -0
  107. data/test/tweening.coffee +18 -0
  108. 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