カテゴリー
【Sassで作るCssミニゲーム】Cssミニゲームで使えるアニメーションテクニックの基礎
※ 当ページには【広告/PR】を含む場合があります。
2021/07/30
2023/12/20

CSSで動きのあるミニゲームを作るとなるとどうしても避けて通れないのがCSSアニメーションです。
純粋なCSSでアニメーション効果をつけるには
transition
animation
この記事では、この二つのプロパティの使い方を比較し、長所短所を説明してから、効果的に利用する方法を検討していきます。
transitionを使ったCSSゲームの基礎
まずは以下のようにインプットチェックボックスを使ったメンタコが動くだけのCSSアニメーションを操作してみてください。
実装の中身
先程のCSSプログラムの中身を見ていきます。
まずは核になるhtml要素のコードは以下です。
<div id="wrapper">
<input type="checkbox" id="move1">
<input type="checkbox" id="move2">
<input type="checkbox" id="move3">
<label for="move0">0</label>
<label for="move1">1</label>
<label for="move2">2</label>
<label for="move3">3</label>
<div class="mentaco"></div>
</div>
ここでもやはりCSSゲームの基礎テクである通称
このhtmlに割り当てているのはCssパートは以下です。
#wrapper {
width: 100%;
height: 300px;
background-color: darkgray;
box-sizing: border-box;
position:relative;
.mentaco{
position: absolute;
display: block;
padding: 0 0 0 0;
transition: all 1s cubic-bezier(.68,-0.55,.27,1.55);
top: 20px;
left: 0;
width: 80px;
height: 72px;
background: transparent url('https://raw.githubusercontent.com/tacoskingdom/commonBlogMaterial/main/deep-tacopots/blog116/mentaco.png') no-repeat 0 0;
background-size: 80px 72px;
}
#move1:checked ~ .mentaco {
transform: translateX(120px) translateY(120px);
}
#move2:checked ~ .mentaco {
transform: translateX(90px) translateY(-20px);
}
#move3:checked ~ .mentaco {
transform: translateX(200px) translateY(10px);
}
input {
position: absolute;
top: 0px;
&#move1 { left: 0px; }
&#move2 { left: 20px; }
&#move3 { left: 40px; }
}
label {
background-color: aqua;
width: 20px;
height: 20px;
display: block;
border-radius: 50%;
position: absolute;
z-index: 1;
text-align: center;
&[for="move0"] { top: 46px; left: 28px; }
&[for="move1"] { top: 165px; left: 148px; }
&[for="move2"] { top: 22px; left: 118px; }
&[for="move3"] { top: 55px; left: 228px; }
}
}
プログラムの解説
transitionを使ったアニメーションはデモを動かしてもらった通り、現在のアニメーションターゲット要素の位置と行き先の
2点間
またチェックボックスをオンオフしても分かるように、
往復
transitionを使ったアニメーションはこの特性ゆえに、CSSプログラムを実装する分には理解しやすいというメリットがあります。
つまりチェックボックスのオンオフフラグを上手く利用することで、メンタコのスプライトを好きな2点間で自由に移動させることができます。
例えば
2 --> 0
1 --> 3
モダンなtransitionの記述法
先程のCSSスタイルの一例で見ていただいた通り、
transform
例えば、先述のスタイルに回転移動と拡大縮小の値を追加で設定したものは以下のようになります。
#move1:checked ~ .mentaco {
transform: translateX(120px) translateY(120px) rotate(45deg) scale(1.4);
}
#move2:checked ~ .mentaco {
transform: translateX(90px) translateY(-20px) rotate(-72deg) scale(0.9);
}
#move3:checked ~ .mentaco {
transform: translateX(200px) translateY(10px) rotate(132deg) scale(1.2);
}
こういったワンライナー(一括指定)で順序が重要となる値を記述するCSSプロパティは
border
そこら辺の事情も鑑みらてたのか、従来のワンライナー指定の代替として、値の個別も指定できるようになっています。
#move1:checked ~ .mentaco {
translate: 120px 120px;
rotate: 45deg;
scale: 1.4;
}
#move2:checked ~ .mentaco {
translate: 90px -20px;
rotate: -72deg;
scale: 0.4;
}
#move3:checked ~ .mentaco {
translate: 200px 10px;
rotate: 192deg;
scale: 1.2;
}
これを試してみると、従来の
tranform
なお、
transform
translate
rotate
scale
skew
matrix
animationを使ったCSSゲームの基礎
座標値や通過時間などを細かく定義することで、複雑な曲線軌道をうごくアニメーションも定義することができますが、その分より複雑なCSSコードを実装しなければならないのが難点です。
先ほどのtransitionで使ったデモプログラムを少々改造してanimationを使ったプログラムに仕立て直したものが以下です。
デモプログラムの中身
こちらも先ほどのように中身を見ていきましょう。
html部は以下のようになります。
<form id="wrapper">
<input type="reset" value="リセット">
<input type="checkbox" id="move1">
<input type="checkbox" id="move2">
<input type="checkbox" id="move3">
<label for="move0">0</label>
<label for="move1">1</label>
<label for="move2">2</label>
<label for="move3">3</label>
<div class="mentaco"></div>
</form>
今回のポイントは
form
以下がcssスタイルコードになります。
#wrapper {
width: 100%;
height: 300px;
background-color: darkgray;
box-sizing: border-box;
position:relative;
.mentaco{
position: absolute;
display: block;
padding: 0 0 0 0;
top: 20px;
left: 0;
width: 80px;
height: 72px;
background: transparent url('https://raw.githubusercontent.com/tacoskingdom/commonBlogMaterial/main/deep-tacopots/blog116/mentaco.png') no-repeat 0 0;
background-size: 80px 72px;
}
#move1:checked ~ .mentaco {
animation: xy1 2s cubic-bezier(.45,.05,.55,.95) forwards;
@keyframes xy1 {
0% {
top: 20px;
left: 0px;
}
30% {
top: 50px + 20px;
left: 280px;
}
70% {
top: 170px + 20px;
left: 200px;
}
100% {
top: 120px + 20px;
left: 120px;
}
}
}
#move2:checked ~ .mentaco {
animation: xy2 2s cubic-bezier(.45,.05,.55,.95) forwards;
@keyframes xy2 {
0% {
top: 120px + 20px;
left: 120px;
}
30% {
top: -40px + 20px;
left: 150px;
}
70% {
top: 50px + 20px;
left: 10px;
}
100% {
top: -20px + 20px;
left: 90px;
}
}
}
#move3:checked ~ .mentaco {
animation: xy3 2s cubic-bezier(.45,.05,.55,.95) forwards;
@keyframes xy3 {
0% {
top: -20px + 20px;
left: 90px;
}
30% {
top: 140px + 20px;
left: 70px;
}
70% {
top: 110px + 20px;
left: 190px;
}
100% {
top: 10px + 20px;
left: 200px;
}
}
}
input {
position: absolute;
top: 0px;
&#move1 { left: 0px; }
&#move2 { left: 20px; }
&#move3 { left: 40px; }
&[type="reset"] {
left: 80px;
}
}
label {
background-color: aqua;
width: 20px;
height: 20px;
display: block;
border-radius: 50%;
position: absolute;
z-index: 1;
text-align: center;
&[for="move0"] { top: 46px; left: 28px; }
&[for="move1"] { top: 165px; left: 148px; }
&[for="move2"] { top: 22px; left: 118px; }
&[for="move3"] { top: 55px; left: 228px; }
}
}
ブログラムの解説
先ほどのanimationのでもプログラムを触ってもらうと実感して分かると思いますが、transitionアニメーションとは異なり、このアニメーションは
一方通行
このことがtransitionアニメーションとの大きな違いであり、アニメーションの巻き戻しは自動ではおこなえません。 デモプログラムでいうと、チェックボックスを順番にクリックして、
0 > 1 > 2 > 3 > [リセット]
よってもし逆再生のアニメーションが必要になる場合には、新しくアニメーションフレームを定義して、html要素に割り当てる必要あります。
このanimationプロパティの
再生不可逆
そこだけ考えてもanimationの実装の労力は2倍であり、更に
@keyframes
とはいえ、animationの持つ高度なアニメーションの表現力は魅力的であり、華やかな演出をWebサイトにもたらすことで、他のサイトにはない印象で集客性に差をつけることも可能かもしれません。
結論
以上、アニメーションをCSSゲームに取り入れる時に念頭においておきたいポイントとしては、
+ CSSアニメーションには、transitionかanimationを使う
+ transitionを使うと2点間を往復するアニメーションが作れる
+ animationを使うと始状態から終状態まで@keyframesで定義したアニメーションが作れる
+ transitionはアニメーションの逆再生(巻き戻し)ができるが、
animationは巻き戻しできない
+ transitionは2点間を直線的にしか移動できないが、
animationはフレームごとに定義した座標を通過するパスで
細かくアニメーション軌道上を移動できる
+ CSSアニメーションを作る際には、transitionとanimationを混ぜない方がベター
基本は作りたいアニメーションがtransitionで出来そうならばtransitionで作成し、どうしてもtransitionで実現しそうにない動きになるならばanimationを使うように実装していくと良いでしょう。
参考サイト
記事を書いた人
ナンデモ系エンジニア
主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。
カテゴリー