# ぶっ壊しドミノ

> 同じ部屋に入った人どうしでドミノを並べて、誰でも倒せるオンラインのブラウザゲーム。他人が積み上げたドミノをぶっ壊すと、誰のドミノを何個倒したかが部屋の全員に知らされる。WebGL2で描いた。

- 制作: [ワカメ](https://wakame.dev/)（個人で企画・開発）
- ステータス: 公開中
- 制作期間: 2026-10
- カテゴリ: Web, Game, Graphics
- 使用技術: WebGL2, GLSL, インスタンス描画, Cloudflare Durable Objects, WebSocket, Pointer Events, WebAudio, JavaScript
- 担当: 企画, ゲーム設計, シェーダー実装, オンライン部屋の実装, 効果音

## 概要

床を指やマウスでなぞると、その線に沿ってドミノが等間隔に並びます。曲線を描けば向きも線に合わせて変わり、うずまきや枝分かれも作れます。ドミノをタップすると手前から奥へ倒れ、届く範囲のドミノを次々に倒していきます。部屋には誰でも入れる「みんなの広場」と、合言葉で入る部屋があり、1部屋に8人まで入れます。並べたドミノは置いた人の色になり、部屋に保存されるので、あとから来た人が他人の作品を倒すこともできます。倒すと「○○が△△のドミノを52個ぶっ壊した！」と全員の画面に出ます。ほかの人のカーソルは名前の札として見え、倒れたドミノはまとめて片付けたり、全部立て直したりできます。部屋はCloudflareのDurable Objectsで、WebSocketでつないでいます。端末ごとに物理演算をすると結果がずれるため、どのドミノが倒れるかはドミノの位置と向きだけからサーバーが決めて全員に配り、各端末は倒れるアニメーションだけを付けています。同じルールのファイルをサーバーと画面の両方で読み込んでいます。描画は3Dライブラリを使わずWebGL2とGLSLで直接書き、最大2000個のドミノをインスタンス描画しています。影は床に押しつぶした形を、重なっても濃くならないようステンシルで1回だけ塗っています。倒れる音もWebAudioでその場で合成しています。

## 全員に同じ倒れ方を見せる

ドミノを物理演算で倒すと、端末ごとの計算のわずかな違いで、ある人の画面では倒れたのに別の人の画面では止まった、ということが起きます。そこで、どのドミノが倒れるかは時間を追わずに形だけで決めることにしました。倒れるドミノの先端が届く範囲（高さぶんの距離）に立っているドミノがあれば、それも倒れる、という判定を順にたどります。

この判定は部屋のDurable Objectが行い、倒れる順番・倒れる向き・前のドミノが当たる角度を全員に配ります。各端末は、その順番どおりに倒れるアニメーションを付けるだけです。ルールは1つのファイルにまとめ、サーバーと画面の両方で読み込んでいるので、サーバーにつながらないときも同じルールで1人で遊べます。

- いちばん手前とほぼ同じ距離に2つあれば両方倒れるので、列の枝分かれもできる
- 倒れたドミノは次のドミノにもたれかかり、次が倒れるのに合わせて寝ていく
- 並べたドミノは部屋に保存し、3日間だれも触らなければ片付ける

## なぞって並べる

床をなぞった点の列を、0.58の間隔で区切ってドミノを置く場所を決め、向きは前後の点から求めて曲がり角でもガタつかないようにしています。すでに立っているドミノに近すぎる場所や、置ける範囲の外は赤く表示して、置かずにとばします。

ドミノの描画はインスタンス描画で、1回の命令で全部を描いています。影は、ドミノを光の向きに沿って床へ押しつぶした形として描き、ステンシルで同じ場所を1回しか塗らないようにして、影どうしが重なっても濃くならないようにしています。

## 成果

- 3Dライブラリなしで、WebGL2とGLSLだけで実装
- なぞった線に沿ってドミノを並べ、曲線や枝分かれも作れる
- 1部屋8人まで、同じ場所にリアルタイムでドミノを並べて倒せる
- 倒れる順番はサーバーが決めて配るので、全員に同じ結果が見える
- 並べたドミノは部屋に保存され、あとから来た人も倒せる
- 誰が誰のドミノを何個倒したかを、部屋の全員に知らせる

## リンク

- [サイト](https://wakame.dev/domino/)

## このサイトについて

- [ワカメの詳細プロフィール](https://wakame.dev/ai-profile/index.html.md)
- [llms.txt](https://wakame.dev/llms.txt)
