カテゴリー
【Sassで解説】ヤマト運輸HPの404エラーページのミニゲームはほぼCssゲームだった
※ 当ページには【広告/PR】を含む場合があります。
2021/05/22

ちょっと前にエラーページなのにカワイイと話題になっていた
今回はそのミニゲームの機能の一部をSassで実装できるか、ベースとなるテクニックをちょっとだけ掘り下げてみたいと思います。
エラーページをカスタマイズするという心意気
エラーページは本来SEO効果もない蛇足なものですので、わざわざリソースを割いてまでこだわりのページに作り上げることはしないのですが、ごくごく稀に、訪れるビジターを喜ばせたいがために画期的なアイデアでおもてなししてくれるウェブサイトを見かけます。
一見集客性のない404ページですが、何かの拍子で話題に上がれば、ウェブサイトを訪れた人の印象にも残ったり、企業であれば顧客好感度アップの効果もあるかも知れません。
このブログでも以前、AWSで静的ホスティングしてCDN型のウェブサイトの404ページのカスタマイズ方法に関して以下のような内容でポストしておりました。
AWS CloudFrontを駆使した柔軟なHTTPリクエストのリダイレクト機能を利用して、特設の404ページに誘導することは割と簡単ですので、Webページ作成に予算と時間の余裕があれば是非ともチャレンジしてはいかがかと思います。
画像の位置を変えてアニメーション
ますはヤマト運輸の404ページへリンクさせていただいた状態で、ゲームの挙動だけを抽出して実行させてみましょう。
最低限動作するテスト用のindex.htmlは、
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="game-wrapper">
<div class="box-game" id="box-1">
<input type='checkbox' id='checkbox1'>
<label for='checkbox1'></label>
<div class="box-game-inner"></div>
</div>
<div class="box-game" id="box-2">
<input type='checkbox' id='checkbox2'>
<label for='checkbox2'></label>
<div class="box-game-inner"></div>
</div>
</div>
</body>
</html>
としておきましょう。
このhtmlに割り当てるcssスタイルファイル(style.css)ですが、以下のScssファイル(style.scss)をSassコンパイルしたものを利用します。
#game-wrapper {
width: 100%;
height: 300px;
background-color: darkgray;
box-sizing: border-box;
position:relative;
.box-game {
position: absolute;
width: 84px;
height: 184px;
overflow: hidden;
label {
display: block;
position: absolute;
bottom: 5px;
left: 18px;
width: 55px;
height: 55px;
z-index: 1;
}
input {
display: none;
}
}
#box-1{
display: block;
left: 100px;
bottom: 158px;
.box-game-inner {
position: absolute;
display: block;
width: 84px;
height: 184px;
overflow: hidden;
background: transparent url('https://www.kuronekoyamato.co.jp/ytc/img/404error_miss01.png') no-repeat 0 0;
background-size: auto;
background-size: 84px 12880px;
}
#checkbox1:checked ~ .box-game-inner {
animation: sprite-miss 3s steps(69) 0s forwards;
@keyframes sprite-miss {
0% {
background-position: 0 0;
}
100% {
background-position: 0 -12696px;
}
}
}
}
#box-2{
display: block;
left: 300px;
bottom: 27px;
.box-game-inner {
position: absolute;
display: block;
width: 84px;
height: 184px;
overflow: hidden;
background: transparent url('https://www.kuronekoyamato.co.jp/ytc/img/404error_hit01.png') no-repeat 0 0;
background-size: auto;
background-size: 84px 13248px;
}
#checkbox2:checked ~ .box-game-inner {
animation: sprite-hit 3s steps(71) 0s forwards;
@keyframes sprite-hit {
0% {
background-position: 0 0;
}
100% {
background-position: 0 -13064px;
}
}
}
}
}
※なお、Sassコンパイラをインストールしていない環境であれば、
とりあえずこれらのコードを適当なフォルダに配置し、ブラウザでindex.htmlを叩くと、以下のようなプログラムが走ります。
2つの箱をクリックしていただくと、2通りのアニメーションが始まると思います。
本家のミニゲームには、ゲームのスタート時に箱がシャッフルするステージと、カウントダウンタイマーなどの機能も実装されていますが、今回の記事ではこのミニゲームのもっとも基礎的なhtmlスプライトクリックでのイベントのトリガー方法と、png画像をスライドさせたアニメーションの基礎方法を解説します。
Cssでの(擬似)クリックイベント
本来、HTMLのスタイリングのために使われるCssではクリックやキー入力などのイベントを受け付ける機能は備わっていません。 そのため、イベントに対する処理を細かくやろうとするとJavascriptで補助なしでは無理なのですが、input要素とlabel要素を上手く組み合わせることで、擬似的なクリックイベントを発生させることが可能です。
この擬似クリックイベントの実装は難しくはなく、まず、
<style>
.hoge {
/* inputにチェックが入っていない時のスタイル */
}
要素のID名:checked ~ .hoge {
/* inputにチェックが入っている時のスタイル */
}
</style>
<input type=“checkbox” id="要素のID名">
<label for="要素のID名"></label>
<div class="hoge">...</div>
というlabelとinput要素と何かの後続要素(ここではdiv)を連続して仕込んでおき、input要素のチェック状態がOn・Offで切り替わるごとに、label要素直後にある後続要素が影響を受けて、スタイルも切り替わるという仕組みになっています。
実際の簡単な例をやってみると、
<style>
#pseudo-event:checked ~ .content-area {
color:red;
}
.content-area {
color:black;
}
</style>
<input type="checkbox" id="pseudo-event">
<label for="pseudo-event"></label>
<div class="content-area">
<p>チェックすると色が変化</p>
</div>
👇が動作するサンプル
とはいえ、サンプルを見ての通りで、この方法は単純なスタイルのON・OFFの制御しかできませんので、ちょっとでも複雑なゲームになるとCssだけでは制御が厳しくなります。
より複雑なゲームを作成したいのであれば、その場合には大人しくJavascriptでのプログラミングに切り替えた方が賢明といえます。
背景画像をスライドさせてアニメーション効果を付ける
擬似クリックイベントのテクニックと合わせて、チェック後にアニメーションを与えるスタイルを仕込んでおくと、Cssだけで動作する簡単なゲームも作れるわけです。
ミニゲーム内のソースコードを覗いてみますと、
この一見滑らかに動いているスプライトの動きは、cssの
animation
steps
@keyframes
background-position
このパラメータの組み合わせを正確に計算しておかないとパラパラ動画のタイミングがズレて見えたりしますので、フレームサイズとステップ数とアニメーション間隔の計算方法を考えてみましょう。
先程のリンク先のpng画像は、サイズが
168x25760
168x368

このpng画像の構造を踏まえた上で、画像をクリック時に適用されるcssアニメーションスタイルのコード部分だけを抜き出すと以下になります。
#box-1{
display: block;
left: 100px;
bottom: 158px;
.box-game-inner {
position: absolute;
display: block;
width: 84px;
height: 184px;
overflow: hidden;
background: transparent url('https://www.kuronekoyamato.co.jp/ytc/img/404error_miss01.png') no-repeat 0 0;
background-size: auto;
background-size: 84px 12880px;
}
#checkbox1:checked ~ .box-game-inner {
animation: sprite-miss 3s steps(69) 0s forwards;
@keyframes sprite-miss {
0% {
background-position: 0 0;
}
100% {
background-position: 0 -12696px;
}
}
}
}
まずクリック前の状態では、
background-size: 84px 12880px
84 x 184px
そしてチェックボックスがcheckedの状態になると、最初のフレームからアニメーション間隔3秒をかけて最後のフレームが見えるようになるまで、つまり
70 - 1 = 69
animation
69 / 3 = 23 fps
アニメーション設定と同時に
@keyframes sprite-miss
y = 184 - 12880 = -12696 px
ということで、このアニメーションが正しく描画されるためには、
+ 画像全体のサイズ
+ フレームサイズ
+ 総フレーム数
+ フレームレート
+ (アニメーション終了時の)キー位置
が全てあらかじめ計算の上で設定することで、あたかもリアルで動いているように見せることが出来ていたわけです。
まとめ
今回は主にHtml&Cssゲーム作成で使える基礎的なテクニックを解説してみました。
見ての通りでCssのスタイリングだけでゲームを開発するのは機能がかなり簡単なプログラムに限定はされますが、HtmlとCssだけあればあとはアイデア次第で簡易ゲームが動かせる!ということに色々と面白い応用の可能性を感じます。
参考サイト
記事を書いた人
ナンデモ系エンジニア
主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。
カテゴリー