javascript

/

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

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

やりたいこと

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

今回は初期設定から、実際に図形を描画するまでやってみたいと思います。

HTML5のcanvasタグと使った画面の描画、移動、衝突検出、制御機構、勝敗状態など、
Webゲームに必要な機能がどのように出来てるのかが、分かるかと思います。

また、今回作るブロック崩しの内容はMDN(Mozilla Developer Network)を参考に、自分なりに解釈したものです。

環境

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

初期設定

まず、お好きな名前のファィルを作成します。私の場合、ブロック崩しゲームとしました。

それをVSCodeで開き、index.htmlstyle.cssscript.jsファィルをそれぞれ同じ階層に作成します。

以下のようになったと思います。

ファィル構造の画像

簡単なHTMLを作成

ゲームの内容は全てHTMLのcanvas要素の中に表示される為、HTMLの中身はとても簡潔です。


<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>ブロック崩しゲーム</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <canvas id="canvas" width="300" height="300"></canvas>
    <script src="./script.js"></script>
  </body>
</html>

htmlの雛形を作成し、linkタグとscriptタグで同じ階層のcssとjsを読み込みます。
bodyの中はidをcanvasとして、長さと高さは300pxにしています。

imgタグと違い、canvasタグには閉じタグが必要なので注意が必要です!
canvasタグの中に書いたテキストは、なんらかの原因でcanvasが表示できない場合の代替テキストの役割をします。

今回は必要ないので、省いてます。

CSSでレイアウトを整える

canvasの背景は初期設定では透明なので、色をつけてあげる必要があります。


* {
  padding: 0;
  margin: 0;
}

body,
html {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgb(65, 172, 104);
}

#canvas {
  background: #eee;
  display: block;
  margin: 0 auto;
  border: 5px solid #333;
}

Flexコンテナでcanvasを上下中央寄せにして、見やすくします。
デザインは自分好みにお好きに変更ください。

下記のように表示されたと思います。

ファィル構造の画像

少しゲームぽくなってきましたね!
次に、いよいよJavascriptを書いていきます。

Javascriptで図形を表示する

canvas要素の取得

最初にcanvas要素の取得2d描画を可能にするように記述します。


// canvasを要素取得
const canvas = document.getElementById("canvas");
// 2Dで描画できるようにする
const ctx = canvas.getContext("2d");

document.getElementByIdでcanvasを取得、canvas.getContext(“2d”);で2dでの描画を可能にします。

getContext()メソッドは元々、canvasタグが持っているメソッドで、javascriptで呼び出してあげると使えるようになります。 
なので、javascriptと一緒に使うのが前提としたタグというわけですね。

ctxはコンテキスト(環境)の略です。

図形を描画してみる(四角形)

先程記述したコードの下にこのように書いてください。


ctx.beginPath(); // パスの開始
ctx.rect(50, 40, 50, 50); // 四角形のパスを定義
ctx.fillStyle = "#FF0000"; // 塗りつぶす色を指定
ctx.fill(); // 現在のパスを塗りつぶす
ctx.closePath(); // パスの終了

下記のような四角形が表示されたかと思います。

ファィル構造の画像

コメントで書いてる通り、ctx.beginPath()とctx.closePath()メソッドで、パスの開始と終了を定義できます。

四角形の定義はrect()メソッドで左から順に X座標、Y座標、横幅、高さを指定できます。
なので、rect( X座標 , Y座標 , 横幅 , 高さ );という風に記述します。

canvasの左上が原点なので、下記のようになってます。

ファィル構造の画像

次にfillStyleで塗りつぶす色を定義してあげます。

fillStyleの時点ではまだ四角形を定義しただけなので、fill();を使って塗りつぶしてあげる必要があります。

ここで一つ注意点があります。

一般的な数学の座標ではX軸は右にいくほどプラスになり、Y軸は上にいくほど同じくプラスになると思います。
しかし、このcanvas内の座標ではX軸は変わらずですが、Y軸は上にいくほどマイナスになります。

この座標の理解はCanvasでの描画やアニメーションを行う際に、重要になってくると思いますので、押さえておきましょう!

図形を描画してみる(円形)

次に円を描画してみます。下記のようにコードを加えてください!


ctx.beginPath(); // パスの開始
ctx.arc(240, 160, 20, 0, Math.PI * 2, false); // 円形のパスを定義
ctx.fillStyle = "green"; // 塗りつぶす色を指定
ctx.fill(); // 現在のパスを塗りつぶす
ctx.closePath(); // パスの狩猟

下記のような円形が表示されたかと思います。

ファィル構造の画像

先程と大きく変わったのはctx.arc(240, 160, 20, 0, Math.PI * 2, false)メソッドの部分でしょう。
円形は見ての通り、arc()メソッドで描くことが可能です。

arc()メソッドは次の6つの引数を取ることができます。

  • 円の中心のX座標
  • 円の中心のY座標
  • 円の半径
  • 開始角度(ラジアン)
  • 終了角度(ラジアン)
  • 描く方向 ( 時計回りはfalse。反時計回りは true。 ) この最後の引数は省略可能で、省略すればデフォルトで時計回りになる。

それぞれ解説していきます。

四角形の時は四角形の左上の点を基準にX座標、Y座標を指定してあげてましたが、
円の場合は円の中心を基準にX座標、Y座標を指定してあげる必要があります。
そこから指定した半径分、幅を取ります。

試しに円のX座標、Y座標を0にするとどういうことか分かるかと思います。

ブロック崩しの画像

上記の画像のように、円の中心がちょうど原点に来ていることが分かります。
このことにより、円は中心からの座標を取ってることが分かりますね!

次に円の形を決めます。 開始角度と終了角度はラジアンで記述してあげる必要があります。
あまり聞き馴染みのない単語かもしれませんが、角度の単位の一つです。

普段私たちがよく使う度数法(例:90度)とは違い、弧度法での角度をラジアンと言います。

  • 0ラジアンは3時の方向
  • 360度 = 2πラジアン

上記を踏まえて、先程のコードを見返してみましょう。
arc(240, 160, 20, 0, Math.PI * 2, false)

0, Math.PI * 2
Math.PI = πのことです。

よって開始地点0ラジアン(3時の方向)から終了地点2πラジアン(360度)に図形を描くと、綺麗な円ができるというわけですね!

最後にfalseで時計回りを指定してあげます。
これは省略してもらって大丈夫です。

今回は以上です。お疲れ様でした!
次回は実際にボールの動かす処理を書いていきます。

参考

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

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

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