如何在游戏状态为暂停时停止游戏的播放列表,并在游戏完成暂停状态后重新播放? JavaScript

Posted

技术标签:

【中文标题】如何在游戏状态为暂停时停止游戏的播放列表,并在游戏完成暂停状态后重新播放? JavaScript【英文标题】:How to stop a playlist of a game when the game state is pause and play again when the game finish the pause state? JavaScript 【发布时间】:2021-08-09 01:56:54 【问题描述】:

我创建了一个游戏,它在运行时发出播放列表,当玩家暂停游戏时发出音乐环境主题,播放列表停止,但当玩家完成暂停状态时,我不知道如何重新开始播放列表。 这是游戏状态的对象:

...
const GAMESTATE = 
    PAUSED: 0,
    RUNNING: 1,
    MENU: 2,
    GAMEOVER: 3,
    NEWLEVEL: 4
  ;
...

这些是播放列表中的歌曲:

...
    constructor() 
        this.gameState = GAMESTATE.MENU;
        this.init = document.getElementById('init');
        this.gameState = GAMESTATE.MENU;
        this.pink = document.getElementById('pink');
        this.epic = document.getElementById('epic');
        this.rock = document.getElementById('rock');
        this.jungla = document.getElementById('jungla');
        this.luna = document.getElementById('luna');
        this.shot = document.getElementById('shot');
        this.piano = document.getElementById('piano');
        this.hight = document.getElementById('hight');
        this.bad = document.getElementById('bad');
        this.playList = [this.init, this.pink, this.epic, 
        this.rock, this.jungla, this.luna, this.shot, this.piano, 
        this.hight];
    
...

请注意,游戏的初始状态是菜单状态。 我做了一个随机播放列表的函数:

...
    getRandom() 
        return Math.floor(Math.random()*this.playList.length);
        
...

然后我在每个关卡的开头放置一首歌曲完成后,另一首随机开始,以固定歌曲为起点。像这样:

...
    start() 
    if(this.gameState !== GAMESTATE.MENU && this.gameState !== 
    GAMESTATE.NEWLEVEL) return;
    this.gameState = GAMESTATE.RUNNING;
    for(i ; i < this.playList.length; i++) 
                this.playList[i].addEventListener('ended', () => 
                    this.playList[this.getRandom()].play();
                )
        
    this.playList[0].play();
    
...

我停止播放列表这样的:

...
    if(this.gameState === GAMESTATE.PAUSED) 
            this.bad.play();
            for(i = 0; i < this.playList.length; i++) 
                if(this.playList[i].play()) 
                    this.playList[i].pause();
                 
    
...

我尝试使用以下命令重新启动播放列表:

...
   if(this.gameState === GAMESTATE.RUNNING) 
            this.bad.pause();
            for(i = 0; i < this.playList.length; i++) 
            if(this.playList[i].pause()) 
                    this.playList[i].play();
            
    
...

但这最后一步失败了,我做错了什么?

【问题讨论】:

【参考方案1】:

暂停

停止播放列表函数中的if 语句调用 play() 函数。您要做的是检查元素以查看它是否正在播放。您可以使用htmlMediaElementpaused 属性来做到这一点。

停止所有声音:(您的循环没有错误,但我个人认为forEach 更具可读性。)

this.playList.forEach( el =>  
  if ( ! el.paused ) 
    el.pause();
  
);

您也可以对所有这些都调用pause()。 docs 状态

如果媒体已经处于暂停状态,此方法将无效。

this.playList.forEach( el => el.pause() );

恢复中

为了从您上次停止播放的位置恢复播放列表,您需要知道您上次播放的是哪一首曲目。我不确定您是否可以通过检查元素的属性来弄清楚这一点,但您绝对可以将这些信息存储在您的类中。

在您的构造函数中,您可以为播放列表中的每个元素添加一个事件侦听器。这会将您的类的 playingTrack 属性更新为最后播放的元素。

this.playList.forEach( el => el.addEventListener('play', 
  this.playingTrack = el;
));

现在你的重启函数不需要循环遍历数组了。它只需要播放该曲目。

this.playingTrack?.play();

大概在你开始播放第一首曲目之前你不会调用这个函数,但为了安全起见,我使用optional chaining 运算符。

【讨论】:

非常感谢,我自己设法找到了一个解决方案,但是这个更优雅,需要的代码也少得多,这使它比我的更聪明。

以上是关于如何在游戏状态为暂停时停止游戏的播放列表,并在游戏完成暂停状态后重新播放? JavaScript的主要内容,如果未能解决你的问题,请参考以下文章

游戏从后台快速恢复后退出暂停状态

如何停止或暂停 SKAction 播放音乐? - 斯威夫特

当用户单击主页按钮时暂停 iOS 应用程序游戏

如何捕捉 SKScene 暂停或 audioEngine 停止的时刻?

使用 SpriteKit 时如何暂停声音

Spritekit - 在 didBecomeActive 时保持游戏暂停