2013-02-28 41 views
6

Tôi có mã JS sau cho trò chơi dựa trên canvas.Phát âm thanh qua JS với chồng chéo

var EXPLOSION = "sounds/explosion.wav"; 

function playSound(str, vol) { 
    var snd = new Audio(); 
    snd.src = str; 
    snd.volume = vol; 
    snd.play(); 
} 

function createExplosion() { 
    playSound(EXPLOSION, 0.5); 
} 

Công trình này sẽ gửi yêu cầu máy chủ tải xuống tệp âm thanh mỗi khi được gọi. Ngoài ra, nếu tôi khai báo đối tượng âm thanh trước:

var snd = new Audio(); 
snd.src = EXPLOSION; 
snd.volume = 0.5; 

function createExplosion() { 
    snd.play(); 
} 

này hoạt động, tuy nhiên nếu các chức năng createExplosion được gọi trước khi âm thanh được chơi xong, nó không phát âm thanh ở tất cả. Điều này có nghĩa rằng chỉ có một lần phát duy nhất của tệp âm thanh được cho phép tại một thời điểm - và trong các tình huống mà nhiều vụ nổ đang diễn ra, nó không hoạt động chút nào.

Có cách nào để phát đúng cách tệp âm thanh nhiều lần trùng lặp với chính nó không?

+1

Đã kết thúc đi với sử dụng thư viện AudioFX: http: // codeincomplete .com/posts/2011/9/17/revisiting_html5_audio/ –

Trả lời

0

Hãy thử điều này:

(function() { 
    var snds = {}; 
    window.playSound(str,vol) { 
     if(!snds[str]) (snds[str] = new Audio()).src = str; 
     snds[str].volume = vol; 
     snds[str].play(); 
    } 
})(); 

Sau đó lần đầu tiên bạn gọi nó là nó sẽ lấy âm thanh, nhưng mỗi lần sau đó nó sẽ tái sử dụng các đối tượng âm thanh tương tự.


EDIT: Bạn cũng có thể tải trước với bản sao để cho phép âm thanh để chơi nhiều hơn một lần tại một thời điểm:

(function() { 
    var snds = {} 
    window.playSound = function(str,vol) { 
     if(!snds[str]) { 
      snds[str] = [new Audio()]; 
      snds[str][0].src = str; 
     } 
     var snd = snds[str], pointer = 0; 
     while(snd[pointer].playing) { 
      pointer++; 
      if(pointer >= snd.length) { 
       snd.push(new Audio()); 
       snd[pointer].src = str; 
      } 
     } 
     snd[pointer].volume = vol; 
     snd[pointer].play(); 
    }; 
})(); 

Lưu ý rằng điều này sẽ gửi nhiều yêu cầu nếu bạn chơi âm thanh chồng chéo bản thân quá nhiều, nhưng nó sẽ trở lại Không được sửa đổi rất nhanh chóng và sẽ chỉ làm như vậy nếu bạn chơi nó nhiều lần hơn bạn đã có trước đó.

+0

Điều này cũng gặp vấn đề tương tự. Âm thanh sẽ phát, nhưng cố gắng phát lại nó trước khi một phiên bản trước đã kết thúc chơi kết quả trong đó nó không phát âm thanh chút nào. Nó có vẻ là một vấn đề với play() ing một đối tượng âm thanh trước khi nó kết thúc. –

+0

Giải pháp thông thường của tôi cho điều này là xây dựng một mảng. Tôi sẽ chỉnh sửa câu trả lời của tôi với điều đó. –

+0

Dường như không hoạt động nhưng tôi có ý tưởng thô sơ về những gì bạn đang cố gắng làm. –

0

Tôi đang tìm kiếm điều này cho lứa tuổi trong một trò chơi Tetris tôi đang xây dựng và tôi nghĩ rằng giải pháp này là tốt nhất.

function playSoundMove() { 
    var sound = document.getElementById("move"); 
    sound.load();  
    sound.play(); 
} 

vừa tải xong và sẵn sàng sử dụng.

1

Bạn chỉ có thể sao chép nút bằng cloneNode()play() nút trùng lặp đó.

yếu tố âm thanh của tôi trông như thế này:

<audio id="knight-audio" src="knight.ogg" preload="auto"></audio> 

và tôi có một người biết lắng nghe onClick mà chỉ làm điều đó:

function click() { 
    const origAudio = document.getElementById("knight-audio"); 
    const newAudio = origAudio.cloneNode() 
    newAudio.play() 
} 

Và kể từ khi các yếu tố audio sẽ không được hiển thị, bạn không thực sự phải gắn nút vào bất cứ thứ gì.

Tôi đã xác minh phía máy khách và phía máy chủ mà Chrome chỉ cố tải xuống tệp âm thanh một lần.

Hãy cẩn thận: Tôi không chắc chắn về tác động hiệu suất, vì điều này trên trang web của tôi, clip này không được phát nhiều hơn ~ 40x tối đa cho một trang. Bạn có thể phải làm sạch các nút âm thanh nếu bạn đang làm một cái gì đó lớn hơn nhiều?

0

Dựa thêm về bộ nhớ hơn so với thời gian xử lý, chúng ta có thể làm cho một mảng của nhiều dòng vô tính của âm thanh và sau đó chơi chúng bằng cách theo thứ tự:

function gameSnd(){ 
    this.t = new Audio('sounds/tick.wav'); 
    this.v = new Audio('sounds/victory.wav'); 
    this.c = 0; 
    this.ticks=[]; 
    for(var i = 0; i<10;i++) 
    this.ticks.push(this.t.cloneNode()); 

    this.tick = function(){ 
    this.c = (this.c + 1)%10; 
    this.ticks[this.c].play(); 
    } 

    this.victory = function(){ 
    this.v.play(); 
    } 

}