javascript

/

純粋なJavascriptでのブロック崩しの作り方④

純粋なJavascriptでのブロック崩しの作り方④ のサムネイル

やりたいこと

フレームワークやライブラリを使わず、純粋なjavascriptのみでブロック崩しを作る。

今回は第4回目となり、ユーザーが操作できるパドルを追加するところまでやっていきましょう!

前回はボールが移動する処理まで作成しました↓

現状ではボールが跳ね返っているのを眺めることしかできず、ゲームとしては面白くありませんね!
操作するパドルを追加してあげることで、ゲーム性が格段にあがると思います。
ではさっそくやっていきましょう!

環境

  • Google Chrome : Version: 130.0.6723.92
  • VSCode : Version : 1.90.2 (Universal)

パドルの追加

パドルを追加するには、まずはパドルの位置や大きさを定義してあげる必要があります。

他の変数が定義されてる箇所の近くに、下記のコードを追加してみてください!


// パドルの設定
const paddleHeight = 10;
const paddleWidth = 75;
let paddleX = (canvas.width - paddleWidth) / 2;

最初の2行でパドルの高さと幅を定義してます。

paddleX = (canvas.width - paddleWidth) / 2;はX軸上のパドルの座標を定義してます。

cavans.widthで定義していたCanvasの幅(今回は300px)を表し、それをpaddleWidth分引いてあげたものを、2で割っています。

paddleWidth分引いてあげる必要があるのは、四角形の時の座標の始まりは中心では無く、左上の点から始まるからです。
仮にcanvas.width - paddleWidth / 2;とした場合はCanvasの中心からちょうどpaddleWidth分右にズレた図形になるかと思います。

次のコードではこれらを用いてさらなる計算が行われます。パドルを画面上に表示する関数を作成しましょう。 drawBall() のすぐ下に次の関数を追加してください。


// パドルを描く関数
function drawPaddle() {
  ctx.beginPath();
  ctx.rect(paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight);
  ctx.fillStyle = "#0095DD";
  ctx.fill();
  ctx.closePath();
}

純粋なJavascriptでのブロック崩しの作り方①でも説明したことを思いだしてみてください。
四角形の定義はrect()メソッドで左から順に X座標、Y座標、横幅、高さを指定できるのでしたね。

これを先程宣言した変数に置き換えてあげてるだけです。

canvas.height - paddleHeightとしてるのは、先程の四角形の時の座標は左上の点から始まることを思い返せば思い返せばすぐに意味が理解できますね!
canvas.heightのみだとちょうどパドルが見えない位置に描画されてしまいます。

関数は定義しただけでは使えないので、drawball()と同じように、draw()関数の中でdrawPaddle();を読んであげる必要があります。


drawPaddle();

そうすると、下記のようにパドルが描画されたかと思います。

blockimage12

パドルの操作

現状ではだだ四角形を描画したにすぎません。
キーボードを操作を実装してパドルとして操作できるようにしていきましょう。
その為には下記のよう機能が必要です。

  • 左ボタンが押されているか、右ボタンが押されているかという情報を保存する2つの変数。

  • ボタンを押してる時とボタンを離した時に指定の関数を発火させる仕組み。

  • ボタンを押してる時とボタンを離した時に実行される関数

  • パドルを左右に動かす機能

一つ一つやっていきましょう。

ボタンが押されているかという情報を保存する2つの変数

ボタンが押されているかどうかは論理値(true or false)で判断できます。 他の変数の近くに下記のコードを追加してみてください。


// ボタンが押されてるか確認する変数
let rightPressed = false;
let leftPressed = false;

初期値はfalse(ボタンを押してない)にしてあげてます。 流れとしては、ボタンが押された時にfalseからtrueにしてあげて、条件分岐でtrueの場合にパドルを動かすような感じです。

これで1つ目のボタンが押されているかという情報を保存する2つの変数を定義することは終わりました。

ボタンを押してる時と離した時に指定の関数を発火させる仕組み

ボタンを押してる時と離した時に指定の関数を発火させる仕組みはdocument.addEventListenerという、Javascriptの機能を使うことで、簡単に実現できます。

下記のようなコードをコード内の一番下に追加してみてください


// ボタンが押された時
document.addEventListener("keydown", keyDownHandler);
// ボタンが離れた時
document.addEventListener("keyup", keyUpHandler);

documentというのはページ全体を表し、ここに対してイベントリスナーを設定することで、ページ全体でキー入力を監視できるようにしています。

addEventListenerは、特定のイベントが起こった時に他の関数を呼び出すことができる仕組みで、引数は左から順に、イベントタイプ、呼び出す関数の順番で値を定義できる。

keydownイベント(ボタンを押してる時)が発生した時にkeyDownHandlerという関数を呼び、
keyupイベント(ボタンを離した時)が発生した時にkeyUpHandlerという関数を呼んであげてます。

これで2つ目のボタンを押してる時とボタンを離した時に指定の関数を発火させる仕組みは完成しましたが、keyDownHandler、keyUpHandlerを作ってないので、現時点で何も起こりません。 なので、それぞれの関数を追加していきましょう。

ボタンを押してる時とボタンを離した時に実行される関数

次のコードを先程のイベントリスナーの下に追加してみてください。


// ボタンが押された時の処理
function keyDownHandler(e) {
  if (e.key === "ArrowRight") {
    rightPressed = true;
  } else if (e.key === "ArrowLeft") {
    leftPressed = true;
  }
}

// ボタンが離れた時の処理
function keyUpHandler(e) {
  if (e.key === "ArrowRight") {
    rightPressed = false;
  } else if (e.key === "ArrowLeft") {
    leftPressed = false;
  }
}

(e)で引数としてイベントの情報を渡しています。
そしてそのeをe.keyとすることで、なんと押されたキーボードのボタンが分かってしまいます。

keyDownHandlerのif (e.key === “ArrowRight”)で、押されてたキーボードが右なら先程定義したrightPressedをtrueに変えてあげます。 左も同様です。

そして、keyUpHandlerでそれぞれのボタンが離れた時にfalseに戻してあげています。
これにより、それぞれに対応したボタンが押されている間だけ、条件をtrueにすることができます。

これで3つ目のボタンを押してる時とボタンを離した時に実行される関数を定義することができました。
ここまでこれば、あとはtrueの場合にパドルを移動させる処理を追加するだけです!

パドルを左右に動かす機能

ここまで書いたコードを利用して、パドルを移動させます。 draw()関数の中で下記のようなコードを追加してみてください。


// パドルの移動処理
if (rightPressed) {
  paddleX += 7;
} else if (leftPressed) {
  paddleX -= 7;
}

条件でrightPressedだけ入れると、この値がtrueの場合のみ実行されます。
そして、処理の内容をpaddleX += 7;としています。
これにより、ボタンが押されている間はパドルが毎フレームプラスされます。

これで4つ目のパドルを左右に動かす機能は完成しました!
実際にブラウザで動作を見てみてください。

blockmovie5

上記のように、無事パドルを動かすことに成功たかと思います。
ですが、パドルが画面外も移動できてしまうことに気づいたかと思います。

これを修正していきましょう

パドルが画面外に行くのを修正

先程のコードをこのように修正してみてください


// パドルの移動処理
if (rightPressed) {
  paddleX = Math.min(paddleX + 7, canvas.width - paddleWidth); //最も小さい値を取る
} else if (leftPressed) {
  paddleX = Math.max(paddleX - 7, 0); //最も大きい値を取る
}

下記のように、Canvas外に出ることは無くなったかと思います。

blockmovie6

Math.minは()の中指定した値の中で最も小さい値を返してくれるという機能を持ってます。
これを利用して、Cnavas外に出ることを防ぐことができます。

()の中はpaddleX + 7と、 canvas.width - paddleWidthという値の2つがあると思います。

Canvas内にパドルがある時はpaddleX + 7の値を続け、パドルの座標がcanvas.width - paddleWidthより高くなる時は、
ボタンを押しても常にcanvas.width - paddleWidthの値を取るつづけるというわけです。

Math.maxはその逆で、()の中指定した値の中で最も大きい値を返してくれるという機能を持ってます。 これを利用して、Cavans外に出そうになったら常に0の座標を取ってあげています。

今回は以上です。お疲れ様でした!
次回はゲームオーバーの機能を追加する予定です。

参考

出典: Mozilla Contributors. “純粋なJavaScriptを使ったブロック崩しゲーム”. MDN Web Docs.

この内容は、Creative Commons Attribution-ShareAlike (CC-BY-SA) 2.5(またはそれ以上)のライセンスのもとで公開されています。

webアプリ 初心者向け 備忘録