     # wrap the real play (_play()) in a load() call to ensure sound was loaded
     # calling play on an already playing Sound object has no effect
     play: () ->
-        if not @playing or (@source? and @source.playbackState == @source.FINISHED_STATE)
+        if not @playing
             @playing = true
-            @load(() => @_play(@loop, @volume))
+            @load(() => @_play(@looping, @volume))
         
     _play: (looping, volume) ->
-        @source = gGame.soundManager.getSoundSource(@key, { loop: looping, volume: volume })
+        @source = gGame.soundManager.getSoundSource(@key, { looping: looping, volume: volume })
+        @source.onended = ( () => @playing = false )
         @source.start(0)
-    
+
     stop: ->
-        @source?.stop(0)
+        if @playing
+            @source.stop(0)
         @source = null
         @playing = false
 

        @mainNode.gain.value = 0

    unmute: ->
        @mainNode.gain.value = 1
            
    stopAll: ->
        @mainNode.disconnect()
        @mainNode = @context.createGainNode()
        @mainNode.connect(@context.destination)
        
    getSoundSource: (key, settings) ->
        if !@enabled then return false

    enabled: true
    context: null
    mainNode: null
    defaultVolume: 0.5
    
    soundMap:
        shoot: 'assets/sound/shoot.mp3'
