Add sounds

This commit is contained in:
sepia 2025-07-28 21:34:23 -05:00
parent f60718e8fd
commit 51b701663d
8 changed files with 84 additions and 3 deletions

View File

@ -52,6 +52,7 @@
<script src="scripts/profile-editor.js"></script>
<script src="scripts/copy-game-link.js"></script>
<script src="scripts/handle-redirects.js"></script>
<script src="scripts/make-sounds.js"></script>
</div>
</body>
</html>

22
public/scripts/make-sounds.js Executable file
View File

@ -0,0 +1,22 @@
const sounds = {};
sounds['victory'] = new Audio('/sounds/victory.ogg');
sounds['defeat'] = new Audio('/sounds/defeat.ogg');
sounds['draw'] = new Audio('/sounds/draw.ogg');
sounds['move'] = new Audio('/sounds/move.ogg');
Object.values(sounds).forEach((sound) => {
sound.volume = 0.12;
});
document.addEventListener('htmx:wsAfterMessage', function (e) {
let msg;
try {
msg = JSON.parse(e.detail.message);
} catch (_) {
return;
}
if (msg.type !== 'sound') {
return;
}
sounds[msg.sound].play();
});

BIN
public/sounds/defeat.ogg Executable file

Binary file not shown.

BIN
public/sounds/draw.ogg Executable file

Binary file not shown.

BIN
public/sounds/move.ogg Executable file

Binary file not shown.

BIN
public/sounds/victory.ogg Executable file

Binary file not shown.

View File

@ -3,9 +3,10 @@ import { html } from '@elysiajs/html';
import { staticPlugin } from '@elysiajs/static';
import { cookie } from '@elysiajs/cookie';
import { WebSocketHandler } from './web-socket-handler';
import { GomokuGame } from './game/game-instance';
import { ElysiaWS } from 'elysia/dist/ws';
const wsHandler = new WebSocketHandler();
export type WS = ElysiaWS<{ query: { playerId: string; gameId: string } }>;
const app = new Elysia()
.use(

View File

@ -13,8 +13,7 @@ import {
UpdateDisplayNameMessage,
} from './messages';
import { v4 as uuidv4 } from 'uuid';
type WS = ElysiaWS<{ query: { playerId: string; gameId: string } }>;
import { WS } from '.';
class PlayerConnection {
id: string;
@ -107,6 +106,19 @@ class GameServer {
);
}
public broadcastSound(sound: string) {
this.connections.forEach((conn: PlayerConnection) =>
this.broadcastSoundToPlayer(conn, sound),
);
}
public broadcastSoundToPlayer(conn: PlayerConnection, sound: string) {
conn.ws.send({
type: 'sound',
sound: sound,
});
}
public broadcastBoardToPlayer(conn: PlayerConnection) {
const isToPlay =
this.gomoku.currentPlayerColor == this.getPlayerColor(conn);
@ -430,6 +442,39 @@ class GameServer {
if (stateBeforeMove != this.gomoku.status) {
this.broadcastButtons();
}
// Broadcast sounds
if (this.gomoku.status === 'playing') {
this.broadcastSound('move');
} else {
const whiteConn = this.whitePlayerId
? this.connections.get(this.whitePlayerId)
: null;
const blackConn = this.blackPlayerId
? this.connections.get(this.blackPlayerId)
: null;
switch (this.gomoku.winnerColor) {
case 'draw':
this.broadcastSound('draw');
case 'white':
if (whiteConn) {
this.broadcastSoundToPlayer(whiteConn, 'victory');
}
if (blackConn) {
this.broadcastSoundToPlayer(blackConn, 'defeat');
}
break;
case 'black':
if (whiteConn) {
this.broadcastSoundToPlayer(whiteConn, 'defeat');
}
if (blackConn) {
this.broadcastSoundToPlayer(blackConn, 'victory');
}
break;
}
}
console.log(
`Move made in game ${this.id} by ${conn.id}: (${row}, ${col})`,
);
@ -461,6 +506,17 @@ class GameServer {
this.broadcastBoard();
this.broadcastTitle();
this.broadcastButtons();
this.broadcastSoundToPlayer(conn, 'defeat');
const otherPlayerId =
resigningPlayerColor === 'white'
? this.blackPlayerId
: this.whitePlayerId;
if (otherPlayerId) {
const otherPlayer = this.connections.get(otherPlayerId);
if (otherPlayer) {
this.broadcastSoundToPlayer(otherPlayer, 'victory');
}
}
console.log(`Player ${conn.id} resigned from game ${this.id}`);
}
@ -634,6 +690,7 @@ class GameServer {
this.broadcastBoard();
this.broadcastButtons();
this.broadcastTitle();
this.broadcastSound('draw');
}
private handleDeclineDraw(): void {