2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Liveviewで作るスロットゲーム

Last updated at Posted at 2021-10-25

Phoenix LiveviewはSPAライクなUIをElixirのみで開発できる素晴らしいライブラリです。

つい最近バージョン0.17.0がリリースされ、アニメーションを使った機能がより豊富になりました。
こちら参考

どのくらい複雑なアニメーションが開発できるのか試したくなったので、ハロウィーンにちなんでドクロのキャラクターと戦うパチスロを作ってみました。

パチスロのリポジトリ
localで遊べます

パチスロにしては見た目はシンプルです。。。(パチスロ未経験)
サンプル画像
slot_gif1.gif

スロット画面のボタンを押すと押された列のスロットが止まります。
三列止まったときに横か斜めで絵柄が3つ揃うと敵にダメージが加えられます。
7が揃った場合は倍のダメージとなります。

結論

ゲーム開発できる?くらいに複雑なアニメーションを作れます。
以下の3つの関数が大活躍しました。
Process.send_after/3
handle_event/3
handle_info/2

開発方法

まずはアニメーション用の画像を準備します。

ドクロの画像

CSSのアニメーションだとかゆいところに手が届かないので、画像をコマ送りにしてアニメにします。
サンプル画像のドクロの敵キャラはAsepriteというドット絵作成ツールを用いて連番のアニメーション画像を作成しました。

作成したシーンは
①登場シーン(13枚)
skull_appear_anim.png

②通常時のシーン(11枚)
skull_attack_anim.png

③ダメージを受けたシーン(17枚)
skull_damage_anim.png

④死亡した時のシーン(55枚)
skull_death_anim.png

①〜④を一枚のwebp画像に変換し、スロットのアクションに応じて使い分けています。

スロットの画像

こちらもAsepriteを使って
①左列(16枚)
②真ん中列(16枚)
③右列(16枚)
④背景(1枚)
⑤ボタン(6枚)
を作成しました。

ドクロのアニメーションと異なる点は①〜⑤のアニメーションがそれぞれ別々の動作をするため、一枚のwebp画像にまとめるのではなく、全てSVGファイルとして出力した点です。
SVGを使うことで位置の細かい調整がしやすくなります。
また

use Phoenix.Component

とすることで

def button(assigns) do
  <svg ... >
    <path ... >
  </svg>

のように任意の名前でSVG画像を関数として定義でき、関数内でsocket.assignsに対する変更を加えることもできます。

詳しくは
Phoenix.Component

ドクロとスロットの絵柄をアニメーションにする

10fps前提で進めます。

基本的な考え方は
①mount時に最初の画像をsocket.assigns.hogeとして状態を持たせて、Process.send_after/3で自プロセスに画像更新用のメッセージを送る

def mount(_, _, socket) do
  Process.send_after(self(), :hoge2, 100)
  {:ok, assign(socket, %{ init_image: image }}
end

②メッセージをhandle_info/2で受けとり、次のフレームのためのメッセージを送る

def handle_info(:hoge, socket) do
  Process.send_after(self(), :hoge3, 100) 
  {:noreply, assign(socket, %{ init_image: image2 }}
end

③さらに続く画像のためのhanndle_infoを定義し、アニメーション全部分一周したら画面の動作を確認する。

ボタンをアニメーションにする

①ボタンのSVGのコードにphx-click="hoge"をつけてhandle_event/3で画像を切り替えました。

# template
<svg phx-click="hoge" ... >

# handle event
handle_event("hoge", _, socket) do
  {:noreply, assign(socket, %{ button_image: image }}
end

やってみて思ったこと

Liveviewを用いることでかなり柔軟なアニメーションが作成できいました。
ゲームエンジンを使わずとも初期のマリオ程度のゲームであれば開発可能ではないかと思います。

WEBでのアニメーションにもっと柔軟性が欲しいと考えるデザイナーやエンジニアの方は是非参考にしてみてください。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?