2024年4月6日土曜日

えもじパズルを作った

えもじパズル を作りました。 完成図と見比べながらパーツを並び替えて、福笑いみたいに絵文字を作るゲームです。 細部まで見比べる力を鍛えるので、特に美術や算数や漢字の学習へ応用しやすいかな。



最近は アイコン点描写漢字点描写 を作っていて、 絵文字点描写も作っていたのですが、ボツ案となりました。 絵文字は (1) 複雑すぎる、(2) 直感的な描画ではないことが多い、の2つが厳しかったです。 1 は左右に絵文字を表示することで自然と表示サイズが小さくなるため、 思っていたより点が密集してしまい、複雑に感じることがわかりました。 スキップアルゴリズムを付ければ複雑性は緩和できますが、 パーツの重なりを活かして作成されていることが多いので 点の直感性とズレていることが多く、本質的な厳しさを感じました。 描画の直感性は点つなぎだと誤魔化せるけど、点描写は誤魔化せないからなあ。

そこで絵文字を使った他のゲームを作ろうと思って、えもじパズルを作ってみました。 アイコンや漢字ではできないけど、絵文字ならできるタイプのゲームです。

作り方

作り方は割と簡単で、SVG のパーツを分解して drag & drop 可能にします。 小さなピースは動かしにくいので雑に計算した面積が全体の 5% 未満なら動かせないようにしたり、自動配置してプレイ感覚の向上に努めました。 あとはユーザにパーツを移動してもらいながら絵文字を作ってもらい、一致チェックします。 一致チェックはシンプルで、canvas を画像化してピクセル単位で比較します。 座標をもとにチェックする方法もありそうですが、重なりの解析が大変だしなあ。 80% くらいの一致率は簡単に出てしまうので、85% 以上の一致率があれば正解としました。 簡単な問題は 90% くらいが良いのですが、難しい問題は 90% を出すのがかなり難しい…。

パズル部分の作り方は簡単なのですが、様々な絵文字で動くようにするのが一苦労でした。 たとえば drag & drop のためにはピースごとに transform 属性を除去して新たな transform 属性を付与する必要があります。 ブラウザだと階層的な transform を getCTM() で解析できるので良いですが、非ブラウザだと解析はなかなか大変で対応ライブラリはないと思います。 getCTM() を使っても元々の path データに transform: matrix() があると移動用の transform 属性と混じってしまうので、まだ面倒なことあります。 これは元の transform の matrix を逆変換しながら座標変換を行い ( 参考1参考2 )、 正しい移動距離を算出し、matrix を更新する必要があります。意外と難しい。 DOMMatrix や SVGMatrix、getCTM() は初めて使いましたが、なかなか便利です。 やはりブラウザの API は最強です。

0 件のコメント: