Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added src/assets/audio/SFX/bell.mp3
Binary file not shown.
Binary file modified src/assets/audio/SFX/cutting.mp3
Binary file not shown.
Binary file added src/assets/audio/SFX/fire-out.mp3
Binary file not shown.
Binary file added src/assets/audio/SFX/fire-start.mp3
Binary file not shown.
Binary file added src/assets/audio/SFX/fire.mp3
Binary file not shown.
Binary file modified src/assets/audio/SFX/ingredient.mp3
Binary file not shown.
Binary file added src/assets/audio/SFX/put-down.mp3
Binary file not shown.
Binary file added src/assets/audio/soundtrack/high-heat.mp3
Binary file not shown.
Binary file added src/assets/audio/soundtrack/low-heat.mp3
Binary file not shown.
63 changes: 63 additions & 0 deletions src/audio/audioListener.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { on } from "../core/gameEvents.js";
import { playSound } from "./audioManager.js";
import { INGREDIENTS } from "../data/items.js";

on("cut_complete", () => {
playSound("cutting");
});

on("crush_complete", () => {
playSound("crushing");
});

on("cauldron_start", () => {
playSound("fireOn");
});

on("cauldron_done", () => {
playSound("fireOff");
});

on("delivered", () => {
playSound("bell");
});

on("trash", () => {
playSound("trash");
});

on("ingredient_pickup", (ing) => {
switch (ing) {
case INGREDIENTS.Vinum:
case INGREDIENTS.Oleum:
case INGREDIENTS.Aqua:
playSound("base");
break;

default:
playSound("ingredient");
break;
}
});

on("place", () => {
playSound("place");
});

on("glass_pickup", () => {
playSound("glass");
});

on("new_order", () => {
playSound("newOrder");
});

on("bottle_potion", (result) => {
const overbrewed = result & ((1 << 28) | (1 << 30));

if (overbrewed) {
playSound("overbrewedFx");
} else {
playSound("bottling");
}
});
30 changes: 27 additions & 3 deletions src/audio/audioManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,29 @@ export function playSound(name) {
sound.play().catch(() => {});
}

let activeMusicName = null;

export function playMusic(name) {
if (activeMusicName === name && activeMusicName !== "menu") return;
const newMusic = music[name];

if (!newMusic) return;

// already playing
if (activeMusic === newMusic) return;

// stop previous
if (activeMusic) {
activeMusic.pause();
activeMusic.currentTime = 0;
}

activeMusic = newMusic;
activeMusicName = name;

activeMusic.volume = settings.musicVolume;
activeMusic.loop = true;

activeMusic.play().catch(() => {});

console.log("Music Playing!");
}

export function stopMusic() {
Expand All @@ -45,6 +48,27 @@ export function stopMusic() {
activeMusic.currentTime = 0;

activeMusic = null;
activeMusicName = null;

currentPhase = "low";
}

let currentPhase = "low";

export function updateGameplayMusic(heat) {
if (heat >= 2 && currentPhase === "low") {
currentPhase = "high";

playMusic("high");
}
}

export function isGameplayMusicPlaying() {
return activeMusicName === "low" || activeMusicName === "high";
}

export function resetGameplayMusic() {
currentPhase = "low";
}

export function updateMusicVolume() {
Expand Down
13 changes: 9 additions & 4 deletions src/audio/music.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import menuMusicFile from "../assets/audio/soundtrack/3_main-menu.mp3";
import gameMusicFile from "../assets/audio/soundtrack/3_gameplay.mp3";
import lowHeatMusicFile from "../assets/audio/soundtrack/low-heat.mp3";
import highHeatMusicFile from "../assets/audio/soundtrack/high-heat.mp3";

const menuMusic = new Audio(menuMusicFile);
menuMusic.loop = true;

const gameMusic = new Audio(gameMusicFile);
gameMusic.loop = true;
const lowHeat = new Audio(lowHeatMusicFile);
lowHeat.loop = true;

const highHeat = new Audio(highHeatMusicFile);
highHeat.loop = true;

const music = {
menu: menuMusic,
game: gameMusic,
low: lowHeat,
high: highHeat,
};

export default music;
12 changes: 9 additions & 3 deletions src/audio/sound.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ import baseFx from "../assets/audio/SFX/base.wav";
import bottlingFx from "../assets/audio/SFX/bottling.wav";
import overbrewedFx from "../assets/audio/SFX/bottling-overbrewed.wav";
import crushingFx from "../assets/audio/SFX/crushing.wav";
import cuttingFx from "../assets/audio/SFX/cutting.wav";
import cuttingFx from "../assets/audio/SFX/cutting.mp3";
import glassFx from "../assets/audio/SFX/glass.wav";
import ingredientFx from "../assets/audio/SFX/ingredient.wav";
import ingredientFx from "../assets/audio/SFX/ingredient.mp3";
import newOrderFx from "../assets/audio/SFX/new-order.wav";
import placeFx from "../assets/audio/SFX/place.wav";
import placeFx from "../assets/audio/SFX/put-down.mp3";
import trashFx from "../assets/audio/SFX/trash.wav";
import fireStart from "../assets/audio/SFX/fire-start.mp3";
import fireOut from "../assets/audio/SFX/fire-out.mp3";
import bellFx from "../assets/audio/SFX/bell.mp3";

const sounds = {
base: new Audio(baseFx),
Expand All @@ -20,6 +23,9 @@ const sounds = {
newOrder: new Audio(newOrderFx),
place: new Audio(placeFx),
trash: new Audio(trashFx),
fireOn: new Audio(fireStart),
fireOff: new Audio(fireOut),
bell: new Audio(bellFx),
};

export default sounds;
17 changes: 17 additions & 0 deletions src/core/gameEvents.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const listeners = {};

export function on(event, callback) {
if (!listeners[event]) {
listeners[event] = [];
}

listeners[event].push(callback);
}

export function emit(event, data = null) {
if (!listeners[event]) return;

listeners[event].forEach((callback) => {
callback(data);
});
}
17 changes: 15 additions & 2 deletions src/core/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,13 @@ import {
import { drawGameOver } from "../rendering/gameOverRenderer.js";
import { drawHUD } from "../rendering/hudRendering.js";
import { drawRecipesMenu } from "../rendering/recipesRenderer.js";
import { playMusic, updateMusicVolume } from "../audio/audioManager.js";
import {
isGameplayMusicPlaying,
playMusic,
updateMusicVolume,
stopMusic,
} from "../audio/audioManager.js";
import "../audio/audioListener.js";

const { canvas, ctx } = Canvas();

Expand Down Expand Up @@ -196,8 +202,15 @@ function loop() {
case GAME_STATES.MENU:
playMusic("menu");
break;

case GAME_STATES.PLAYING:
playMusic("game");
if (!isGameplayMusicPlaying()) {
playMusic("low");
}
break;

case GAME_STATES.GAME_OVER:
stopMusic();
break;
}
}
Expand Down
10 changes: 10 additions & 0 deletions src/data/gameData.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import {
resetGameplayMusic,
updateGameplayMusic,
} from "../audio/audioManager.js";
import { emit } from "../core/gameEvents.js";

const gameData = {
essence: 0,
heat: 1,
Expand Down Expand Up @@ -25,6 +31,7 @@ function callHeatListeners() {
function increaseHeat() {
if (gameData.heat >= defaultState.maxHeat) return;
gameData.heat++;
updateGameplayMusic(gameData.heat);
callHeatListeners();
}

Expand All @@ -40,13 +47,15 @@ function makeDelivery() {

function addOrder(recipe) {
if (activeOrders.length > 2) return;

activeOrders.push({
recipe: recipe.recipe,
timeRemaining:
currentState.baseTime * defaultState.orderDurationRatio * recipe.count,
maxTime:
currentState.baseTime * defaultState.orderDurationRatio * recipe.count,
});
emit("new_order");
}

const defaultState = Object.freeze({
Expand All @@ -70,6 +79,7 @@ function resetState() {
gameData.essence = 0;
gameData.heat = 1;
currentState.ordersFullfilled = 0;
resetGameplayMusic();

heatListeners.length = 0;
attachHeatListener((heatLevel) => {
Expand Down
2 changes: 1 addition & 1 deletion src/data/settings.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const settings = {
musicVolume: 0.0,
musicVolume: 0.4,
sfxVolume: 0.5,
};

Expand Down
21 changes: 20 additions & 1 deletion src/entities/station.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import {
addOrder,
makeDelivery,
} from "../data/gameData.js";
import { emit } from "../core/gameEvents.js";
import { CUT } from "../data/items.js";

// Is this a valid ingredient for the task
const canAction = (ing) => {
Expand Down Expand Up @@ -42,6 +44,8 @@ class Station {
this.startWorking = (baseTime) => {
this._work_lock = true;
this.duration = Math.ceil(baseTime * defaultState.stationRatio);
//Event
emit(action === CUT ? "cut_complete" : "crush_complete");
};

this.doWork = (timeStep) => {
Expand All @@ -62,6 +66,7 @@ class Station {
this.inventory === 0;

this.place = (playerInv) => {
emit("place");
this.inventory = playerInv.ingredient;
playerInv.ingredient = 0;
};
Expand All @@ -73,6 +78,7 @@ class Station {
!playerInv.hasGlass();

this.take = (playerInv) => {
emit("ingredient_pickup", playerInv.ingredient);
playerInv.ingredient = this.inventory;
this.inventory = 0;
this.duration = 0;
Expand All @@ -97,6 +103,7 @@ class DeliveryStation {
);

if (orderIndex !== -1) {
emit("delivered");
activeOrders.splice(orderIndex, 1);
makeDelivery();
} else {
Expand All @@ -116,11 +123,16 @@ class Ingredient {
constructor(ing) {
this.inventory = ing;
this.canPlace = (playerInv) => playerInv.ingredient === this.inventory;
this.place = (playerInv) => (playerInv.ingredient = 0);
this.place = (playerInv) => {
playerInv.ingredient = 0;
emit("place");
};

this.canTake = (playerInv) => playerInv.empty();
this.take = (playerInv) => {
playerInv.ingredient = this.inventory;

emit("ingredient_pickup", playerInv.ingredient);
};
}
}
Expand All @@ -133,6 +145,7 @@ class Glass {

this.canTake = (playerInv) => playerInv.empty();
this.take = (playerInv) => {
emit("glass_pickup");
playerInv.glass = this.inventory;
};
}
Expand Down Expand Up @@ -177,6 +190,8 @@ class Cauldron {
this.inventory |= playerInv.ingredient;
playerInv.ingredient = 0;
this.itemCount++;

emit("place");
};

this.canTake = (playerInv) =>
Expand All @@ -190,12 +205,15 @@ class Cauldron {
this.inventory = 0;
this.progress = this.duration = 0;
this.itemCount = 0;
emit("cauldron_done");
emit("bottle_potion", playerInv.glass);
};

this.canWork = () =>
this.duration === 0 && this._get_base(this.inventory) !== 0;

this.startWorking = (baseTime) => {
emit("cauldron_start");
this.duration = baseTime * defaultState.cookRatio;
this._first_brew = true;
};
Expand Down Expand Up @@ -249,6 +267,7 @@ class TrashCan {
this.canPlace = () => true;

this.place = (playerInv) => {
emit("trash");
playerInv.ingredient = 0;
playerInv.glass = 0;
};
Expand Down