「tmlib.js 怒濤の 100 サンプル!!」を試す その94

更新が遅くなりました。
その94。

tmlib.js 怒濤の 100 サンプル!! – Graphics(HTML5 Canvas) 編

今回試すサンプルは「図形(上級)」の「パックマンを描画しよう」です。
ではサンプルが掲載されているのでまずは見てみましょう。
中央のボタンを押してみて下さい。
口をパクパクさせる黄色の円が描画されたと思います。

/*
* 定数
*/
var SCREEN_WIDTH = 465;
var SCREEN_HEIGHT= 465;
var RADIUS       = 128;

tm.main(function() {
// canvas インスタンス生成
var canvas = tm.graphics.Canvas("#world");

// 幅, 高さを指定
canvas.resize(SCREEN_WIDTH, SCREEN_HEIGHT);
// 画面にフィットさせる
canvas.fitWindow();

// 色を指定
canvas.setFillStyle("yellow").setStrokeStyle("yellow");
// 座標系を中心に移動
canvas.setTransformCenter();

// アニメーション
var x = 0;
var offset = 0;
var frame = 270;
tm.setLoop(function() {
// 画面クリア
canvas.clearColor("black");
// 塗りつぶし描画
canvas.save();
canvas.translate(x, 0);
canvas.beginPath().moveTo(0, 0).arc(0, 0, RADIUS, Math.degToRad(0+offset), Math.degToRad(360-offset), false).fill();
canvas.restore();

// 移動
if ((x+=4) > 400) { x = -400; }

// パクパク
offset = ((Math.sin( Math.degToRad(frame*10) )+1)/2)*45;
++frame;
}, 1000/60);
});

前振りとして、パックマンを知らない人がいるかもしれませんので、一言で説明すると昔人気のあったゲームキャラです。検索するとすぐ見つかりますよ。
そう思うとゲームの一部を再現しているわけでちょっとワクワクしませんか?

では本題へ。
今回のサンプルは今までのものと比べて難しいというわけではありませんが、記述方法が少し変えてあります。
慣れるまでは自分のやりやすい方法で勉強したほうがいいと思います。

6行目

「 RADIUS 」という変数を定義し、「 128 」という数値を設定しています。
これはパックマンの半径を決める数値になります。

18行目

記述方法が変えてある行の1つ目がココです。
塗りつぶし描画の色と、ストローク描画の色を指定する2つの指示を1行で記述しています。
このように複数の指示(メソッド)を連続して述方法を「 メソッドチェーン 」と言います。
前述した通リ慣れないと混乱しがちになりますのでこういう方法もあると覚えておくだけでいいかと思います。
jQuery等ではよくみる記述方法です。
ちなみに分解して記述すると以下のようになります。

canvas.setFillStyle("yellow");
canvas.setStrokeStyle("yellow");

 

20行目

これは以前勉強した通リ座標の原点を画面中央にするよう指示しています。

22~25行目

アニメーションさせるための変数を定義しています。
23行目の「 x 」は横移動する際に使われます。
24行目の「 offset 」はパクパクさせる口の始点と終点を計算する際に使われます。
25行目の「 frame 」はパクパクという動作を行わせるのに使われます。

26行目

tm.setloop 」で囲われた内容を繰り返し処理を記述します。

28行目

背景を黒に指示するとともにパクパクという動作を描画したらそのまま残ってしまいますのでそれを消去するという処理も含めて指示しています。
言葉よりも体感するのがわかりやすいです。
この行だけコメントアウトしてみて実感してみてください。

30行目

現在の状態を保存しています。
現在の状態というのは背景を黒にし何も描画されていない状態のことを指します。

31行目

パックマンの移動指示はこの行が行なっています。
36行目は後述しますがあくまでX座標を決めているだけです。
x 」という変数に格納されている数値に従って移動処理を行なっているというとわかるでしょうか。

32行目

記述方法が変えてある行の2つ目です。
18行目と同じように「 メソッドチェーン 」を使って1行で記述されています。
分解すると処理内容がわかりやすいかと思います。

canvas.beginPath();
canvas.moveTo(0, 0);
canvas.arc(0, 0, RADIUS, Math.degToRad(0+offset), Math.degToRad(360-offset), false);
canvas.fill();

描画の開始を宣言し、
描画の開始座標を決めて、
円弧を描画するようにしパラメータを決め、
実際に描画する。

円弧を描画する所が肝ですね。
パラメータはドキュメントには「 x, y, radius, startAngle, endAngle, anticlockwise 」のようになっています。
訳すと「 X座標, Y座標, 半径, 開始角度, 終わり角度, 反時計回り(回転方向) 」になります。
XY座標は「 0 」ですので中心に、半径は6行目で定義した値が、開始角度には0に「 offset 」を足したものをラジアンに変換し、終わり角度は360から「 offset 」を引いたものをラジアンに変換し、反時計回り描画するように指示しています。
上唇と下唇の位置を計算で出しているわけですね。

33行目

30行目で保存した状態へと戻しています。

36行目

このif文ですが条件式の中に括弧がありますので先にそこから計算します。
x += 4 」これは「 x 」という変数に「 4 」を足してその答えを「 x 」として格納することを表します。
そしてその「 x 」が400を超えていたら「 -400 」という値を格納するようになっています。
この「 x 」がループしたときの31行目の移動処理に使われますのでX座標が4づつ増えるということは画面右方向に移動するということになります。
400を超えたらというのはパックマンの大きさを考慮して画面右端に到達したらまた左端から現れるようにするためのものです。

39~40行目

上記の処理を終えたら次の口の大きさを決めるために三角関数を用いて計算しています。
基準点の0度からどの程度口を開けるのかというのを「 frame 」という変数を使用していますが、三角関数がうろ覚えのため割愛させてください。
単純に「 frame 」を元に正弦(sine(サイン))を求め口の大きさを決めています。
40行目で「 frame 」をインクリメント(1づつ足す処理)を行なっていることからループごとに口の大きさに変化を与えてパクパクするように見えるわけです。

工業設計の教科書でも読みなおそうと思います…


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です