javascriptを使わず、html + cssだけでクリックシューティングゲームを作ってみた

CSSで描かれたぐぬぬ画像などを見てたら、ふとhtml + CSSだけでアクションゲームが作れないかと思ったので作ってみました。
ページ移動すればいくらでも可能ですが、それだとつまらないので、1ページ内で作るという縛りもつけてます。

デモページ

http://ndruger.lolipop.jp//hatena/20110429/css_game/css_game.htm
Chrome / Safariの最新版で動きます。Firefox / IEだと動きません。

技術的な説明

アニメーションはCSS Animationを使うだけなので簡単ですが、問題は状態管理です。

アクションゲームを作るには、基本的に下記の要素が必要です。

  • 1. ユーザー入力に対する状態の変更
  • 2. 状態の保持
  • 3. 状態に応じて見た目を変更

これらをhtml + CSSで実現する方法を考えます。

"1. ユーザー入力に対する状態の変更"を実装するには、:hover, :activeなどが思い浮かびますが、それらでは"2. 状態の保持"ができません。
よって、疑似クラスの状態変化が継続する、:visited, :focus, :checkedなどが使えそうです。

最初は、aタグのフラグメントジャンプ()を使って:visitedで状態を変えようとしたのですが、最近のブラウザは訪問履歴読み取り防止のため、:visitedで有効なプロパティがcolorなどに限られていて、ゲームに使うのは難しいと分かりました。
:focusは別な場所をクリックすると解除されるのであきらめました。
残ったのは:checkedですが、inputタグのtype=radio, checkboxならユーザー入力に応じて状態を記憶できるので、これを使います。


次に"3. 状態に応じて見た目を変更"の実現ですが、inputタグのtype=radio, checkboxを使った場合、その要素にどうやってキャラクター画像とマップさせるかが問題です。

  • CSSには親・祖先セレクタがないので、input:checkedの親要素でbackground-imageプロパティを適応できない
  • inputタグのtype=radio, checkboxはbackground-imageプロパティが反映されない
  • inputタグはDHTMLで無理矢理付けない限り子要素を持てない -> 子要素で画像を表示するなどのテクニックができない

この問題を解決するために、CSS3のappearanceプロパティを使います。
使っているコンテンツを今まで見たことがないのですが、このプロパティを"-moz-appearance: button;-webkit-appearance: button;"のように指定すると、background-imageプロパティが反映されるようになります。CSS3の仕様ではこの挙動は明示されてません。


ここまでいけば後は簡単です。
アニメーションしている牛がクリックされて:checkedが有効になると、牛の取得アイコンとして適切なbackground-image, positionに変えてしまいます。
ついでにスコアを表示するため、type=radioの同じnameの要素を作って、ユーザーのクリックでそちらは:checkedが解除されるようにします。
そして、:checkedでレイアウトが変更され、スコアの画像がずれるようにすると、牛のクリックごとにスコアが上がるようにできます。