【ステージ#6】 マウス操作に関するプログラミング問題

《難易度★★★》マウスに反応した動作をさせるスキルを試すプログラミング問題です。あわせて一定時間ごとに処理させることによるアニメーションも扱います。

問題

つねにマウスカーソルと同じ位置にボールが表示されるプログラム(HTML,CSS,JavaScript)がすでに用意されています。これをベースとして、以下の問題の指示にしたがってコードを追加・修正しなさい。

  • 問題6-1:ボールがマウスカーソルの動きにちょっと遅れてついてくるようにしなさい
  • 問題6-2:10個のボールがぞろぞろついてくるようにしなさい
  • 問題6-3:10個のボールが勝手にぐるぐる動くようにしなさい

See the Pen ステージ#6問題 by programmingbird (@programmingbird) on CodePen.

問題コード(JavaScript)の確認

// マウスの座標を入れる変数の準備 まずマウスのx座標とy座標を入れておくために「連想配列」を作っている。こうしておくと、mousePoint.xとかmousuPoint.yと書くことでそれぞれの値を取り出せるようになる。初期値としてnullを入れている。nullは「値が存在しない」という意味。

// Ballクラスの定義 が重要。targetを指定するとそれを追いかける、Ballというクラスを作ってるようだ。Ballにはボールを表示させるdrawというメソッドと最新の表示位置を計算するupdateというメソッドを持たせている。

//「トリガー①」の設定 マウスがちょっとでも動いたら関数mouseMoveを呼び出す。mouseMoveはちょっと先の//「アクション①」の設定に書いてあってさっき用意したmousuPointに、現在のマウスのx座標とy座標をセットする処理。

//「トリガー②」の設定 ここで実質的にプログラムをスタートさせている。まずballという名前でBallクラスのインスタンスを作ってる。その際、targetとしてmousuPointを指定している。これでマウスの位置を追いかけるようになる。続けてボールの表示をして、最後にタイマーをセット。10だから10ミリ秒ごとにloopを呼び出す。loopは//「アクション②」の設定に書いてる。いわゆるメインループで画面をいったんクリアし、ballの座標計算とボールの表示を行う。

問題6-1の解説と解答例

解説(発想のしかた)

【クラスのメソッド】「ちょっと遅れてついてくる」ってどうしたらいいか? ボールの動き方を決めているBallクラスのupdateメソッドを改良しよう。x,yともに、現在の「ボールの座標とターゲット(マウスカーソル)の座標の差の10%」だけ近づける、みたいな感じにしてみよう。

update: function() {
    this.x += (this.target.x - this.x) * 0.1;
    this.y += (this.target.y - this.y) * 0.1;
}

解答例

See the Pen ステージ#6問題6-1 by programmingbird (@programmingbird) on CodePen.

問題6-2の解説と解答例

解説(発想のしかた)

【トリガー②】10個のボールがぞろぞろ?さあどうしょう。同じようなものをたくさん取り扱う場合は配列を使うとよさそう。それぞれのボールのtargetについては、最初の1個だけは、問題6-1と同じでmousePointだけど、それ以降の9個は自分より1つ前のボールをtargetにして追いかけることになる。

var balls = [];
for (var i = 0; i < 10; i++) {
  var target = mousePoint;
  if (i > 0) {
    target = balls[i - 1];
  }
  var ball = new Ball(target);
  ball.draw();
  balls.push(ball);
}

【アクション②】loopの中のボールのupdateとdrawを呼び出す部分も、忘れずに配列に書き直して10個分ちゃんと座標計算と表示が処理されるようにしておく。

for (var i = 0; i < 10; i++) {
    balls[i].update();
    balls[i].draw();
}

解答例

See the Pen ステージ#6問題6-2 by programmingbird (@programmingbird) on CodePen.

問題6-3の解説と解答例

解説(発想のしかた)

10個が勝手にぐるぐる!要は先頭のボールのtargetになってるmousePointをマウスの動きに対応させるんじゃなくて、別途勝手にぐるぐる動かしてあげればよさそう。まずは、マウスが動くたびにmousePointにマウスカーソルの座標をセットする関数mouseMoveとcvsにイベントリスナーを追加していた行を削除する。あわせて「ぐるぐる動かす」のに三角関数を使うので角度を表す変数、とりあえずaという名前でmousePointに追加しておく。初期値はa,x,yとも0で。

var mousePoint = {
  x: 0,
  y: 0,
  a: 0
};

【アクション②】loopにmousePointをぐるぐる動かす処理を追加する。角度aをちょっとずつ増やすことで先頭のボールがぐるぐる回る。その他のボールは問題6-2のまま、順に前のボールについてくる。

解答例

See the Pen ステージ#6問題6-3 by programmingbird (@programmingbird) on CodePen.