shank 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 +22 -0
- data/Gemfile +3 -0
- data/LICENSE +22 -0
- data/README.md +0 -0
- data/Rakefile +2 -0
- data/lib/assets/javascripts/engine.gamepads.coffee +46 -0
- data/lib/assets/javascripts/engine_stats.coffee +10 -0
- data/lib/assets/javascripts/error_handler.coffee +11 -0
- data/lib/assets/javascripts/game_keys.coffee +6 -0
- data/lib/assets/javascripts/gamepads.coffee +21 -0
- data/lib/assets/javascripts/gamepads.controller.coffee +138 -0
- data/lib/assets/javascripts/init.coffee +6 -0
- data/lib/assets/javascripts/joysticks.coffee +238 -0
- data/lib/assets/javascripts/jquery.hotkeys.coffee +161 -0
- data/lib/assets/javascripts/jquery.reverse_merge.coffee +21 -0
- data/lib/assets/javascripts/keydown.coffee +73 -0
- data/lib/assets/javascripts/mouse.coffee +66 -0
- data/lib/assets/javascripts/music.coffee +78 -0
- data/lib/assets/javascripts/pixie_canvas.coffee +739 -0
- data/lib/assets/javascripts/request_animation_frame.coffee +22 -0
- data/lib/assets/javascripts/shank.coffee +18 -0
- data/lib/assets/javascripts/sound.coffee +131 -0
- data/lib/assets/javascripts/storage.coffee +88 -0
- data/lib/shank/version.rb +3 -0
- data/lib/shank.rb +10 -0
- data/shank.gemspec +17 -0
- data/test/jquery.reverse_merge.coffee +43 -0
- data/test/keydown.coffee +19 -0
- data/test/pixie_canvas.coffee +18 -0
- data/test/request_animation_frame.coffee +7 -0
- data/test/sound.coffee +7 -0
- data/test/storage.coffee +47 -0
- data/test/xstats.coffee +7 -0
- data/vendor/assets/javascripts/xstats.js +767 -0
- metadata +113 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
###*
|
2
|
+
A browser polyfill so you can consistently
|
3
|
+
call requestAnimationFrame. Using
|
4
|
+
requestAnimationFrame is preferred to
|
5
|
+
setInterval for main game loops.
|
6
|
+
|
7
|
+
http://paulirish.com/2011/requestanimationframe-for-smart-animating/
|
8
|
+
|
9
|
+
@name requestAnimationFrame
|
10
|
+
@namespace
|
11
|
+
###
|
12
|
+
|
13
|
+
window.requestAnimationFrame ||=
|
14
|
+
window.webkitRequestAnimationFrame ||
|
15
|
+
window.mozRequestAnimationFrame ||
|
16
|
+
window.oRequestAnimationFrame ||
|
17
|
+
window.msRequestAnimationFrame ||
|
18
|
+
(callback, element) ->
|
19
|
+
window.setTimeout( ->
|
20
|
+
callback(+new Date())
|
21
|
+
, 1000 / 60)
|
22
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#= require init
|
2
|
+
|
3
|
+
#= require engine.gamepads
|
4
|
+
#= require engine_stats
|
5
|
+
#= require error_handler
|
6
|
+
#= require game_keys
|
7
|
+
#= require gamepads
|
8
|
+
#= require gamepads.controller
|
9
|
+
#= require joysticks
|
10
|
+
#= require jquery.hotkeys
|
11
|
+
#= require jquery.reverse_merge
|
12
|
+
#= require keydown
|
13
|
+
#= require mouse
|
14
|
+
#= require music
|
15
|
+
#= require pixie_canvas
|
16
|
+
#= require request_animation_frame
|
17
|
+
#= require sound
|
18
|
+
#= require storage
|
@@ -0,0 +1,131 @@
|
|
1
|
+
(($) ->
|
2
|
+
###*
|
3
|
+
A simple interface for playing sounds in games.
|
4
|
+
|
5
|
+
@name Sound
|
6
|
+
@namespace
|
7
|
+
###
|
8
|
+
directory = App?.directories?.sounds || "sounds"
|
9
|
+
format = "wav"
|
10
|
+
sounds = {}
|
11
|
+
globalVolume = 1
|
12
|
+
|
13
|
+
loadSoundChannel = (name) ->
|
14
|
+
url = "#{BASE_URL}/#{directory}/#{name}.#{format}"
|
15
|
+
|
16
|
+
sound = $('<audio />',
|
17
|
+
autobuffer: true
|
18
|
+
preload: 'auto'
|
19
|
+
src: url
|
20
|
+
).get(0)
|
21
|
+
|
22
|
+
Sound = (id, maxChannels) ->
|
23
|
+
play: ->
|
24
|
+
Sound.play(id, maxChannels)
|
25
|
+
|
26
|
+
stop: ->
|
27
|
+
Sound.stop(id)
|
28
|
+
|
29
|
+
Object.extend Sound,
|
30
|
+
###*
|
31
|
+
Set the global volume modifier for all sound effects.
|
32
|
+
|
33
|
+
Any value set is clamped between 0 and 1. This is multiplied
|
34
|
+
into each individual effect that plays.
|
35
|
+
|
36
|
+
If no argument is given return the current global sound effect volume.
|
37
|
+
|
38
|
+
@name globalVolume
|
39
|
+
@methodOf Sound
|
40
|
+
@param {Number} [newVolume] The volume to set
|
41
|
+
###
|
42
|
+
globalVolume: (newVolume) ->
|
43
|
+
if newVolume?
|
44
|
+
globalVolume = newVolume.clamp(0, 1)
|
45
|
+
|
46
|
+
return globalVolume
|
47
|
+
|
48
|
+
###*
|
49
|
+
Play a sound from your sounds
|
50
|
+
directory with the name of `id`.
|
51
|
+
|
52
|
+
<code><pre>
|
53
|
+
# plays a sound called explode from your sounds directory
|
54
|
+
Sound.play('explode')
|
55
|
+
</pre></code>
|
56
|
+
|
57
|
+
@name play
|
58
|
+
@methodOf Sound
|
59
|
+
|
60
|
+
@param {String} id id or name of the sound file to play
|
61
|
+
@param {String} maxChannels max number of sounds able to be played simultaneously
|
62
|
+
###
|
63
|
+
play: (id, maxChannels) ->
|
64
|
+
# TODO: Too many channels crash Chrome!!!1
|
65
|
+
maxChannels ||= 4
|
66
|
+
|
67
|
+
unless sounds[id]
|
68
|
+
sounds[id] = [loadSoundChannel(id)]
|
69
|
+
|
70
|
+
channels = sounds[id]
|
71
|
+
|
72
|
+
freeChannels = $.grep channels, (sound) ->
|
73
|
+
sound.currentTime == sound.duration || sound.currentTime == 0
|
74
|
+
|
75
|
+
if channel = freeChannels.first()
|
76
|
+
try
|
77
|
+
channel.currentTime = 0
|
78
|
+
|
79
|
+
channel.volume = globalVolume
|
80
|
+
channel.play()
|
81
|
+
else
|
82
|
+
if !maxChannels || channels.length < maxChannels
|
83
|
+
sound = loadSoundChannel(id)
|
84
|
+
channels.push(sound)
|
85
|
+
sound.play()
|
86
|
+
sound.volume = globalVolume
|
87
|
+
|
88
|
+
###*
|
89
|
+
Play a sound from the given
|
90
|
+
url with the name of `id`.
|
91
|
+
|
92
|
+
<code><pre>
|
93
|
+
# plays the sound at the specified url
|
94
|
+
Sound.playFromUrl('http://YourSoundWebsite.com/explode.wav')
|
95
|
+
</pre></code>
|
96
|
+
|
97
|
+
@name playFromUrl
|
98
|
+
@methodOf Sound
|
99
|
+
|
100
|
+
@param {String} url location of sound file to play
|
101
|
+
|
102
|
+
@returns {Sound} this sound object
|
103
|
+
###
|
104
|
+
playFromUrl: (url) ->
|
105
|
+
sound = $('<audio />').get(0)
|
106
|
+
sound.src = url
|
107
|
+
|
108
|
+
sound.play()
|
109
|
+
sound.volume = globalVolume
|
110
|
+
|
111
|
+
return sound
|
112
|
+
|
113
|
+
###*
|
114
|
+
Stop a sound while it is playing.
|
115
|
+
|
116
|
+
<code><pre>
|
117
|
+
# stops the sound 'explode' from
|
118
|
+
# playing if it is currently playing
|
119
|
+
Sound.stop('explode')
|
120
|
+
</pre></code>
|
121
|
+
|
122
|
+
@name stop
|
123
|
+
@methodOf Sound
|
124
|
+
|
125
|
+
@param {String} id id or name of sound to stop playing.
|
126
|
+
###
|
127
|
+
stop: (id) ->
|
128
|
+
sounds[id]?.stop()
|
129
|
+
|
130
|
+
(exports ? this)["Sound"] = Sound
|
131
|
+
)(jQuery)
|
@@ -0,0 +1,88 @@
|
|
1
|
+
( ->
|
2
|
+
###*
|
3
|
+
A wrapper on the Local Storage API
|
4
|
+
|
5
|
+
@name Local
|
6
|
+
@namespace
|
7
|
+
###
|
8
|
+
|
9
|
+
###*
|
10
|
+
Store an object in local storage.
|
11
|
+
|
12
|
+
<code><pre>
|
13
|
+
# you can store strings
|
14
|
+
Local.set('name', 'Matt')
|
15
|
+
|
16
|
+
# and numbers
|
17
|
+
Local.set('age', 26)
|
18
|
+
|
19
|
+
# and even objects
|
20
|
+
Local.set('person', {name: 'Matt', age: 26})
|
21
|
+
</pre></code>
|
22
|
+
|
23
|
+
@name set
|
24
|
+
@methodOf Local
|
25
|
+
|
26
|
+
@param {String} key string used to identify the object you are storing
|
27
|
+
@param {Object} value value of the object you are storing
|
28
|
+
|
29
|
+
@returns {Object} value
|
30
|
+
###
|
31
|
+
store = (key, value) ->
|
32
|
+
localStorage[key] = JSON.stringify(value)
|
33
|
+
|
34
|
+
return value
|
35
|
+
|
36
|
+
###*
|
37
|
+
Retrieve an object from local storage.
|
38
|
+
|
39
|
+
<code><pre>
|
40
|
+
Local.get('name')
|
41
|
+
# => 'Matt'
|
42
|
+
|
43
|
+
Local.get('age')
|
44
|
+
# => 26
|
45
|
+
|
46
|
+
Local.get('person')
|
47
|
+
# => { age: 26, name: 'Matt' }
|
48
|
+
</pre></code>
|
49
|
+
|
50
|
+
@name get
|
51
|
+
@methodOf Local
|
52
|
+
|
53
|
+
@param {String} key string that identifies the stored object
|
54
|
+
|
55
|
+
@returns {Object} The object that was stored or undefined if no object was stored.
|
56
|
+
###
|
57
|
+
retrieve = (key) ->
|
58
|
+
value = localStorage[key]
|
59
|
+
|
60
|
+
if value?
|
61
|
+
JSON.parse(value)
|
62
|
+
|
63
|
+
# Export
|
64
|
+
(exports ? this)["Local"] =
|
65
|
+
get: retrieve
|
66
|
+
set: store
|
67
|
+
put: store
|
68
|
+
###*
|
69
|
+
Access an instance of Local with a specified prefix.
|
70
|
+
|
71
|
+
@name new
|
72
|
+
@methodOf Local
|
73
|
+
|
74
|
+
@param {String} prefix
|
75
|
+
@returns {Local} An interface to local storage with the given prefix applied.
|
76
|
+
###
|
77
|
+
new: (prefix) ->
|
78
|
+
prefix ||= ""
|
79
|
+
|
80
|
+
get: (key) ->
|
81
|
+
retrieve("#{prefix}_#{key}")
|
82
|
+
set: (key, value) ->
|
83
|
+
store("#{prefix}_#{key}", value)
|
84
|
+
put: (key, value) ->
|
85
|
+
store("#{prefix}_#{key}", value)
|
86
|
+
|
87
|
+
)()
|
88
|
+
|
data/lib/shank.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
module Shank
|
2
|
+
if defined? ::Rails::Engine
|
3
|
+
class Rails < Rails::Engine
|
4
|
+
end
|
5
|
+
elsif defined? ::Sprockets
|
6
|
+
root_dir = File.expand_path(File.dirname(File.dirname(__FILE__)))
|
7
|
+
|
8
|
+
::Sprockets.append_path File.join(root_dir, "lib", "assets", "javascripts")
|
9
|
+
end
|
10
|
+
end
|
data/shank.gemspec
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/shank/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.name = "shank"
|
6
|
+
gem.version = Shank::VERSION
|
7
|
+
gem.authors = ["Matt Diebolt", "Daniel X. Moore"]
|
8
|
+
gem.email = ["pixie@pixieengine.com"]
|
9
|
+
gem.homepage = "https://github.com/PixieEngine/Shank"
|
10
|
+
gem.summary = %q{Sometimes you gotta stab someone to make a game}
|
11
|
+
gem.description = %q{Polyfills for making games in the browser}
|
12
|
+
|
13
|
+
gem.files = `git ls-files`.split("\n")
|
14
|
+
gem.require_paths = ["lib"]
|
15
|
+
|
16
|
+
gem.add_development_dependency "rake"
|
17
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module "jQuery.reverseMerge"
|
2
|
+
|
3
|
+
test "reverse merge", ->
|
4
|
+
o = {
|
5
|
+
exists: "cool"
|
6
|
+
}
|
7
|
+
|
8
|
+
$.reverseMerge o,
|
9
|
+
another: "also cool"
|
10
|
+
exists: "not cool"
|
11
|
+
u: undefined
|
12
|
+
|
13
|
+
equal o.exists, "cool"
|
14
|
+
equal o.another, "also cool"
|
15
|
+
equal o.u, undefined
|
16
|
+
ok "u" of o
|
17
|
+
|
18
|
+
test "multiple arguments", ->
|
19
|
+
o = {
|
20
|
+
a: 0
|
21
|
+
}
|
22
|
+
|
23
|
+
$.reverseMerge o, {
|
24
|
+
a: 1
|
25
|
+
b: 1
|
26
|
+
}, {
|
27
|
+
a: 2
|
28
|
+
b: 2
|
29
|
+
c: 2
|
30
|
+
}, {
|
31
|
+
a: 3
|
32
|
+
b: 3
|
33
|
+
c: 3
|
34
|
+
d: 3
|
35
|
+
}
|
36
|
+
|
37
|
+
equal o.a, 0
|
38
|
+
equal o.b, 1
|
39
|
+
equal o.c, 2
|
40
|
+
equal o.d, 3
|
41
|
+
|
42
|
+
module()
|
43
|
+
|
data/test/keydown.coffee
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module "keydown"
|
2
|
+
|
3
|
+
test "keydown", ->
|
4
|
+
event = $.Event("keydown")
|
5
|
+
event.which = 32
|
6
|
+
|
7
|
+
$(document).trigger event
|
8
|
+
|
9
|
+
equal(keydown.space, true, "Space should be down after a keydown event")
|
10
|
+
|
11
|
+
event = $.Event("keyup")
|
12
|
+
event.which = 32
|
13
|
+
|
14
|
+
$(document).trigger event
|
15
|
+
|
16
|
+
equal(keydown.space, false, "Space should be up after a keyup event")
|
17
|
+
|
18
|
+
module()
|
19
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module "PixieCanvas"
|
2
|
+
|
3
|
+
test "exists", ->
|
4
|
+
ok $.fn.pixieCanvas
|
5
|
+
|
6
|
+
test "#centerText font", ->
|
7
|
+
canvas = $("<canvas>").pixieCanvas()
|
8
|
+
|
9
|
+
fontString = "normal normal normal 11px/16px Monaco, monospace"
|
10
|
+
|
11
|
+
canvas.centerText
|
12
|
+
x: 50
|
13
|
+
y: 50
|
14
|
+
font: fontString
|
15
|
+
|
16
|
+
equals canvas.font(), fontString
|
17
|
+
|
18
|
+
module()
|
data/test/sound.coffee
ADDED
data/test/storage.coffee
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
module "Storage"
|
2
|
+
|
3
|
+
test "Local exists", ->
|
4
|
+
ok(Local)
|
5
|
+
|
6
|
+
test "Local.set and Local.get", ->
|
7
|
+
object =
|
8
|
+
key: "test"
|
9
|
+
cool: true
|
10
|
+
num: 17
|
11
|
+
sub:
|
12
|
+
a: true
|
13
|
+
b: 14
|
14
|
+
c: "str"
|
15
|
+
|
16
|
+
Local.set("__TEST", object)
|
17
|
+
ret = Local.get("__TEST")
|
18
|
+
equal ret.key, object.key
|
19
|
+
equal ret.cool, object.cool
|
20
|
+
equal ret.num, object.num
|
21
|
+
equal ret.sub.a, object.sub.a
|
22
|
+
equal ret.sub.b, object.sub.b
|
23
|
+
equal ret.sub.c, object.sub.c
|
24
|
+
|
25
|
+
Local.set("__TEST", 0)
|
26
|
+
ret = Local.get("__TEST")
|
27
|
+
equal ret, 0
|
28
|
+
|
29
|
+
Local.set("__TEST", false)
|
30
|
+
ret = Local.get("__TEST")
|
31
|
+
equal ret, false
|
32
|
+
|
33
|
+
Local.set("__TEST", "")
|
34
|
+
ret = Local.get("__TEST")
|
35
|
+
equal ret, ""
|
36
|
+
|
37
|
+
test "Local.new", ->
|
38
|
+
local = Local.new("TEST")
|
39
|
+
key = "a test value"
|
40
|
+
|
41
|
+
local.set(key, true)
|
42
|
+
equal local.get(key), true
|
43
|
+
|
44
|
+
equal Local.get(key), null
|
45
|
+
|
46
|
+
module()
|
47
|
+
|