Skip to content

Commit

Permalink
Sounds (#79)
Browse files Browse the repository at this point in the history
* add sound effects

* configurable asset path

* configurable sound

* update docs

* remove console log
  • Loading branch information
Danny Blue committed Feb 15, 2024
1 parent d91de34 commit 2a5d7cc
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 10 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ Go Board WebComponent. The entire library weights less than 5kb gzip and less th
## All you need to get started is some markup and a script tag

```HTML
<script src="https://cdn.jsdelivr.net/npm/go-board@latest/bundle/go-board.min.js"></script>
<script
src="https://cdn.jsdelivr.net/npm/go-board@latest/bundle/go-board.min.js"
data-asset-path="https://cdn.jsdelivr.net/npm/go-board@latest/assets"
></script>

<go-board coords>
<go-stone color="black" slot="R17"></go-stone>
Expand Down
Binary file added assets/effects.webm
Binary file not shown.
Binary file added assets/kaya.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/stones.webm
Binary file not shown.
8 changes: 6 additions & 2 deletions dev.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,22 @@
</style>

<form action="/save-game">
<button>submit</button>
<go-board name="board"></go-board>
</form>

<script src="./target/register.js" type="module"></script>
<script
src="./target/register.js"
type="module"
data-asset-path="/assets"
></script>

<script type="module">
const board = document.querySelector("go-board");
const url = new URL(window.location);

board.coords = url.searchParams.has("coords");
board.debug = url.searchParams.has("debug");
board.readonly = url.searchParams.has("readonly");

if (url.searchParams.has("ogsid")) {
const ogsid = url.searchParams.get("ogsid");
Expand Down
6 changes: 5 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@
<go-board></go-board>
</form>

<script src="./bundle/go-board.min.js" type="module"></script>
<script
src="./bundle/go-board.min.js"
type="module"
data-asset-path="/assets/test"
></script>

<script type="module">
const board = document.querySelector("go-board");
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
},
"files": [
"target",
"bundle"
"bundle",
"assets"
],
"repository": {
"type": "git",
Expand Down
23 changes: 18 additions & 5 deletions src/board.element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Debug } from "./debug.js";
import { GoStoneElement, StoneColor } from "./stone.element.js";
import { findAttachedEnemyStones, findGroup } from "./game.js";
import { Move, parseSGF } from "./sgf.js";
import { Sfx } from "./sfx.js";

@injectable
export class GoBoardElement extends HTMLElement {
Expand All @@ -17,7 +18,7 @@ export class GoBoardElement extends HTMLElement {
:host {
font-family: system-ui;
box-sizing: border-box;
background: #dcb35c;
background: url("assets/kaya.jpg") #dcb35c;
display: block;
padding: 0;
position: relative;
Expand Down Expand Up @@ -186,6 +187,7 @@ export class GoBoardElement extends HTMLElement {
@attr accessor cols = 19;
@attr accessor coords = false;
@attr accessor readonly = false;
@attr accessor sfx = false;

moves: Move[] = [];
sgf: string | null = null;
Expand Down Expand Up @@ -224,6 +226,7 @@ export class GoBoardElement extends HTMLElement {
// this makes state calculations very cheap. the stone added/removed lifecycle callbacks keep this map in state.
#spaces = new Map<string, GoStoneElement | null>();
#header = this.dom.query("#header")!;
#audio = new Sfx();
#prevKey = "";
#currentKey = Array.from({ length: this.rows * this.cols })
.map(() => "*")
Expand Down Expand Up @@ -266,7 +269,7 @@ export class GoBoardElement extends HTMLElement {
this.#spaces.set(stone.slot, null);
}

@listen("click") onClick(e: Event) {
@listen("mousedown") onClick(e: Event) {
if (this.readonly) {
return;
}
Expand Down Expand Up @@ -382,9 +385,19 @@ export class GoBoardElement extends HTMLElement {
} else {
// board state is valid and we can proceed

// remove captured stones from dom
for (let stone of removedStones) {
stone.remove();
if (removedStones.length) {
// remove captured stones from dom
for (let stone of removedStones) {
stone.remove();
}

if (this.sfx) {
this.#audio.captureStones(removedStones.length);
}
} else {
if (this.sfx) {
this.#audio.placeStone();
}
}

// find added stones group
Expand Down
87 changes: 87 additions & 0 deletions src/sfx.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
const script = document.querySelector<HTMLScriptElement>(
"script[data-asset-path]"
);

export class Sfx {
#stones = new Audio();
#effects = new Audio();

constructor() {
this.#stones.volume = 0.1;
this.#effects.volume = 0.1;

if (script) {
if (script.dataset.assetPath) {
this.#stones.src = `${script.dataset.assetPath}/stones.webm`;
this.#effects.src = `${script.dataset.assetPath}/effects.webm`;
}
}
}

placeStone() {
let sounds = [
[1000.0, 137.20833333333331],
[2137.208333333333, 58.854166666666664],
[3196.0625, 86.60416666666666],
[4282.666666666667, 85.0],
[5367.666666666667, 86.8125],
];

const [start, duration] = sounds[Math.floor(Math.random() * sounds.length)];

return new Promise<void>((resolve) => {
this.#stones.currentTime = start / 1000;
this.#stones.play();

setTimeout(() => {
this.#stones.pause();

resolve();
}, duration);
});
}

captureStones(count: number) {
const single = [
[2507.1041666666665, 1074.6458333333333],
[6200.895833333333, 1485.9166666666667],
[10539.125, 1034.9375],
[14253.833333333332, 895.8541666666666],
];

const pile = [
[1000.0, 507.1041666666667],
[4581.75, 619.1458333333333],
[8686.8125, 852.3125],
[12574.0625, 679.7708333333334],
[16149.687499999998, 1148.8125],
[18298.5, 1145.3333333333333],
];

return new Promise<void>((resolve) => {
let start: number;
let duration: number;

if (count === 1) {
const sprite = single[Math.floor(Math.random() * single.length)];

start = sprite[0];
duration = sprite[1];
} else {
const sprite = pile[Math.floor(Math.random() * pile.length)];

start = sprite[0];
duration = sprite[1];
}

this.#effects.currentTime = start / 1000;
this.#effects.play();

setTimeout(() => {
this.#effects.pause();

resolve();
}, duration);
});
}
}

0 comments on commit 2a5d7cc

Please sign in to comment.