💠

平面のルービックキューブ的なものを作った

2023/07/20に公開2

自分でも何を言ってるのか分からないが、見れば分かる。こういうやつ。

4色のパネルがバラバラに配置されているので、列または行単位でパネルをスライドして同じ色が集まるように並び替えるゲーム。

ここで遊べる。

https://kurehajime.github.io/iroawase/

機能概要

このゲームには以下のような機能がある。

モード選択

このゲームでは「easy」と「hard」の二種類のモードを選べる。easyでは2x2、hardは3x3でプレイする。

ゲームプレイ

モードを選択するとゲームが始まる。チュートリアルはない。即プレイ開始。

結果表示

プレイ履歴の再生

クリア画面から「PLAYBACK」ボタンを押すと、自分のプレイを早送りで振り返る事ができる。

プレイ履歴のシェア機能

プレイ履歴はシェアできる。結果画面のURLを公開するだけで良い。

https://kurehajime.github.io/iroawase/?f=211331212214144442434432342331212313&l=3a3b0c2d2a3b1c0d5a1b-1c0d2a2b0c-2d2a0b2c0d4a0b0c3d1a2b0c-2d1a0b4c0d1a1b4c0d1a2b4c0d5a2b0c3d2a2b-2c0d1a1b-1c0d1a0b-1c0d1a3b0c-3d2a2b-2c0d2a4b-1c0d1a4b1c0d2a4b0c1d2a5b-1c0d1a1b0c1d4a2b-2c0d2a2b0c3d3a1b-1c0d2a1b0c1d3a1b-1c0d2a0b0c3d4a2b-4c0d4a1b-4c0d2a3b0c-3d5a3b0c-2d4a3b1c0d5a3b0c2d3a3b-3c0d3a4b-3c0d3a5b-3c0d4a2b0c3d4a2b1c0d5a2b0c2d3a4b0c-1d4a2b-1c0d3a3b0c-2d3a3b0c-1d3a2b1c0d3a4b0c-2d3a2b-1c0d3a2b0c1d3a3b-3c0d3a5b-3c0d3a4b-3c0&m=hard&t=120


これをクリックすると再生できる。

構成技術

このゲームを構成している技術はこんな感じ。

フロントエンド
React

バックエンド
なし(Github Pagesに静的なHTMLを配置してるだけ)

技術解説

描画まわり

画面はReact+SVGで構成している。

SVGはXMLで図形を描画できる画像フォーマット。

こんな感じでXMLを定義すると…

<svg width="500" height="500">
    <rect width="150" height="100" x="25" y="15" />
    <circle stroke="green" fill="white" x="30" y="30" cx="50" cy="50" r="48"></circle>
    <text x="100" y="100" fill="red">ほげぇ</text>
</svg>

こんなふうに画像になる。

このSVGのXMLをReactで組み立てる事によってインタラクティブなゲームを作ってる。

ループするスクロール

このゲームではパネルを左にずらすと、反対側の右からニュッとパネルが出てくる。
スライドする途中では、同じパネルが右端と左端の両方に存在している。

このような摩訶不思議な状態をどのように実現しているのかというと、かなり強引な方法で実現している。

画面に見えているマップの上下左右に同じマップをコピーして配置している。
そうすることで、どんなにはみ出しても途切れることなくスクロールできる。

プレイ履歴のシェア

バックエンドのアプリケーションサーバーが存在しない静的なページなのにどうやってプレイ履歴のシェアができるのか。「FaaSのAPIを叩いてるだけなのでサーバーレスです」などという詭弁ではない。HTMLをローカルにダウンロードして機内モードにしてもちゃんと動く真のサーバーレスだ。

そのカラクリはURLにある。

https://kurehajime.github.io/iroawase/?f=211331212214144442434432342331212313&l=3a3b0c2d2a3b1c0d5a1b-1c0d2a2b0c-2d2a0b2c0d4a0b0c3d1a2b0c-2d1a0b4c0d1a1b4c0d1a2b4c0d5a2b0c3d2a2b-2c0d1a1b-1c0d1a0b-1c0d1a3b0c-3d2a2b-2c0d2a4b-1c0d1a4b1c0d2a4b0c1d2a5b-1c0d1a1b0c1d4a2b-2c0d2a2b0c3d3a1b-1c0d2a1b0c1d3a1b-1c0d2a0b0c3d4a2b-4c0d4a1b-4c0d2a3b0c-3d5a3b0c-2d4a3b1c0d5a3b0c2d3a3b-3c0d3a4b-3c0d3a5b-3c0d4a2b0c3d4a2b1c0d5a2b0c2d3a4b0c-1d4a2b-1c0d3a3b0c-2d3a3b0c-1d3a2b1c0d3a4b0c-2d3a2b-1c0d3a2b0c1d3a3b-3c0d3a5b-3c0d3a4b-3c0&m=hard&t=120

とても長い。
この長いURLにプレイ履歴の情報が全部詰まっている。

f=211331212214144442434432342331212313

これは初期配置。

211331212
214144442
434432342
331212313

この配置からスタートしたということを表している。

l=3a3b0c2d2a3b1c0d5a1b-1c0d2a2b0c-2d2a0b2c0d4a0b0c3d1a2b0c-2d1a0b4c0d1a1b4c0d1a2b4c0d5a2b0c3d2a2b-2c0d1a1b-1c0d1a0b-1c0d1a3b0c-3d2a2b-2c0d2a4b-1c0d1a4b1c0d2a4b0c1d2a5b-1c0d1a1b0c1d4a2b-2c0d2a2b0c3d3a1b-1c0d2a1b0c1d3a1b-1c0d2a0b0c3d4a2b-4c0d4a1b-4c0d2a3b0c-3d5a3b0c-2d4a3b1c0d5a3b0c2d3a3b-3c0d3a4b-3c0d3a5b-3c0d4a2b0c3d4a2b1c0d5a2b0c2d3a4b0c-1d4a2b-1c0d3a3b0c-2d3a3b0c-1d3a2b1c0d3a4b0c-2d3a2b-1c0d3a2b0c1d3a3b-3c0d3a5b-3c0d3a4b-3c0

これはその後の操作履歴。
dが区切り文字になっている。
最初の5ムーブは以下の通り。

3a3b0c2
2a3b1c0
5a1b-1c0
2a2b0c-2
2a0b2c0

1ムーブ目はこれ。

3a3b0c2

abcが区切り文字になっていて、
「x=3,y=3のパネルをx軸方向に0,y方向に2マス動かした」
ということを表している。

このようにプレイ履歴を全部URLに突っ込むことで、DBもバックエンドの技術も利用せずにシェア機能を実現している。安上がり。

おわりに

Easyモード 8 move
https://kurehajime.github.io/iroawase/?f=3134232214424113&l=1a3b-1c0d0a2b0c-2d1a0b0c1d2a3b-1c0d2a0b0c3d2a3b-1c0d2a2b0c1d3a3b0c-1&m=easy&t=23

Hardモード 25move
https://kurehajime.github.io/iroawase/?f=314311113342344321213142223442441223&l=5a5b-3c0d3a2b0c3d2a1b-2c0d2a3b-1c0d2a4b-1c0d2a5b-1c0d0a2b0c3d1a0b1c0d4a1b-1c0d5a0b0c1d3a1b-3c0d4a5b0c-3d5a3b0c-1d4a2b-2c0d4a3b0c-1d2a2b-2c0d3a1b1c0d4a3b0c2d5a2b0c-1d3a2b2c0d3a0b2c0d5a0b0c3d2a0b-2c0d1a1b-1c0d2a2b-2c0&m=hard&t=79

Discussion

ZsrtrghZsrtrgh

アイデアがすごい!
やってみたら楽しかった