我正在try 将点击按钮时播放的声音随机化,但我也想跳过最后播放的声音.例如,如果Sfx4将连续播放四次,这听起来就不自然了.我想总是播放一种新的声音(当然是在这5种声音中).我做错了什么?如果可能的话,给我一些关于如何实施它的 idea .

<template>
    <button class="book__nav-btn" @click="playTurnSfx">
        <slot> </slot>
    </button>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue';
import Sfx1 from '@/assets/sounds/page-turn-1.mp3?url';
import Sfx2 from '@/assets/sounds/page-turn-2.mp3?url';
import Sfx3 from '@/assets/sounds/page-turn-3.mp3?url';
import Sfx4 from '@/assets/sounds/page-turn-4.mp3?url';
import Sfx5 from '@/assets/sounds/page-turn-5.mp3?url';

const sounds = [Sfx1, Sfx2, Sfx3, Sfx4, Sfx5];
const lastPlayedIndex = ref(null);
let playableSounds = sounds.toSpliced(lastPlayedIndex.value, 1);
const randomIndex = computed(() => {
    return Math.floor(Math.random() * playableSounds.length);
});

const playTurnSfx = () => {
    const sound = new Audio(sounds[randomIndex.value]);
    sound.volume = 0.1;
    sound.play();
};
</script>

推荐答案

您始终可以跟踪最新的值,将其从数组中筛选出来(别担心,原始数组不会更改,您将通过Filter获得数组的副本,但不会有与您的条件不匹配的项),并随机化结果:

let sounds = ['a', 'b', 'c', 'd', 'e'];
let previous = -1;

function randomize() {
    let randIndex = parseInt(Math.random() * (sounds.length - ((sounds.indexOf(previous) >= 0) ? 1 : 0)));
    console.log(previous = sounds.filter(item => (item !== previous))[randIndex]);
}
<input type="button" value="randomize" onclick="randomize()">

编辑

查看了问题的第二个编辑中的try ,以下是我是如何工作的(我忽略了声音播放,我们需要修复决定播放哪种声音的逻辑,所以在这里可以安全地断定播放声音有效):

const sounds = ['Sfx1', 'Sfx2', 'Sfx3', 'Sfx4', 'Sfx5'];
let previous = null;

const getRand = () => {
    const filteredSounds = sounds.filter(item => item !== previous);
    return filteredSounds[Math.floor(Math.random() * filteredSounds.length)];
};

const playSfx = () => {
    //const sound = new Audio(sounds[randIndex]);
    //sound.volume = 0.1;
    //sound.play();
    previous = getRand();
    console.log(previous);
};

for (let i = 0; i < 20; i++) playSfx();

你在try 应用这个 idea 时犯的逻辑错误是,在正确地过滤你的数组并获得一个随机索引之后,你从未过滤的数组而不是过滤的数组中获得与随机索引相对应的声音.

例如,如果previousSfx2,那么您的筛选器会得到一个类似[Sfx1, Sfx3, Sfx4, Sfx5]的数组,但初始数组仍然是[Sfx1, Sfx2, Sfx3, Sfx4, Sfx5],所以如果您得到一个介于0..3之间的随机整数,恰好是1,那么filteredSounds[1]将是Sfx3,这与previous不同,在这个场景中,previousSfx2,而sounds[1]仍然是Sfx2,因此您需要获得随机索引filteredSounds的值,而不是未筛选的sounds.

Javascript相关问答推荐

使用JavaScript单击上一个或下一个特定按钮创建卡滑动器以滑动单个卡

如何在不创建新键的情况下动态更改 map 中的项目?

将现场录音发送到后端

MathJax可以导入本地HTML文档使用的JS文件吗?

你怎么看啦啦队的回应?

我怎么才能得到Kotlin的密文?

保持物品顺序的可变大小物品分配到平衡组的算法

S文本内容和值不必要的不同

使用原型判断对象是否为类的实例

我在Django中的视图中遇到多值键错误

为什么123[';toString';].long返回1?

使用getBorbingClientRect()更改绝对元素位置

在使用REACT更改了CSS类之后,无法更改CSS样式

TypeError:无法读取未定义的属性(正在读取';宽度';)

当标题被点击时,如何使内容出现在另一个div上?

在JS/TS中将复杂图形转换为数组或其他数据 struct

如何修复使用axios运行TSC index.ts时出现的错误?

Jexl to LowerCase()和Replace()

如何使用puppeteer操作所有选项

如何按区域进行过滤并将其从结果数组中删除?