第5回 エディターが学ぶ初めてのプログラミング(JavaScript編 関数の実行タイミングを定める)

先日、自分の口癖が「ちなみに」であることに気づいたエディター若栁です。
エディターが学ぶ初めてのプログラミングの第5回。第4回に続き、今回もスロットゲームを改修していきます。

今回着手するのは、画像の切り替わり処理の部分。今はsetTimeout()を使って、以下のように書いています。

上で使っているsetTimeout()以外にも、JavaScriptには処理のタイミングを決めるメソッドがあります。

  • setTimeout:指定した時間が経過したら、関数を呼び出して1回だけ実行する
  • setInterval:指定した時間の間隔で、関数を呼び出して繰り返し実行する←今回はこちらを使ってみます。

setIntervalは、設定した秒数の間隔で、関数を呼び出して実行させます。
設定をオフにするまで、5分おきとか8分おきに鳴り続ける目覚ましアラームのイメージです。
読みは、せっといんたーばる。フォントによって、大文字のIと小文字のlが区別しにくい時もありますのでお気をつけ下さい。

よし、じゃあsetTimeoutをsetIntervalへ置き換えてみよう!と書いたコードがこちらです。
(注意)以下のコードは間違った例なので実行しないでください(注意)

動きました、最初の数秒だけ。

その後は動作が重くなり、画像は切り替わらない上、画面を閉じるのにも数秒かかる始末。7行目と8行目をよく見ると、

start_slot()の中で、さらに0.08秒ごとにstart_slot()を呼び出しているため、処理が重複しています。その結果、何度も同じ処理が走っていました。

以下で、ランダムな画像を表示させるための関数slotting()を新たに作り、start_slot()の外に出しました。

これで、処理が重くなることなく順調に動きました。次は画像切り替えを止める処理へ移ります。

setIntervalは、「もうやめていいよ」という指示が飛ぶまで、指定の間隔で関数を実行し続けます。
この「もうやめていいよ」にあたるのが、clearIntervalです。設定した間隔をclearして、処理を止めます。
setTimeoutはclearTimeoutと、setIntervalはclearIntervalとセット、と覚えるとよさそうです。

今回は先に、完成形のコードを載せます。

start_slot()もstop_slot()も、数行増えていますが追って説明します。まずは24行目のclearIntervalから。

「setInterval(slotting, 80) で動いているんだから、clearInterval(slotting)じゃだめなの?」と思った方。
だめなんです・・・setIntervalで始めた処理を止めるには、setIntervalの戻り値をclearIntervalに入れる、のが正解。
本ブログの第2回ではこの点に触れなかったのですが、setTimeoutも同じです。

戻り値とは

プログラムが処理された後に、戻ってくる値のこと。
返り値とも言うようですが英語だとreturnなので、どっちでも良さそう。このブログでは戻り値、で統一します。

今回は変数timerIDで戻り値を受け取って、スロット動作の制御にも使っています。
以下、コメントアウトして、どういう処理をしているかを補足します。

timerIDに入っている値が、nullかそれ以外かで、スロットが止まっているか動いているか、も判断できるようになりました。
結果、もともとあった以下の不具合も解消されました。

  • あたりが出た画面でストップボタンを押すと、あたり判定が出てしまう。
  • スタートボタンを押した数だけ、絵柄の切り替わりが早くなる。

これで最初に作ったスロットよりも、完成度が高くなりました。やった!!
今回はsetIntervalとclearIntervalを扱ってみました。