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 CHANGED
@@ -1,3 +1,3 @@
1
1
  module Shank
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
data/lib/shank.rb CHANGED
@@ -1,7 +1,14 @@
1
1
  require 'sprockets'
2
2
 
3
- module Shank
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 File.join(root_dir, "source")
13
+ ::Sprockets.append_path asset_dir
7
14
  end
data/pixie.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "author": "STRd6",
3
+ "main": null,
4
+ "name": "Shank",
5
+ "library": true,
6
+ "directories": {
7
+ "lib": "lib",
8
+ "source": "source",
9
+ "test": "test"
10
+ },
11
+ "libs": {
12
+ }
13
+ }
data/shank.gemspec CHANGED
@@ -15,5 +15,7 @@ Gem::Specification.new do |gem|
15
15
 
16
16
  gem.add_development_dependency "rake"
17
17
 
18
+ gem.add_dependency "coffee-script"
18
19
  gem.add_dependency "sprockets"
20
+ gem.add_dependency "pixie_dust"
19
21
  end
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
- root = (exports ? this)
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()
@@ -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
- root = (exports ? this)
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>"
@@ -1,19 +1,30 @@
1
- root = (exports ? this)
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] ||= Gamepads.Controller
15
- index: index
16
- state: state
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
- root = (exports ? this)
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.2
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
- "SELECT": 6
34
- "BACK": 6
23
+ "LT": 6
24
+ "RT": 7
25
+
26
+ "SELECT": 8
27
+ "BACK": 8
35
28
 
36
- "START": 7
29
+ "START": 9
37
30
 
38
- "HOME": 8
39
- "GUIDE": 8
31
+ "TL": 10
32
+ "TR": 11
40
33
 
41
- "TL": 9
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
- actionDown: (buttons...) ->
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
@@ -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 unless prevKeysDown[key]
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
- #TODO Position relative to canvas element
49
- mousePosition.x = event.pageX
50
- mousePosition.y = event.pageY
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
@@ -11,9 +11,7 @@ default, the track is looped.
11
11
  @namespace
12
12
  ###
13
13
 
14
- root = (exports ? this)
15
-
16
- root.Music = (->
14
+ Music = (->
17
15
  # TODO: Load this from local storage of user preferences
18
16
  globalMusicVolume = 1
19
17
  trackVolume = 1
data/source/shank.coffee CHANGED
@@ -1,17 +1 @@
1
- #= require init
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 globalVolume
37
+
38
+ @name volume
39
39
  @methodOf Sound
40
40
  @param {Number} [newVolume] The volume to set
41
41
  ###
42
- globalVolume: (newVolume) ->
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
- (exports ? this)["Sound"] = Sound
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)