sound when pieces connect

This commit is contained in:
Zutatensuppe 2021-05-29 23:14:19 +02:00
parent 472113ad74
commit 21d7db5677
14 changed files with 75 additions and 8 deletions

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -4,8 +4,8 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>🧩 jigsaw.hyottoko.club</title> <title>🧩 jigsaw.hyottoko.club</title>
<script type="module" crossorigin src="/assets/index.4d785533.js"></script> <script type="module" crossorigin src="/assets/index.d7fe3ee6.js"></script>
<link rel="modulepreload" href="/assets/vendor.b622ee49.js"> <link rel="modulepreload" href="/assets/vendor.18cd2d7e.js">
<link rel="stylesheet" href="/assets/index.f7304069.css"> <link rel="stylesheet" href="/assets/index.f7304069.css">
</head> </head>
<body> <body>

View file

@ -344,6 +344,7 @@ const INPUT_EV_PLAYER_COLOR = 7;
const INPUT_EV_PLAYER_NAME = 8; const INPUT_EV_PLAYER_NAME = 8;
const INPUT_EV_MOVE = 9; const INPUT_EV_MOVE = 9;
const INPUT_EV_TOGGLE_PREVIEW = 10; const INPUT_EV_TOGGLE_PREVIEW = 10;
const INPUT_EV_TOGGLE_SOUNDS = 11;
const CHANGE_DATA = 1; const CHANGE_DATA = 1;
const CHANGE_TILE = 2; const CHANGE_TILE = 2;
const CHANGE_PLAYER = 3; const CHANGE_PLAYER = 3;
@ -366,6 +367,7 @@ var Protocol = {
INPUT_EV_PLAYER_COLOR, INPUT_EV_PLAYER_COLOR,
INPUT_EV_PLAYER_NAME, INPUT_EV_PLAYER_NAME,
INPUT_EV_TOGGLE_PREVIEW, INPUT_EV_TOGGLE_PREVIEW,
INPUT_EV_TOGGLE_SOUNDS,
CHANGE_DATA, CHANGE_DATA,
CHANGE_TILE, CHANGE_TILE,
CHANGE_PLAYER, CHANGE_PLAYER,
@ -871,7 +873,7 @@ const getPuzzleWidth = (gameId) => {
const getPuzzleHeight = (gameId) => { const getPuzzleHeight = (gameId) => {
return GAMES[gameId].puzzle.info.height; return GAMES[gameId].puzzle.info.height;
}; };
function handleInput$1(gameId, playerId, input, ts) { function handleInput$1(gameId, playerId, input, ts, onSnap) {
const puzzle = GAMES[gameId].puzzle; const puzzle = GAMES[gameId].puzzle;
const evtInfo = getEvtInfo(gameId, playerId); const evtInfo = getEvtInfo(gameId, playerId);
const changes = []; const changes = [];
@ -1054,6 +1056,9 @@ function handleInput$1(gameId, playerId, input, ts) {
changeData(gameId, { finished: ts }); changeData(gameId, { finished: ts });
_dataChange(); _dataChange();
} }
if (onSnap) {
onSnap(playerId);
}
} }
else { else {
// Snap to other tiles // Snap to other tiles
@ -1101,6 +1106,9 @@ function handleInput$1(gameId, playerId, input, ts) {
changePlayer(gameId, playerId, { d, ts }); changePlayer(gameId, playerId, { d, ts });
_playerChange(); _playerChange();
} }
if (snapped && onSnap) {
onSnap(playerId);
}
} }
} }
else { else {

View file

@ -530,7 +530,8 @@ function handleInput(
gameId: string, gameId: string,
playerId: string, playerId: string,
input: Input, input: Input,
ts: Timestamp ts: Timestamp,
onSnap?: (playerId: string) => void
): Array<Change> { ): Array<Change> {
const puzzle = GAMES[gameId].puzzle const puzzle = GAMES[gameId].puzzle
const evtInfo = getEvtInfo(gameId, playerId) const evtInfo = getEvtInfo(gameId, playerId)
@ -734,6 +735,9 @@ function handleInput(
changeData(gameId, { finished: ts }) changeData(gameId, { finished: ts })
_dataChange() _dataChange()
} }
if (onSnap) {
onSnap(playerId)
}
} else { } else {
// Snap to other tiles // Snap to other tiles
const check = ( const check = (
@ -789,6 +793,9 @@ function handleInput(
changePlayer(gameId, playerId, { d, ts }) changePlayer(gameId, playerId, { d, ts })
_playerChange() _playerChange()
} }
if (snapped && onSnap) {
onSnap(playerId)
}
} }
} else { } else {
changePlayer(gameId, playerId, { d, ts }) changePlayer(gameId, playerId, { d, ts })

View file

@ -58,6 +58,7 @@ const INPUT_EV_PLAYER_COLOR = 7
const INPUT_EV_PLAYER_NAME = 8 const INPUT_EV_PLAYER_NAME = 8
const INPUT_EV_MOVE = 9 const INPUT_EV_MOVE = 9
const INPUT_EV_TOGGLE_PREVIEW = 10 const INPUT_EV_TOGGLE_PREVIEW = 10
const INPUT_EV_TOGGLE_SOUNDS = 11
const CHANGE_DATA = 1 const CHANGE_DATA = 1
const CHANGE_TILE = 2 const CHANGE_TILE = 2
@ -87,6 +88,7 @@ export default {
INPUT_EV_PLAYER_NAME, INPUT_EV_PLAYER_NAME,
INPUT_EV_TOGGLE_PREVIEW, INPUT_EV_TOGGLE_PREVIEW,
INPUT_EV_TOGGLE_SOUNDS,
CHANGE_DATA, CHANGE_DATA,
CHANGE_TILE, CHANGE_TILE,

BIN
src/frontend/click.mp3 Normal file

Binary file not shown.

View file

@ -12,6 +12,7 @@
<tr><td>🖼 Toggle preview:</td><td><div><kbd>Space</kbd></div></td></tr> <tr><td>🖼 Toggle preview:</td><td><div><kbd>Space</kbd></div></td></tr>
<tr><td>🧩 Toggle fixed pieces:</td><td><div><kbd>F</kbd></div></td></tr> <tr><td>🧩 Toggle fixed pieces:</td><td><div><kbd>F</kbd></div></td></tr>
<tr><td>🧩 Toggle loose pieces:</td><td><div><kbd>G</kbd></div></td></tr> <tr><td>🧩 Toggle loose pieces:</td><td><div><kbd>G</kbd></div></td></tr>
<tr><td>🔉 Toggle sounds:</td><td><div><kbd>M</kbd></div></td></tr>
</table> </table>
</div> </div>
</template> </template>

View file

@ -13,6 +13,10 @@
<td><label>Name: </label></td> <td><label>Name: </label></td>
<td><input type="text" maxLength="16" v-model="modelValue.name" /></td> <td><input type="text" maxLength="16" v-model="modelValue.name" /></td>
</tr> </tr>
<tr>
<td><label>Sounds: </label></td>
<td><input type="checkbox" v-model="modelValue.soundsEnabled" /></td>
</tr>
</table> </table>
</div> </div>
</template> </template>

View file

@ -31,6 +31,9 @@ declare global {
// @ts-ignore // @ts-ignore
const images = import.meta.globEager('./*.png') const images = import.meta.globEager('./*.png')
// @ts-ignore
const sounds = import.meta.globEager('./*.mp3')
export const MODE_PLAY = 'play' export const MODE_PLAY = 'play'
export const MODE_REPLAY = 'replay' export const MODE_REPLAY = 'replay'
@ -46,6 +49,7 @@ interface Hud {
setPiecesTotal: (v: number) => void setPiecesTotal: (v: number) => void
setConnectionState: (v: number) => void setConnectionState: (v: number) => void
togglePreview: () => void togglePreview: () => void
toggleSoundsEnabled: () => void
setReplaySpeed?: (v: number) => void setReplaySpeed?: (v: number) => void
setReplayPaused?: (v: boolean) => void setReplayPaused?: (v: boolean) => void
} }
@ -171,6 +175,9 @@ function EventAdapter (canvas: HTMLCanvasElement, window: any, viewport: any) {
PIECE_VIEW_LOOSE = !PIECE_VIEW_LOOSE PIECE_VIEW_LOOSE = !PIECE_VIEW_LOOSE
RERENDER = true RERENDER = true
} }
if (ev.key === 'M' || ev.key === 'm') {
addEvent([Protocol.INPUT_EV_TOGGLE_SOUNDS])
}
}) })
const addEvent = (event: GameEvent) => { const addEvent = (event: GameEvent) => {
@ -233,6 +240,9 @@ export async function main(
return MODE === MODE_REPLAY || player.id !== clientId return MODE === MODE_REPLAY || player.id !== clientId
} }
const click = sounds['./click.mp3'].default
const clickAudio = new Audio(click)
const cursorGrab = await Graphics.loadImageToBitmap(images['./grab.png'].default) const cursorGrab = await Graphics.loadImageToBitmap(images['./grab.png'].default)
const cursorHand = await Graphics.loadImageToBitmap(images['./hand.png'].default) const cursorHand = await Graphics.loadImageToBitmap(images['./hand.png'].default)
const cursorGrabMask = await Graphics.loadImageToBitmap(images['./grab_mask.png'].default) const cursorGrabMask = await Graphics.loadImageToBitmap(images['./grab_mask.png'].default)
@ -404,6 +414,13 @@ export async function main(
let finished = longFinished let finished = longFinished
const justFinished = () => finished && !longFinished const justFinished = () => finished && !longFinished
const playerSoundEnabled = (): boolean => {
const enabled = localStorage.getItem('sound_enabled')
if (enabled === null) {
return false
}
return enabled === '1'
}
const playerBgColor = () => { const playerBgColor = () => {
return (Game.getPlayerBgColor(gameId, clientId) return (Game.getPlayerBgColor(gameId, clientId)
|| localStorage.getItem('bg_color') || localStorage.getItem('bg_color')
@ -614,12 +631,24 @@ export async function main(
viewport.zoom('out', viewport.worldToViewport(pos)) viewport.zoom('out', viewport.worldToViewport(pos))
} else if (type === Protocol.INPUT_EV_TOGGLE_PREVIEW) { } else if (type === Protocol.INPUT_EV_TOGGLE_PREVIEW) {
HUD.togglePreview() HUD.togglePreview()
} else if (type === Protocol.INPUT_EV_TOGGLE_SOUNDS) {
HUD.toggleSoundsEnabled()
} }
// LOCAL + SERVER CHANGES // LOCAL + SERVER CHANGES
// ------------------------------------------------------------- // -------------------------------------------------------------
const ts = TIME() const ts = TIME()
const changes = Game.handleInput(gameId, clientId, evt, ts) const changes = Game.handleInput(
gameId,
clientId,
evt,
ts,
(playerId: string) => {
if (playerSoundEnabled()) {
clickAudio.play()
}
}
)
if (changes.length > 0) { if (changes.length > 0) {
RERENDER = true RERENDER = true
} }
@ -787,6 +816,9 @@ export async function main(
localStorage.setItem('player_name', value) localStorage.setItem('player_name', value)
evts.addEvent([Protocol.INPUT_EV_PLAYER_NAME, value]) evts.addEvent([Protocol.INPUT_EV_PLAYER_NAME, value])
}, },
onSoundsEnabledChange: (value: boolean) => {
localStorage.setItem('sound_enabled', value ? '1' : '0')
},
replayOnSpeedUp, replayOnSpeedUp,
replayOnSpeedDown, replayOnSpeedDown,
replayOnPauseToggle, replayOnPauseToggle,
@ -795,6 +827,7 @@ export async function main(
background: playerBgColor(), background: playerBgColor(),
color: playerColor(), color: playerColor(),
name: playerName(), name: playerName(),
soundsEnabled: playerSoundEnabled(),
}, },
disconnect: Communication.disconnect, disconnect: Communication.disconnect,
connect: connect, connect: connect,

View file

@ -70,12 +70,14 @@ export default defineComponent({
background: '', background: '',
color: '', color: '',
name: '', name: '',
soundsEnabled: false,
}, },
previewImageUrl: '', previewImageUrl: '',
setHotkeys: (v: boolean) => {}, setHotkeys: (v: boolean) => {},
onBgChange: (v: string) => {}, onBgChange: (v: string) => {},
onColorChange: (v: string) => {}, onColorChange: (v: string) => {},
onNameChange: (v: string) => {}, onNameChange: (v: string) => {},
onSoundsEnabledChange: (v: boolean) => {},
disconnect: () => {}, disconnect: () => {},
connect: () => {}, connect: () => {},
}, },
@ -94,6 +96,9 @@ export default defineComponent({
this.$watch(() => this.g.player.name, (value: string) => { this.$watch(() => this.g.player.name, (value: string) => {
this.g.onNameChange(value) this.g.onNameChange(value)
}) })
this.$watch(() => this.g.player.soundsEnabled, (value: boolean) => {
this.g.onSoundsEnabledChange(value)
})
this.g = await main( this.g = await main(
`${this.$route.params.id}`, `${this.$route.params.id}`,
// @ts-ignore // @ts-ignore
@ -111,6 +116,7 @@ export default defineComponent({
setPiecesTotal: (v: number) => { this.piecesTotal = v }, setPiecesTotal: (v: number) => { this.piecesTotal = v },
setConnectionState: (v: number) => { this.connectionState = v }, setConnectionState: (v: number) => { this.connectionState = v },
togglePreview: () => { this.toggle('preview', false) }, togglePreview: () => { this.toggle('preview', false) },
toggleSoundsEnabled: () => { this.g.player.soundsEnabled = !this.g.player.soundsEnabled },
} }
) )
}, },

View file

@ -69,12 +69,14 @@ export default defineComponent({
background: '', background: '',
color: '', color: '',
name: '', name: '',
soundsEnabled: false,
}, },
previewImageUrl: '', previewImageUrl: '',
setHotkeys: (v: boolean) => {}, setHotkeys: (v: boolean) => {},
onBgChange: (v: string) => {}, onBgChange: (v: string) => {},
onColorChange: (v: string) => {}, onColorChange: (v: string) => {},
onNameChange: (v: string) => {}, onNameChange: (v: string) => {},
onSoundsEnabledChange: (v: boolean) => {},
replayOnSpeedUp: () => {}, replayOnSpeedUp: () => {},
replayOnSpeedDown: () => {}, replayOnSpeedDown: () => {},
replayOnPauseToggle: () => {}, replayOnPauseToggle: () => {},
@ -100,6 +102,9 @@ export default defineComponent({
this.$watch(() => this.g.player.name, (value: string) => { this.$watch(() => this.g.player.name, (value: string) => {
this.g.onNameChange(value) this.g.onNameChange(value)
}) })
this.$watch(() => this.g.player.soundsEnabled, (value: boolean) => {
this.g.onSoundsEnabledChange(value)
})
this.g = await main( this.g = await main(
`${this.$route.params.id}`, `${this.$route.params.id}`,
// @ts-ignore // @ts-ignore
@ -119,6 +124,7 @@ export default defineComponent({
setConnectionState: (v: number) => { this.connectionState = v }, setConnectionState: (v: number) => { this.connectionState = v },
setReplaySpeed: (v: number) => { this.replay.speed = v }, setReplaySpeed: (v: number) => { this.replay.speed = v },
setReplayPaused: (v: boolean) => { this.replay.paused = v }, setReplayPaused: (v: boolean) => { this.replay.paused = v },
toggleSoundsEnabled: () => { this.g.player.soundsEnabled = !this.g.player.soundsEnabled },
} }
) )
}, },