shank 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/shank/version.rb +1 -1
- data/lib/shank.rb +9 -2
- data/pixie.json +13 -0
- data/shank.gemspec +2 -0
- data/source/{init.coffee → _init.coffee} +0 -0
- data/source/engine.gamepads.coffee +6 -8
- data/source/error_handler.coffee +1 -3
- data/source/gamepads.coffee +21 -7
- data/source/gamepads.combined_controller.coffee +38 -0
- data/source/gamepads.controller.coffee +25 -23
- data/source/gamepads.keyboard_controller.coffee +90 -0
- data/source/keydown.coffee +5 -2
- data/source/mouse.coffee +10 -3
- data/source/music.coffee +1 -3
- data/source/shank.coffee +1 -17
- data/source/sound.coffee +27 -12
- metadata +82 -68
- data/source/engine_stats.coffee +0 -12
- data/source/joysticks.coffee +0 -240
- data/source/jquery.reverse_merge.coffee +0 -21
- data/test/jquery.reverse_merge.coffee +0 -43
- data/test/xstats.coffee +0 -7
- data/vendor/assets/javascripts/xstats.js +0 -767
data/lib/shank/version.rb
CHANGED
data/lib/shank.rb
CHANGED
@@ -1,7 +1,14 @@
|
|
1
1
|
require 'sprockets'
|
2
2
|
|
3
|
-
|
3
|
+
require 'pixie_dust'
|
4
|
+
|
5
|
+
if defined? ::Rails
|
6
|
+
class Engine < ::Rails::Engine
|
7
|
+
config.paths['app/assets'] = "source"
|
8
|
+
end
|
9
|
+
else
|
4
10
|
root_dir = File.expand_path(File.dirname(File.dirname(__FILE__)))
|
11
|
+
asset_dir = File.join(root_dir, "source")
|
5
12
|
|
6
|
-
::Sprockets.append_path
|
13
|
+
::Sprockets.append_path asset_dir
|
7
14
|
end
|
data/pixie.json
ADDED
data/shank.gemspec
CHANGED
File without changes
|
@@ -3,17 +3,17 @@ The <code>Gamepads</code> module gives the engine access to gamepads.
|
|
3
3
|
|
4
4
|
# First you need to add the `Gamepads` module to the engine
|
5
5
|
Engine.defaultModules.push "Gamepads"
|
6
|
-
|
6
|
+
|
7
7
|
window.engine = Engine
|
8
8
|
...
|
9
|
-
|
9
|
+
|
10
10
|
# Then you need to get a controller reference
|
11
11
|
# id = 0 for player 1, etc.
|
12
12
|
controller = engine.controller(id)
|
13
|
-
|
13
|
+
|
14
14
|
# Point indicating direction primary axis is held
|
15
15
|
direction = controller.position()
|
16
|
-
|
16
|
+
|
17
17
|
# Check if buttons are held
|
18
18
|
controller.actionDown("A")
|
19
19
|
controller.actionDown("B")
|
@@ -27,11 +27,9 @@ The <code>Gamepads</code> module gives the engine access to gamepads.
|
|
27
27
|
@param {Object} I Instance variables
|
28
28
|
@param {Object} self Reference to the engine
|
29
29
|
###
|
30
|
-
|
31
|
-
|
32
|
-
root.Engine.Gamepads = (I, self) ->
|
30
|
+
Engine.Gamepads = (I, self) ->
|
33
31
|
gamepads = Gamepads()
|
34
|
-
|
32
|
+
|
35
33
|
self.bind "beforeUpdate", ->
|
36
34
|
# Update the gamepads
|
37
35
|
gamepads.update()
|
data/source/error_handler.coffee
CHANGED
@@ -2,9 +2,7 @@
|
|
2
2
|
This error handler captures any runtime errors and reports them to the IDE
|
3
3
|
if present.
|
4
4
|
###
|
5
|
-
|
6
|
-
|
7
|
-
root.onerror = (message, url, lineNumber) ->
|
5
|
+
window.onerror = (message, url, lineNumber) ->
|
8
6
|
errorContext = $('script').last().text().split('\n')[(lineNumber-5)..(lineNumber+4)]
|
9
7
|
|
10
8
|
errorContext[4] = "<b style='font-weight: bold; text-decoration: underline;'>" + errorContext[4] + "</b>"
|
data/source/gamepads.coffee
CHANGED
@@ -1,19 +1,30 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
root.Gamepads = (I={}) ->
|
1
|
+
Gamepads = (I={}) ->
|
4
2
|
state = {} # holds current and previous states
|
5
3
|
controllers = [] # controller cache
|
6
4
|
|
7
5
|
# Capture the current gamepad state
|
8
6
|
snapshot = ->
|
9
|
-
Array::map.call navigator.webkitGamepads || navigator.webkitGetGamepads(), (x) ->
|
7
|
+
Array::map.call navigator.webkitGamepads || navigator.webkitGetGamepads?() || [], (x) ->
|
10
8
|
axes: x.axes
|
11
9
|
buttons: x.buttons
|
12
10
|
|
13
11
|
controller: (index=0) ->
|
14
|
-
controllers[index]
|
15
|
-
|
16
|
-
|
12
|
+
if controller = controllers[index]
|
13
|
+
return controller
|
14
|
+
|
15
|
+
gamepadIndex = index # (index + 1) % 4 # Offsetting gamepads
|
16
|
+
|
17
|
+
gamepad =
|
18
|
+
Gamepads.Controller
|
19
|
+
index: gamepadIndex
|
20
|
+
state: state
|
21
|
+
|
22
|
+
if index is 0 # TODO Second keyboard controls
|
23
|
+
keyboardController = Gamepads.KeyboardController()
|
24
|
+
|
25
|
+
controllers[index] ||= Gamepads.CombinedController(gamepad, keyboardController)
|
26
|
+
else
|
27
|
+
controllers[index] ||= gamepad
|
17
28
|
|
18
29
|
update: ->
|
19
30
|
state.previous = state.current
|
@@ -21,3 +32,6 @@ root.Gamepads = (I={}) ->
|
|
21
32
|
|
22
33
|
controllers.each (controller) ->
|
23
34
|
controller?.update()
|
35
|
+
|
36
|
+
# window.addEventListener "MozGamepadConnected", (event) ->
|
37
|
+
# console.log event
|
@@ -0,0 +1,38 @@
|
|
1
|
+
Gamepads.CombinedController = (sources...) ->
|
2
|
+
|
3
|
+
self = Core().extend
|
4
|
+
buttonDown: (buttons...) ->
|
5
|
+
sources.inject false, (memo, source) ->
|
6
|
+
memo or source.buttonDown buttons...
|
7
|
+
|
8
|
+
# true if button was just pressed
|
9
|
+
buttonPressed: (button) ->
|
10
|
+
sources.inject false, (memo, source) ->
|
11
|
+
memo or source.buttonPressed(button)
|
12
|
+
|
13
|
+
# true if button was just released
|
14
|
+
buttonReleased: (button) ->
|
15
|
+
sources.inject false, (memo, source) ->
|
16
|
+
memo or source.buttonPressed(button)
|
17
|
+
|
18
|
+
position: (stick=0) ->
|
19
|
+
raw = sources.inject Point(0, 0), (point, source) ->
|
20
|
+
point.add(source.position(stick))
|
21
|
+
|
22
|
+
# TODO: This could be a point method
|
23
|
+
if raw.length() > 1
|
24
|
+
raw.norm()
|
25
|
+
else
|
26
|
+
raw
|
27
|
+
|
28
|
+
tap: ->
|
29
|
+
raw = sources.inject Point(0, 0), (point, source) ->
|
30
|
+
point.add(source.tap())
|
31
|
+
|
32
|
+
Point(raw.x.sign(), raw.y.sign())
|
33
|
+
|
34
|
+
update: ->
|
35
|
+
sources.invoke "update"
|
36
|
+
|
37
|
+
drawDebug: (canvas) ->
|
38
|
+
sources.invoke "drawDebug", canvas
|
@@ -1,12 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
root.Gamepads.Controller = (I={}) ->
|
1
|
+
Gamepads.Controller = (I={}) ->
|
4
2
|
Object.reverseMerge I,
|
5
3
|
debugColor: "#000"
|
6
4
|
|
7
5
|
MAX_BUFFER = 0.03
|
8
6
|
AXIS_MAX = 1 - MAX_BUFFER
|
9
|
-
DEAD_ZONE = AXIS_MAX * 0.
|
7
|
+
DEAD_ZONE = AXIS_MAX * 0.25
|
10
8
|
TRIP_HIGH = AXIS_MAX * 0.75
|
11
9
|
TRIP_LOW = AXIS_MAX * 0.5
|
12
10
|
|
@@ -16,30 +14,24 @@ root.Gamepads.Controller = (I={}) ->
|
|
16
14
|
"A": 0
|
17
15
|
"B": 1
|
18
16
|
|
19
|
-
# X/C, Y/D are interchangeable
|
20
|
-
"C": 2
|
21
|
-
"D": 3
|
22
17
|
"X": 2
|
23
18
|
"Y": 3
|
24
19
|
|
25
|
-
"L": 4
|
26
20
|
"LB": 4
|
27
|
-
"L1": 4
|
28
|
-
|
29
|
-
"R": 5
|
30
21
|
"RB": 5
|
31
|
-
"R1": 5
|
32
22
|
|
33
|
-
"
|
34
|
-
"
|
23
|
+
"LT": 6
|
24
|
+
"RT": 7
|
25
|
+
|
26
|
+
"SELECT": 8
|
27
|
+
"BACK": 8
|
35
28
|
|
36
|
-
"START":
|
29
|
+
"START": 9
|
37
30
|
|
38
|
-
"
|
39
|
-
"
|
31
|
+
"TL": 10
|
32
|
+
"TR": 11
|
40
33
|
|
41
|
-
"
|
42
|
-
"TR": 10
|
34
|
+
"HOME": 16
|
43
35
|
|
44
36
|
currentState = ->
|
45
37
|
I.state.current?[I.index]
|
@@ -65,7 +57,7 @@ root.Gamepads.Controller = (I={}) ->
|
|
65
57
|
tap = Point(x, y)
|
66
58
|
|
67
59
|
self = Core().include(Bindable).extend
|
68
|
-
|
60
|
+
buttonDown: (buttons...) ->
|
69
61
|
if state = currentState()
|
70
62
|
buttons.inject false, (down, button) ->
|
71
63
|
down || if button is "ANY"
|
@@ -82,6 +74,11 @@ root.Gamepads.Controller = (I={}) ->
|
|
82
74
|
|
83
75
|
return (self.buttons()[buttonId] > BUTTON_THRESHOLD) && !(previousState()?.buttons[buttonId] > BUTTON_THRESHOLD)
|
84
76
|
|
77
|
+
buttonReleased: (button) ->
|
78
|
+
buttonId = buttonMapping[button]
|
79
|
+
|
80
|
+
return !(self.buttons()[buttonId] > BUTTON_THRESHOLD) && (previousState()?.buttons[buttonId] > BUTTON_THRESHOLD)
|
81
|
+
|
85
82
|
position: (stick=0) ->
|
86
83
|
if state = currentState()
|
87
84
|
p = Point(self.axis(2*stick), self.axis(2*stick+1))
|
@@ -129,12 +126,17 @@ root.Gamepads.Controller = (I={}) ->
|
|
129
126
|
color: I.debugColor
|
130
127
|
text: axis
|
131
128
|
x: 0
|
132
|
-
y: i * lineHeight
|
129
|
+
y: (i + 1) * lineHeight
|
133
130
|
|
134
131
|
self.buttons().each (button, i) ->
|
132
|
+
canvas.drawText
|
133
|
+
color: I.debugColor
|
134
|
+
text: "#{i}:"
|
135
|
+
x: 230
|
136
|
+
y: (i + 1) * lineHeight
|
137
|
+
|
135
138
|
canvas.drawText
|
136
139
|
color: I.debugColor
|
137
140
|
text: button
|
138
141
|
x: 250
|
139
|
-
y: i * lineHeight
|
140
|
-
|
142
|
+
y: (i + 1) * lineHeight
|
@@ -0,0 +1,90 @@
|
|
1
|
+
Gamepads.KeyboardController = (I={}) ->
|
2
|
+
Object.reverseMerge I,
|
3
|
+
axisMapping: [
|
4
|
+
["left", "right"]
|
5
|
+
["up", "down"]
|
6
|
+
]
|
7
|
+
buttonMapping:
|
8
|
+
"A": 'z'
|
9
|
+
"B": 'x'
|
10
|
+
|
11
|
+
# X/C, Y/D are interchangeable
|
12
|
+
"C": 'c'
|
13
|
+
"D": 'v'
|
14
|
+
"X": 'c'
|
15
|
+
"Y": 'v'
|
16
|
+
|
17
|
+
"SELECT": "shift"
|
18
|
+
"START": "return"
|
19
|
+
|
20
|
+
debugColor: "#000"
|
21
|
+
|
22
|
+
tap = Point(0, 0)
|
23
|
+
buttonKeys = Object.keys(I.buttonMapping)
|
24
|
+
buttonValues = buttonKeys.map (key) ->
|
25
|
+
I.buttonMapping[key]
|
26
|
+
|
27
|
+
# Init any keys used
|
28
|
+
I.axisMapping.each (axis) ->
|
29
|
+
axis.each (key) ->
|
30
|
+
keydown[key] = false
|
31
|
+
|
32
|
+
buttonKeys.each (key) ->
|
33
|
+
keydown[key] = false
|
34
|
+
|
35
|
+
processTaps = ->
|
36
|
+
[x, y] = I.axisMapping.map ([negative, positive]) ->
|
37
|
+
justPressed[positive] - justPressed[negative]
|
38
|
+
|
39
|
+
tap = Point(x, y)
|
40
|
+
|
41
|
+
self = Core().include(Bindable).extend
|
42
|
+
buttonDown: (buttons...) ->
|
43
|
+
buttons.inject false, (down, button) ->
|
44
|
+
down || if button is "ANY"
|
45
|
+
buttonValues.inject false, (down, button) ->
|
46
|
+
down || keydown[button]
|
47
|
+
else
|
48
|
+
keydown[I.buttonMapping[button]]
|
49
|
+
|
50
|
+
# true if button was just pressed
|
51
|
+
buttonPressed: (button) ->
|
52
|
+
keyname = I.buttonMapping[button]
|
53
|
+
|
54
|
+
return justPressed[keyname]
|
55
|
+
|
56
|
+
buttonReleased: (button) ->
|
57
|
+
keyname = I.buttonMapping[button]
|
58
|
+
|
59
|
+
return justReleased[keyname]
|
60
|
+
|
61
|
+
position: (stick=0) ->
|
62
|
+
[x, y] = I.axisMapping.map ([negative, positive]) ->
|
63
|
+
keydown[positive] - keydown[negative]
|
64
|
+
|
65
|
+
tap = Point(x, y)
|
66
|
+
|
67
|
+
tap: ->
|
68
|
+
tap
|
69
|
+
|
70
|
+
update: ->
|
71
|
+
processTaps()
|
72
|
+
|
73
|
+
drawDebug: (canvas) ->
|
74
|
+
lineHeight = 18
|
75
|
+
|
76
|
+
p = self.position()
|
77
|
+
|
78
|
+
["x", "y"].each (key, i) ->
|
79
|
+
canvas.drawText
|
80
|
+
color: I.debugColor
|
81
|
+
text: p[key]
|
82
|
+
x: 0
|
83
|
+
y: i * lineHeight
|
84
|
+
|
85
|
+
buttonKeys.each (button, i) ->
|
86
|
+
canvas.drawText
|
87
|
+
color: I.debugColor
|
88
|
+
text: self.buttonDown(button)
|
89
|
+
x: 250
|
90
|
+
y: i * lineHeight
|
data/source/keydown.coffee
CHANGED
@@ -21,7 +21,7 @@ $ ->
|
|
21
21
|
###
|
22
22
|
|
23
23
|
###*
|
24
|
-
The global justPressed property lets your query the status of keys. However,
|
24
|
+
The global justPressed property lets your query the status of keys. However,
|
25
25
|
unlike keydown it will only trigger once for each time the key is pressed.
|
26
26
|
|
27
27
|
<code><pre>
|
@@ -43,6 +43,7 @@ $ ->
|
|
43
43
|
###
|
44
44
|
window.keydown = {}
|
45
45
|
window.justPressed = {}
|
46
|
+
window.justReleased = {}
|
46
47
|
|
47
48
|
prevKeysDown = {}
|
48
49
|
|
@@ -60,10 +61,12 @@ $ ->
|
|
60
61
|
|
61
62
|
window.updateKeys = () ->
|
62
63
|
window.justPressed = {}
|
64
|
+
window.justReleased = {}
|
63
65
|
keydown.any = false
|
64
66
|
|
65
67
|
for key, value of keydown
|
66
|
-
justPressed[key] = value
|
68
|
+
justPressed[key] = value and !prevKeysDown[key]
|
69
|
+
justReleased[key] = !value and prevKeysDown[key]
|
67
70
|
|
68
71
|
justPressed.any = true if (justPressed[key] || mousePressed.left || mousePressed.right)
|
69
72
|
keydown.any = true if (value || mouseDown.left || mouseDown.right)
|
data/source/mouse.coffee
CHANGED
@@ -32,6 +32,7 @@ $ ->
|
|
32
32
|
###
|
33
33
|
window.mouseDown = {}
|
34
34
|
window.mousePressed = {}
|
35
|
+
window.mouseReleased = {}
|
35
36
|
window.mousePosition = Point(0, 0)
|
36
37
|
|
37
38
|
prevButtonsDown = {}
|
@@ -45,9 +46,11 @@ $ ->
|
|
45
46
|
buttonNames[event.which]
|
46
47
|
|
47
48
|
$(document).bind "mousemove", (event) ->
|
48
|
-
#
|
49
|
-
|
50
|
-
|
49
|
+
# Position relative to canvas element
|
50
|
+
offset = $("canvas").offset()
|
51
|
+
|
52
|
+
mousePosition.x = event.pageX - offset.left
|
53
|
+
mousePosition.y = event.pageY - offset.top
|
51
54
|
|
52
55
|
$(document).bind "mousedown", (event) ->
|
53
56
|
mouseDown[buttonName(event)] = true
|
@@ -57,10 +60,14 @@ $ ->
|
|
57
60
|
|
58
61
|
window.updateMouse = ->
|
59
62
|
window.mousePressed = {}
|
63
|
+
window.mouseReleased = {}
|
60
64
|
|
61
65
|
for button, value of mouseDown
|
62
66
|
mousePressed[button] = value unless prevButtonsDown[button]
|
63
67
|
|
68
|
+
for button, value of mouseDown
|
69
|
+
mouseReleased[button] = !value if prevButtonsDown[button]
|
70
|
+
|
64
71
|
prevButtonsDown = {}
|
65
72
|
for button, value of mouseDown
|
66
73
|
prevButtonsDown[button] = value
|
data/source/music.coffee
CHANGED
data/source/shank.coffee
CHANGED
@@ -1,17 +1 @@
|
|
1
|
-
#=
|
2
|
-
|
3
|
-
#= require engine.gamepads
|
4
|
-
#= require engine_stats
|
5
|
-
#= require error_handler
|
6
|
-
#= require gamepads
|
7
|
-
#= require gamepads.controller
|
8
|
-
#= require joysticks
|
9
|
-
#= require jquery.hotkeys
|
10
|
-
#= require jquery.reverse_merge
|
11
|
-
#= require keydown
|
12
|
-
#= require mouse
|
13
|
-
#= require music
|
14
|
-
#= require pixie_canvas
|
15
|
-
#= require request_animation_frame
|
16
|
-
#= require sound
|
17
|
-
#= require storage
|
1
|
+
#= require_tree .
|
data/source/sound.coffee
CHANGED
@@ -29,24 +29,24 @@
|
|
29
29
|
Object.extend Sound,
|
30
30
|
###*
|
31
31
|
Set the global volume modifier for all sound effects.
|
32
|
-
|
32
|
+
|
33
33
|
Any value set is clamped between 0 and 1. This is multiplied
|
34
34
|
into each individual effect that plays.
|
35
|
-
|
35
|
+
|
36
36
|
If no argument is given return the current global sound effect volume.
|
37
|
-
|
38
|
-
@name
|
37
|
+
|
38
|
+
@name volume
|
39
39
|
@methodOf Sound
|
40
40
|
@param {Number} [newVolume] The volume to set
|
41
41
|
###
|
42
|
-
|
42
|
+
volume: (newVolume) ->
|
43
43
|
if newVolume?
|
44
44
|
globalVolume = newVolume.clamp(0, 1)
|
45
45
|
|
46
46
|
return globalVolume
|
47
47
|
|
48
48
|
###*
|
49
|
-
Play a sound from your sounds
|
49
|
+
Play a sound from your sounds
|
50
50
|
directory with the name of `id`.
|
51
51
|
|
52
52
|
<code><pre>
|
@@ -59,7 +59,7 @@
|
|
59
59
|
|
60
60
|
@param {String} id id or name of the sound file to play
|
61
61
|
@param {String} maxChannels max number of sounds able to be played simultaneously
|
62
|
-
###
|
62
|
+
###
|
63
63
|
play: (id, maxChannels) ->
|
64
64
|
# TODO: Too many channels crash Chrome!!!1
|
65
65
|
maxChannels ||= 4
|
@@ -100,7 +100,7 @@
|
|
100
100
|
@param {String} url location of sound file to play
|
101
101
|
|
102
102
|
@returns {Sound} this sound object
|
103
|
-
###
|
103
|
+
###
|
104
104
|
playFromUrl: (url) ->
|
105
105
|
sound = $('<audio />').get(0)
|
106
106
|
sound.src = url
|
@@ -114,8 +114,8 @@
|
|
114
114
|
Stop a sound while it is playing.
|
115
115
|
|
116
116
|
<code><pre>
|
117
|
-
# stops the sound 'explode' from
|
118
|
-
# playing if it is currently playing
|
117
|
+
# stops the sound 'explode' from
|
118
|
+
# playing if it is currently playing
|
119
119
|
Sound.stop('explode')
|
120
120
|
</pre></code>
|
121
121
|
|
@@ -123,9 +123,24 @@
|
|
123
123
|
@methodOf Sound
|
124
124
|
|
125
125
|
@param {String} id id or name of sound to stop playing.
|
126
|
-
###
|
126
|
+
###
|
127
127
|
stop: (id) ->
|
128
128
|
sounds[id]?.stop()
|
129
129
|
|
130
|
-
|
130
|
+
###*
|
131
|
+
Set the global volume modifier for all sound effects.
|
132
|
+
|
133
|
+
Any value set is clamped between 0 and 1. This is multiplied
|
134
|
+
into each individual effect that plays.
|
135
|
+
|
136
|
+
If no argument is given return the current global sound effect volume.
|
137
|
+
|
138
|
+
@name globalVolume
|
139
|
+
@deprecated
|
140
|
+
@methodOf Sound
|
141
|
+
@param {Number} [newVolume] The volume to set
|
142
|
+
###
|
143
|
+
Sound.globalVolume = Sound.volume
|
144
|
+
|
145
|
+
(exports ? this)["Sound"] = Sound
|
131
146
|
)(jQuery)
|