なぜ要るか
前の術で1枚絵ができました。置いてみると、ちゃんとゲームらしくなります。
でも動きません。 何度遊んでも、まったく同じ顔でこちらを見ています。
ここで多くの人が「動かすには何十枚も絵が必要だ」と考えて止まります。違います。 1枚のまま、顔を左右上下に向けられます。しかも追加の道具は要りません。
使うのはCSSの傾きだけです。3行で済みます。
使う道具: なし(1枚絵とブラウザだけ)
AIプロンプト
この術の作業をAIへ任せるときは、これをそのまま貼ってください。
index.html のキャラ絵に、カーソルを追って顔が向く動きを付けて。CSSの perspective と rotateY/rotateX で、絵は1枚のまま。振り幅は左右14度・上下10度、動きは0.4秒の ease-out。それ以外は変えないで。
振り幅の14度と10度は、自分の絵で気持ちよかった数字に置き換えてください。
板を傾けているだけです
先に仕組みを言います。やっているのは、絵を板として傾けることだけです。
顔のパーツを動かしているわけではありません。1枚の板を、奥行きのある空間に置いて回している。それだけです。
なのに、なぜ顔が「向いた」ように見えるのか。人間は、遠近が付いた顔を「向き」として読むからです。左側が縮んで右側が広がれば、脳が「左を向いた」と解釈します。
実際にやったものがこれです。同じ char.png 1枚で、左向きと右向きです。
2枚とも同じ画像ファイルです。 傾きの角度だけが違います。
やってみる
絵を「奥行きのある入れ物」に入れる
index.htmlのキャラの部分を、こうします。<div class="chara"> <img id="charaImg" src="char.png" alt="対戦相手のこより"> </div>divは中身をまとめるための箱、imgが絵そのものです。箱で囲んでおくと、箱と絵に別々の動きを付けられます。CSSはこれだけです。3-2で決めたとおり1ファイル構成なので、
index.htmlの中にある<style>の内側へ書きます。.chara { width: 240px; perspective: 600px; } .chara img { width: 100%; display: block; transition: transform .4s ease-out; }perspectiveが奥行きです。 これを書くと、その箱の中が「手前と奥がある空間」として扱われます。これが無いと、傾けても平べったく潰れるだけで「向いた」ようには見えません。数字が小さいほど遠近が強くつきます。向きを変える関数を1つ書く
var charaImg = document.getElementById('charaImg'); function faceTo(x, y) { charaImg.style.transform = 'rotateY(' + (x * 14).toFixed(1) + 'deg) rotateX(' + (-y * 10).toFixed(1) + 'deg)'; }こちらは動きなので、
index.htmlの<script>の内側へ書きます。1行目で、charaImgという名前を付けた絵をコードから触れる形で取り出しています。rotateYが縦の軸を中心にした回転で左右の向きになり、rotateXが横の軸を中心にした回転で上下の向きになります。degは角度の単位です。xとyは -1 から 1 で渡します。faceTo(1, 0)で右を向き、faceTo(-1, 0)で左を向きます。14と10が振り幅です。 ここが今回いちばん大事な数字なので、あとで自分で触ってください。カーソルを追わせる
document.addEventListener('mousemove', function (e) { var x = (e.clientX / window.innerWidth) * 2 - 1; var y = (e.clientY / window.innerHeight) * 2 - 1; faceTo(x, y); });画面のどこにカーソルがあるかを -1〜1 に変換して、そのまま渡しています。
e.clientXがカーソルの横位置、window.innerWidthが画面の横幅です。割ると 0〜1 になり、2倍して1を引くと、左端が -1、中央が 0、右端が 1 になります。mousemoveは、マウスが動くたびにこの中身を呼び出す仕掛けです。開いて、マウスを動かす
open index.htmlブラウザにゲームの画面が出ます。その上でカーソルを左右に振ってください。顔がついてきます。
ここで「思ったより動かない」と感じたら、次を読んでください。それが正常な反応です。
仕組みが分かったので、次のキャラからはまとめて頼めます。
claude -p "index.html のキャラ絵に、カーソルを追って顔が向く動きを付けて。CSSの perspective と rotateY/rotateX で、絵は1枚のまま。振り幅は左右14度・上下10度、動きは0.4秒の ease-out。それ以外は変えないで。"数字まで指定しているのに注目してください。 この術で自分の手で見つけた数字は、そのまま次からの指示になります。
保存する
git add . git commit -m "1枚絵の顔が左右上下を向くようにした" git push
小さく表示すると、傾きは見えません
これは僕が実際にやって気づいたことです。
最初、キャラを 180px で表示していました。角度は同じ14度です。まったく分かりませんでした。 動いている実感がゼロでした。
同じコードのまま 320px にしたら、はっきり向くようになりました。
理由は単純で、傾きは画面上の「ずれた量」でしか知覚できないからです。絵が小さければ、14度傾けてもずれる量は数ピクセルしかありません。
対処は3つあります。上から順に試してください。
| 対処 | やり方 |
|---|---|
| 大きく表示する | いちばん効く。240px以上を目安にする |
| 角度を強める | 14 を 20 くらいまで上げる |
| 顔を大きく写す | 絵の余白を切り詰めて、顔の割合を上げる |
逆に、角度を30度以上にすると「板が回った」とバレます。 顔の向きではなく紙が回転しているように見えます。上限は20度くらいと考えてください。
動きの「時間」で生きて見えます
もう1つ、効くのに見落とされやすいものがあります。動く速さです。
上のCSSにこれが入っています。
transition: transform .4s ease-out;
これを消すと、顔がカクッと瞬間移動します。同じ角度でも、生き物に見えなくなります。
0.4秒かけて、しかも終わりが緩やかに減速する(ease-out)。これで「首を回した」ように見えます。角度より、この0.4秒の方が効きます。
本格的にやると何が違うか
正直に書きます。この方法は板を傾けているだけなので、限界があります。
本物の3Dのように見せるには、絵をパーツに分解して、パーツごとに違う量だけ動かします。前髪は大きく、顔は中くらい、後ろ髪は小さく。このずれが立体感を作ります。
僕はここまでやる場合、see-through で1枚絵をレイヤーに分解して、simple-puppet で動かしています。実際、この講座の公開版の三つの的でも、こよりを simple-puppet へ移して、瞬きと首の揺れを入れています(講座の範囲外のおまけです。板を傾けるだけでも十分に成立します)。
別作品のCNPトレカで使っている咲耶を分解したときは、こういう単位に分かれました。
前髪 / 後ろ髪 / 顔 / 白目 / 瞳 / まつげ / 眉 / 口 / 首 / 上衣 / 下衣 / 手 / 足
隠れて見えない部分まで描き足された状態で出てきます。だから顔を横に向けても、後ろ髪の裏に穴が空きません。
レイヤーは、絵を何枚かの重ねた板に分けたもののことです。分解にはGPU(画像の計算が得意な部品)を時間貸しで借りる必要があるので、1キャラあたり数百円と1時間くらいかかります。
最初の1本には要りません。 板を傾けるだけで、キャラは十分に生きます。パーツ分解は「このキャラで長く遊ぶ」と決めてからで間に合います。
つまずきどころ
傾けても何も変わらない
perspective が抜けています。これは親要素(.chara)に書きます。img 側に書いても効きません。
呼吸のような上下運動と喧嘩する
キャラを上下にゆっくり揺らす(呼吸)を足すと、傾きが消えることがあります。transform は1つしか持てないためです。あとから書いた方が前を打ち消します。
解決は入れ子にすることです。外側の div で揺らし、内側の img で傾ける。 上のHTMLが最初から2階層になっているのはこのためです。
顔ではなく体ごと傾いてしまう
そのとおりで、絵ごと傾いています。気になる場合は rotateX を弱めて(10 → 5)、左右の動きを主にしてください。左右は違和感が出にくいです。
スマホで動かない
mousemove はカーソルがある環境のイベントです。スマホでは指の位置で動かすか、ゲームの状況(勝った・負けた)に応じて向きを変える方が自然です。状況で動かす方は4-6でやります。
Windows の場合
コードは同じです。open index.html の代わりに start index.html を使ってください。
次の一歩
14 と 10 の数字を変えて、自分の絵で気持ちのいい角度を探してください。
20 まで上げてみると、どこから「板が回った」に見え始めるかが分かります。その境目を1回見ておくと、以降どのキャラでも迷いません。
顔が向いただけで、もう相手が「見ている」感じが出ます。次はまばたきと口を付けて、生きているところまで持っていきます!
ここまでの三つの的
この講座は、見本ゲーム「三つの的」を術ごとにすこしずつ育てながら進みます。下にあるのはこの術を終えた時点の実物です。そのまま遊べます。
