mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-08-17 05:34:37 +00:00
Implement a "ka-ching" sound effect on kill (#2097)
## Description: Building off of [this PR](https://github.com/openfrontio/OpenFrontIO/pull/2090) which implemented music, I extend this functionality to add sound effects. Diff will be reduced if and when that PR gets merged! I think the game would benefit from more sound effects, and adding a "ka-ching" sound effect on kill seems like an easy place to start. The ka-ching sound effect was found [here](https://freesound.org/people/AKkingStudio/sounds/684165/) and is licensed under Creative Commons. ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced Demo video with sound: https://github.com/user-attachments/assets/18c857a4-a741-492a-bbc1-68d4f3ba38da ## Please put your Discord username so you can be contacted if a bug or regression is found: basedgob --------- Co-authored-by: icslucas <carolinacarazolli@gmail.com>
This commit is contained in:
co-authored by
icslucas
parent
ed062c9dbc
commit
5b36c02ff0
@@ -380,7 +380,8 @@
|
|||||||
"terrain_disabled": "Terrain view disabled",
|
"terrain_disabled": "Terrain view disabled",
|
||||||
"exit_game_label": "Exit Game",
|
"exit_game_label": "Exit Game",
|
||||||
"exit_game_info": "Return to main menu",
|
"exit_game_info": "Return to main menu",
|
||||||
"background_music_volume": "Background Music Volume"
|
"background_music_volume": "Background Music Volume",
|
||||||
|
"sound_effects_volume": "Sound Effects Volume"
|
||||||
},
|
},
|
||||||
"chat": {
|
"chat": {
|
||||||
"title": "Quick Chat",
|
"title": "Quick Chat",
|
||||||
|
|||||||
Binary file not shown.
@@ -7,6 +7,7 @@ import {
|
|||||||
RailroadUpdate,
|
RailroadUpdate,
|
||||||
} from "../../../core/game/GameUpdates";
|
} from "../../../core/game/GameUpdates";
|
||||||
import { GameView, UnitView } from "../../../core/game/GameView";
|
import { GameView, UnitView } from "../../../core/game/GameView";
|
||||||
|
import SoundManager, { SoundEffect } from "../../sound/SoundManager";
|
||||||
import { renderNumber } from "../../Utils";
|
import { renderNumber } from "../../Utils";
|
||||||
import { AnimatedSpriteLoader } from "../AnimatedSpriteLoader";
|
import { AnimatedSpriteLoader } from "../AnimatedSpriteLoader";
|
||||||
import { conquestFxFactory } from "../fx/ConquestFx";
|
import { conquestFxFactory } from "../fx/ConquestFx";
|
||||||
@@ -216,6 +217,8 @@ export class FxLayer implements Layer {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SoundManager.playSoundEffect(SoundEffect.KaChing);
|
||||||
|
|
||||||
const conquestFx = conquestFxFactory(
|
const conquestFx = conquestFxFactory(
|
||||||
this.animatedSpriteLoader,
|
this.animatedSpriteLoader,
|
||||||
conquest,
|
conquest,
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ export class SettingsModal extends LitElement implements Layer {
|
|||||||
SoundManager.setBackgroundMusicVolume(
|
SoundManager.setBackgroundMusicVolume(
|
||||||
this.userSettings.backgroundMusicVolume(),
|
this.userSettings.backgroundMusicVolume(),
|
||||||
);
|
);
|
||||||
|
SoundManager.setSoundEffectsVolume(this.userSettings.soundEffectsVolume());
|
||||||
this.eventBus.on(ShowSettingsModalEvent, (event) => {
|
this.eventBus.on(ShowSettingsModalEvent, (event) => {
|
||||||
this.isVisible = event.isVisible;
|
this.isVisible = event.isVisible;
|
||||||
this.shouldPause = event.shouldPause;
|
this.shouldPause = event.shouldPause;
|
||||||
@@ -162,6 +163,13 @@ export class SettingsModal extends LitElement implements Layer {
|
|||||||
this.requestUpdate();
|
this.requestUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private onSoundEffectsVolumeChange(event: Event) {
|
||||||
|
const volume = parseFloat((event.target as HTMLInputElement).value) / 100;
|
||||||
|
this.userSettings.setSoundEffectsVolume(volume);
|
||||||
|
SoundManager.setSoundEffectsVolume(volume);
|
||||||
|
this.requestUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!this.isVisible) {
|
if (!this.isVisible) {
|
||||||
return null;
|
return null;
|
||||||
@@ -221,6 +229,33 @@ export class SettingsModal extends LitElement implements Layer {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="flex gap-3 items-center w-full text-left p-3 hover:bg-slate-700 rounded text-white transition-colors"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src=${musicIcon}
|
||||||
|
alt="soundEffectsIcon"
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
/>
|
||||||
|
<div class="flex-1">
|
||||||
|
<div class="font-medium">
|
||||||
|
${translateText("user_setting.sound_effects_volume")}
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="range"
|
||||||
|
min="0"
|
||||||
|
max="100"
|
||||||
|
.value=${this.userSettings.soundEffectsVolume() * 100}
|
||||||
|
@input=${this.onSoundEffectsVolumeChange}
|
||||||
|
class="w-full border border-slate-500 rounded-lg"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="text-sm text-slate-400">
|
||||||
|
${Math.round(this.userSettings.soundEffectsVolume() * 100)}%
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="flex gap-3 items-center w-full text-left p-3 hover:bg-slate-700 rounded text-white transition-colors"
|
class="flex gap-3 items-center w-full text-left p-3 hover:bg-slate-700 rounded text-white transition-colors"
|
||||||
@click="${this.onTerrainButtonClick}"
|
@click="${this.onTerrainButtonClick}"
|
||||||
|
|||||||
@@ -1,22 +1,42 @@
|
|||||||
import { Howl, Howler } from "howler";
|
import { Howl } from "howler";
|
||||||
import of4 from "../../../proprietary/sounds/music/of4.mp3";
|
import of4 from "../../../proprietary/sounds/music/of4.mp3";
|
||||||
import openfront from "../../../proprietary/sounds/music/openfront.mp3";
|
import openfront from "../../../proprietary/sounds/music/openfront.mp3";
|
||||||
import war from "../../../proprietary/sounds/music/war.mp3";
|
import war from "../../../proprietary/sounds/music/war.mp3";
|
||||||
|
import kaChingSound from "../../../resources/sounds/effects/ka-ching.mp3";
|
||||||
|
|
||||||
|
export enum SoundEffect {
|
||||||
|
KaChing = "ka-ching",
|
||||||
|
}
|
||||||
|
|
||||||
class SoundManager {
|
class SoundManager {
|
||||||
private backgroundMusic: Howl[] = [];
|
private backgroundMusic: Howl[] = [];
|
||||||
private currentTrack: number = 0;
|
private currentTrack: number = 0;
|
||||||
|
private soundEffects: Map<SoundEffect, Howl> = new Map();
|
||||||
|
private soundEffectsVolume: number = 1;
|
||||||
|
private backgroundMusicVolume: number = 0;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.backgroundMusic = [
|
this.backgroundMusic = [
|
||||||
new Howl({ src: [of4], loop: false, onend: this.playNext.bind(this) }),
|
new Howl({
|
||||||
|
src: [of4],
|
||||||
|
loop: false,
|
||||||
|
onend: this.playNext.bind(this),
|
||||||
|
volume: 0,
|
||||||
|
}),
|
||||||
new Howl({
|
new Howl({
|
||||||
src: [openfront],
|
src: [openfront],
|
||||||
loop: false,
|
loop: false,
|
||||||
onend: this.playNext.bind(this),
|
onend: this.playNext.bind(this),
|
||||||
|
volume: 0,
|
||||||
|
}),
|
||||||
|
new Howl({
|
||||||
|
src: [war],
|
||||||
|
loop: false,
|
||||||
|
onend: this.playNext.bind(this),
|
||||||
|
volume: 0,
|
||||||
}),
|
}),
|
||||||
new Howl({ src: [war], loop: false, onend: this.playNext.bind(this) }),
|
|
||||||
];
|
];
|
||||||
this.setBackgroundMusicVolume(0);
|
this.loadSoundEffect(SoundEffect.KaChing, kaChingSound);
|
||||||
}
|
}
|
||||||
|
|
||||||
public playBackgroundMusic(): void {
|
public playBackgroundMusic(): void {
|
||||||
@@ -35,14 +55,55 @@ class SoundManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public setBackgroundMusicVolume(volume: number): void {
|
public setBackgroundMusicVolume(volume: number): void {
|
||||||
const newVolume = Math.max(0, Math.min(1, volume));
|
this.backgroundMusicVolume = Math.max(0, Math.min(1, volume));
|
||||||
Howler.volume(newVolume);
|
this.backgroundMusic.forEach((track) => {
|
||||||
|
track.volume(this.backgroundMusicVolume);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private playNext(): void {
|
private playNext(): void {
|
||||||
this.currentTrack = (this.currentTrack + 1) % this.backgroundMusic.length;
|
this.currentTrack = (this.currentTrack + 1) % this.backgroundMusic.length;
|
||||||
this.playBackgroundMusic();
|
this.playBackgroundMusic();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public loadSoundEffect(name: SoundEffect, src: string): void {
|
||||||
|
if (!this.soundEffects.has(name)) {
|
||||||
|
const sound = new Howl({
|
||||||
|
src: [src],
|
||||||
|
volume: this.soundEffectsVolume,
|
||||||
|
});
|
||||||
|
this.soundEffects.set(name, sound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public playSoundEffect(name: SoundEffect): void {
|
||||||
|
const sound = this.soundEffects.get(name);
|
||||||
|
if (sound) {
|
||||||
|
sound.play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public setSoundEffectsVolume(volume: number): void {
|
||||||
|
this.soundEffectsVolume = Math.max(0, Math.min(1, volume));
|
||||||
|
this.soundEffects.forEach((sound) => {
|
||||||
|
sound.volume(this.soundEffectsVolume);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public stopSoundEffect(name: SoundEffect): void {
|
||||||
|
const sound = this.soundEffects.get(name);
|
||||||
|
if (sound) {
|
||||||
|
sound.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public unloadSoundEffect(name: SoundEffect): void {
|
||||||
|
const sound = this.soundEffects.get(name);
|
||||||
|
if (sound) {
|
||||||
|
sound.unload();
|
||||||
|
this.soundEffects.delete(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new SoundManager();
|
export default new SoundManager();
|
||||||
|
|||||||
@@ -176,4 +176,12 @@ export class UserSettings {
|
|||||||
setBackgroundMusicVolume(volume: number): void {
|
setBackgroundMusicVolume(volume: number): void {
|
||||||
this.setFloat("settings.backgroundMusicVolume", volume);
|
this.setFloat("settings.backgroundMusicVolume", volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
soundEffectsVolume(): number {
|
||||||
|
return this.getFloat("settings.soundEffectsVolume", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
setSoundEffectsVolume(volume: number): void {
|
||||||
|
this.setFloat("settings.soundEffectsVolume", volume);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user