こんにちは。
JavaScriptさわってみる企画11回目です! 結構やりましたね~。手持ちの本を見ると基本部分はだいたい終わってる感じです。いよいよ最終回か!?
たぶんですけど今までやったことだけでも内容によってはゲームが作れないこともないと思うんですよ(トランプゲームとか)。
ゲームってごく単純化して考えると
① 入力:ボタンを押すなど
② 計算:条件分岐など
③ 出力:画像表示など
の繰り返しでしかないんですよね。
9回目でやったイベントハンドラは①や②ですし10回目でやったCanvasは③、2~5回目でやった分岐、ループ、演算なんかは②ですね。1回目でやった内容はボタンを押すと入力した内容が表示されるってものですからいちおう①~③までやってるわけです。
しかしゲームらしいゲームを作ろうと思ったらまだ触れていないある要素が絶対に必要になると思います。
それは時間です。
(音声だと思った方! それも正解ですね!!)
今回はJavaScriptに時間の概念を吹き込むタイマーメソッドをさわってみます。
※免責
この記事は初心者がやってみた、というだけの内容なので間違ったことを書いている可能性が多分にあります。ご了承ください。
タイマーメソッド↓
setTimeout(①,②) : ②ミリ秒後に関数①を呼び出す。
clearTimeout(①) : setTimeoutで処理中のタイマー①を停止。①はsetTimeoutの戻り値。
setInterval(①,②) : ②ミリ秒毎に関数①を呼び出す。
clearTimeout(①) : setIntervalで処理中のタイマー①を停止。①はsetIntervalの戻り値。
ネットを調べてみたところ、これら以外にも時間を使った処理をするにはgetTimeメソッドなど"Dateオブジェクト"というものを使う方法もあるようです。
前回のさわってみる企画で作ったマウス位置に線を描くスクリプトに時間(タイマー)を加えてアニメーションさせてみます。
中身の前に完成したものからお見せします。
グレーの部分をクリックまたはタップするとそこから円が大きくなるアニメーションが表示されるというものです。さらにクリック/タップの位置が中央あたりだった場合は画像も表示されます。
クリックした座標
コマ
ちなみに止める機能はつけておりませんのでどうしても止めたい場合はブラウザのページを閉じるか更新してもらう必要があります(・∀・)<先に言えよ
中身↓
<style>
#area {background-color:gray; width:400px; height:300px;margin-top:0px}
#posi2 {background-color:lightgreen;width:400px;margin: 0px; padding:0px;}
#posi3 {background-color:yellow; width:400px;margin: 0px; padding:0px;}
</style>
<script>
let ctx;
let i=1;
let timer;
let xx;
let yy;
window.onload = function () {
document.getElementById("area").onclick = clickedposition;
const canvas = document.getElementById("area");
ctx = canvas.getContext("2d");
ctx.strokeStyle = "#00FFFF";
ctx.lineWidth = 10;
}
const maru = function(){
document.getElementById("posi3").textContent = "コマ" + i;
ctx.clearRect(0,0,400,300)
ctx.beginPath();
ctx.arc(xx,yy,i,0,2*Math.PI);
ctx.stroke();
ctx.closePath();
if (xx>=170 && xx<=230 && yy>=130 && yy<=170){
ctx.drawImage(pic,xx-i/2,yy-i/2,i,i)};
i++;
if(i>=100){i=1};
}
function drawmaru(){
clearInterval(timer);
timer = setInterval(maru,10);
}
function clickedposition(e) {
document.getElementById("posi2").textContent = "クリックした座標 X=" + e.offsetX + ", Y=" + e.offsetY;
xx = e.offsetX;
yy = e.offsetY;
drawmaru();
}
</script>
<body>
<img id ="pic" src="https://cdn.profile-image.st-hatena.com/users/icedtomatobazooka/profile.png?1597500718" style="display:none"/>
<p id="posi2">クリックした座標</p>
<p id="posi3">コマ</p>
<canvas id="area" width="400" height="300"></canvas>
</body>
それぞれの関数の役割↓
clickedposition(e):クリック/タップしたとき座標を取得してdrawmaruを呼び出す。
drawmaru:10ミリ秒毎に関数maruを呼び出す。
maru:実行される度に大きさを変えて円を描く。
関数drawmaruの中でタイマーメソッドのsetIntervalを使っていますがポイントとなるのは関数maruのほうで、まずは実行される度に値が増える変数iを使っていること。i++;と書いておくと実行される度に1ずつ増えるので描く円の半径のところにiを使って円を大きくしています。永遠に増加させると円が大きすぎになってcanvasエリアに収まらなくなるので最後に100以上になったら1に戻す、としています。
それから円の中心座標は広域変数を使っていること。引数で値を渡したときは1度しか実行されず、繰返しは動きませんでした。
途中にあるif(xx>=170~のところはクリック/タップが中心付近だったら画像も表示するってところです。
今回のテーマからは少し脱線しますがcanvasでの画像表示はHTMLで記述しておき、drawImageでそのidを指定します。
drawImage(①,②,③,④,⑤);
①:id ②x座標 ③y座標 ④幅 ⑤高さ
④、⑤は省略可能で省略すると元サイズで表示されます。
そしてbody部分にこれを入れる↓
<img id = ”①" src = "②" style="display:none"/>
①は任意のid名でdrawImageの①と一致する。②は画像URL。style="display:none"を入れないとそこに表示されます。
画像を拡大させるとき、左上を原点として右下に伸びるように拡大されるので画像の中心から上下左右均等に拡大させるために拡大する半分のスピードで左上に移動させてやってます(drawImageの座標をxx-i/2,yy-i/2としているところ)。
直接的に画像の中心を原点にできるのかは知りませんがこういう「ちょっと強引か?」って思う実装方法はゲーム制作ではよくあることです(たぶん)。
今回の学習内容はこんなもんです。ところで今回見たままモードで編集したのですがJavaScript動いてますね? 黄色とグレーの間にp要素が勝手に入ってしまいますがそれ以外は何も問題なさそうです。よくわかりませんが動いてるからいっか(;^ω^)
らくがき。