(enhance) 効果音の音量を設定可能に

This commit is contained in:
kakkokari-gtyih 2024-01-08 18:12:34 +09:00
parent accee5dfc8
commit 86d2280182
4 changed files with 36 additions and 9 deletions

1
locales/index.d.ts vendored
View File

@ -1193,6 +1193,7 @@ export interface Locale {
"addMfmFunction": string;
"enableQuickAddMfmFunction": string;
"bubbleGame": string;
"sfx": string;
"_announcement": {
"forExistingUsers": string;
"forExistingUsersDescription": string;

View File

@ -1190,6 +1190,7 @@ decorate: "デコる"
addMfmFunction: "装飾を追加"
enableQuickAddMfmFunction: "高度なMFMのピッカーを表示する"
bubbleGame: "バブルゲーム"
sfx: "効果音"
_announcement:
forExistingUsers: "既存ユーザーのみ"

View File

@ -109,9 +109,14 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
<div v-if="showConfig" :class="$style.frame">
<div :class="$style.frameInner">
<MkRange v-model="bgmVolume" :min="0" :max="1" :step="0.0025" :textConverter="(v) => `${Math.floor(v * 100)}%`" :continuousUpdate="true">
<template #label>BGM {{ i18n.ts.volume }}</template>
</MkRange>
<div class="_gaps">
<MkRange v-model="bgmVolume" :min="0" :max="1" :step="0.0025" :textConverter="(v) => `${Math.floor(v * 100)}%`" :continuousUpdate="true">
<template #label>BGM {{ i18n.ts.volume }}</template>
</MkRange>
<MkRange v-model="sfxVolume" :min="0" :max="1" :step="0.0025" :textConverter="(v) => `${Math.floor(v * 100)}%`" :continuousUpdate="true">
<template #label>{{ i18n.ts.sfx }} {{ i18n.ts.volume }}</template>
</MkRange>
</div>
</div>
</div>
<div v-if="showConfig" :class="$style.frame">
@ -398,7 +403,8 @@ const gameOver = ref(false);
const gameStarted = ref(false);
const highScore = ref<number | null>(null);
const showConfig = ref(false);
const bgmVolume = ref(0.1);
const bgmVolume = ref(0.25);
const sfxVolume = ref(1);
let game: DropAndFusionGame;
let containerElRect: DOMRect | null = null;
@ -528,6 +534,7 @@ async function start() {
width: GAME_WIDTH,
height: GAME_HEIGHT,
canvas: canvasEl.value!,
sfxVolume: sfxVolume.value,
...(
gameMode.value === 'normal' ? {
monoDefinitions: NORAML_MONOS,
@ -560,6 +567,13 @@ watch(bgmVolume, (value) => {
}
});
watch(sfxVolume, (value) => {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (game) {
game.setSfxVolume(value);
}
});
function getGameImageDriveFile() {
return new Promise<Misskey.entities.DriveFile | null>(res => {
const dcanvas = document.createElement('canvas');
@ -700,7 +714,7 @@ definePageMetadata({
border-radius: 10px;
}
.frameInner {
padding: 4px 8px;
padding: 8px;
background: #F1E8DC;
box-shadow: 0 0 2px 1px #ce8a5c, inset 0 0 1px 1px #693410;
border-radius: 6px;

View File

@ -48,6 +48,8 @@ export class DropAndFusionGame extends EventEmitter<{
private monoTextures: Record<string, Blob> = {};
private monoTextureUrls: Record<string, string> = {};
private sfxVolume = 1;
/**
*
*/
@ -84,6 +86,7 @@ export class DropAndFusionGame extends EventEmitter<{
width: number;
height: number;
monoDefinitions: Mono[];
sfxVolume?: number;
}) {
super();
@ -91,6 +94,10 @@ export class DropAndFusionGame extends EventEmitter<{
this.gameHeight = opts.height;
this.monoDefinitions = opts.monoDefinitions;
if (opts.sfxVolume) {
this.sfxVolume = opts.sfxVolume;
}
this.engine = Matter.Engine.create({
constraintIterations: 2 * PHYSICS_QUALITY_FACTOR,
positionIterations: 6 * PHYSICS_QUALITY_FACTOR,
@ -225,7 +232,7 @@ export class DropAndFusionGame extends EventEmitter<{
// TODO: 効果音再生はコンポーネント側の責務なので移動する
const pan = ((newX / this.gameWidth) - 0.5) * 2;
sound.playUrl('/client-assets/drop-and-fusion/bubble2.mp3', 1, pan, nextMono.sfxPitch);
sound.playUrl('/client-assets/drop-and-fusion/bubble2.mp3', this.sfxVolume, pan, nextMono.sfxPitch);
this.emit('monoAdded', nextMono);
this.emit('fusioned', newX, newY, additionalScore);
@ -238,7 +245,7 @@ export class DropAndFusionGame extends EventEmitter<{
//}
//sound.playUrl({
// type: 'syuilo/bubble2',
// volume: 1,
// volume: this.sfxVolume,
//});
}
}
@ -324,7 +331,7 @@ export class DropAndFusionGame extends EventEmitter<{
const energy = pairs.collision.depth;
if (energy > minCollisionEnergyForSound) {
// TODO: 効果音再生はコンポーネント側の責務なので移動する
const vol = (Math.min(maxCollisionEnergyForSound, energy - minCollisionEnergyForSound) / maxCollisionEnergyForSound) / 4;
const vol = (Math.min(maxCollisionEnergyForSound, energy - minCollisionEnergyForSound) / maxCollisionEnergyForSound) / 4 * this.sfxVolume;
const pan = ((((bodyA.position.x + bodyB.position.x) / 2) / this.gameWidth) - 0.5) * 2;
const pitch = soundPitchMin + ((soundPitchMax - soundPitchMin) * (1 - (Math.min(10, energy) / 10)));
sound.playUrl('/client-assets/drop-and-fusion/poi1.mp3', vol, pan, pitch);
@ -345,6 +352,10 @@ export class DropAndFusionGame extends EventEmitter<{
this.loaded = true;
}
public setSfxVolume(volume: number) {
this.sfxVolume = volume;
}
public getTextureImageUrl(mono: Mono) {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (this.monoTextureUrls[mono.img]) {
@ -388,7 +399,7 @@ export class DropAndFusionGame extends EventEmitter<{
// TODO: 効果音再生はコンポーネント側の責務なので移動する
const pan = ((x / this.gameWidth) - 0.5) * 2;
sound.playUrl('/client-assets/drop-and-fusion/poi2.mp3', 1, pan);
sound.playUrl('/client-assets/drop-and-fusion/poi2.mp3', this.sfxVolume, pan);
}
public dispose() {