diff --git a/public/sounds/clear.wav b/public/sounds/clear.wav new file mode 100644 index 0000000..366bf56 Binary files /dev/null and b/public/sounds/clear.wav differ diff --git a/public/sounds/down.wav b/public/sounds/down.wav new file mode 100644 index 0000000..d2ae8fd Binary files /dev/null and b/public/sounds/down.wav differ diff --git a/public/sounds/drop.wav b/public/sounds/drop.wav new file mode 100644 index 0000000..4f5b154 Binary files /dev/null and b/public/sounds/drop.wav differ diff --git a/public/sounds/left.wav b/public/sounds/left.wav new file mode 100644 index 0000000..5d79f92 Binary files /dev/null and b/public/sounds/left.wav differ diff --git a/public/sounds/right.wav b/public/sounds/right.wav new file mode 100644 index 0000000..0069422 Binary files /dev/null and b/public/sounds/right.wav differ diff --git a/src/tetromino-dom-view.coffee b/src/tetromino-dom-view.coffee index 36b11d3..4844a3c 100644 --- a/src/tetromino-dom-view.coffee +++ b/src/tetromino-dom-view.coffee @@ -87,7 +87,27 @@ export class PlayingFieldDomView THEMES = ['blue', 'orange', 'yellow'] + soundContext: new AudioContext() + allSounds: + down: + url: 'sounds/down.wav' + volume: 1 + drop: + url: 'sounds/drop.wav' + volume: 1 + left: + url: 'sounds/left.wav' + volume: 1 + right: + url: 'sounds/right.wav' + volume: 1 + clear: + url: 'sounds/clear.wav' + volume: 3 + constructor: (@fieldModel, @domId, options) -> + @isLocalPlayer = @fieldModel.isLocalPlayer() + @ordinal = options.ordinal @blockHeight = 20 @blockWidth = 20 @@ -141,6 +161,53 @@ export class PlayingFieldDomView else $(@pausedSelector()).removeClass('visible') + # sound + if @isLocalPlayer + @initializeSounds() + decouple.on @fieldModel, 'afterAttachPiece', @, (caller, event) => console.log("attach") + decouple.on @fieldModel, 'onInput', @, (caller, event, arg) => + if arg in ['down','left','right'] + @playSound arg + decouple.on @fieldModel, 'clear', @, => @playSound('clear') + decouple.on @fieldModel, 'beforeDrop', @, => @playSound('drop') + + initializeSounds: () -> @loadSound(key, sound) for key, sound of @allSounds + loadSound: (name, sound) => + req = new XMLHttpRequest() + req.open('GET', sound.url, true) + req.responseType = 'arraybuffer' + req.onload = => + @soundContext.decodeAudioData req.response, + (buff) => + sound.buffer = buff + (err) -> + console.error('E: ', err) + req.send() + + + playSound: (name, options) => + if not sound = @allSounds[name] + console.warn(name, ' entry not found in allSounds') + return + + soundVolume = @allSounds[name].volume or 1 + buffer = sound.buffer + if not buffer + console.warn(name, ' buffer not found in allSounds') + return + else + source = @soundContext.createBufferSource() + source.buffer = buffer + volume = @soundContext.createGain() + if options + if options.volume + volume.gain.value = soundVolume * options.volume + else + volume.gain.value = soundVolume + volume.connect @soundContext.destination + source.connect volume + source.start 0 + return leaveGame: (callback = null) => $(@fieldSelector()).fadeOut 'slow', => diff --git a/src/tetromino-engine.coffee b/src/tetromino-engine.coffee index 942bb6b..142c812 100644 --- a/src/tetromino-engine.coffee +++ b/src/tetromino-engine.coffee @@ -188,7 +188,9 @@ export class PlayingField @STATE_PAUSED = STATE_PAUSED = 1 @STATE_GAMEOVER_MESSAGE = STATE_GAMEOVER_MESSAGE = 2 @STATE_GAMEOVER_READY = STATE_GAMEOVER_READY = 3 - + + isLocalPlayer: -> @viewType == 'local' + constructor: (game, options, @DEBUG = false) -> @playerId = options.playerId if options.playerId? @viewType = options.viewType @@ -220,7 +222,7 @@ export class PlayingField decouple.trigger(game, 'newPlayingFieldBeforeInit', @) - useDebugFill = @viewType == 'local' and @DEBUG + useDebugFill = @isLocalPlayer() and @DEBUG if useDebugFill for i in [0 ... @fieldHeight] when i > @fieldHeight - 5 for j in [0 ... @fieldWidth] when j != 0 @@ -270,6 +272,7 @@ export class PlayingField when STATE_PLAYING if event.action == 'escape' then @pause(); return true return false unless @acceptingMoveInput() + decouple.trigger(@, 'onInput', event.action) switch event.action when 'left' then @moveLeft() when 'right' then @moveRight()