LoginSignup
17
16

More than 5 years have passed since last update.

tmlib.jsでゲームをつくってみよう!

Posted at

はじめに

最近、tmlibを使う機会が多いため
簡単なゲームでtmlibのチュートリアル的なものを書いてみようかと思います。
技術ブログ的なことは初めて書くので、見づらいかもです…

とりあえず、プログラミングでサンプルが多いブロック崩しを作成!
ちなみに、画像は一切使用せず、図形だけでつくります。

1.どこに書こう

プログラムソースとかサーバーに置くの面倒なので、
とりあえず、runStantで書いていきます!

runStant
tmlib.js の公式エディタツール!
書いたコードがすぐに実行されるので、
tmlibやhtml5、javascript等をさくっと実行するのに便利。
さらに、書いた内容はURLで保存できるので、ブックマーク等を使用して
いつでも続きから書ける。

runStantはこちら

2.tmlibの準備

最初にrunStantのページへアクセスすると、
下の画像のようになっているはずです。(2014年12月)
使用しているブラウザはchromeです。

photo00.jpg

ここからまずは、tmlibを使えるようにします。

1.ページ右上のhtmlタブをクリック
2.下記のコードを参考に変更

<!DOCTYPE html>

<html>
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, user-scalable=no" />
        <meta name="apple-mobile-web-app-capable" content="yes" />

        <title>${title}</title>
        <meta name="description" content="${description}" />

        <style>${style}</style>
        //変更
        <script src="https://cdn.rawgit.com/phi-jp/tmlib.js/develop/build/tmlib.min.js"></script>
        <script>${script}</script>
    </head>
    <body>
        //変更
        <canvas id="world"></canvas>
    </body>
</html>

3.今度は、javascriptタブをクリック

tm.main(function(){
    console.log("start tmlib");
});

左下のフレームにstart tmlib
と表示されていればtmlibを使用する準備ができています

できない場合はこちら

3.とりあえず適当に表示

手始めに適当な大きさの四角を描画してみました。

photo01.jpg

var app = tm.display.CanvasApp("#World")

tmlibで使用するアプリケーションクラスを作成します。
指定している#worldはhtmlで記述したcanvasタグのidです。

// キャンバスの大きさを変更
app.resize(SCREEN_WIDTH, SCREEN_HEIGHT);
// キャンバスの大きさを現在のウィンドウの大きさに合わせる
app.fitWindow();

キャンバスサイズを変更して、比率を変えずに現在のブラウザに合わせてくれます。

// 四角を作る
var rect = tm.display.RectangleShape(200 , 200);
//画面(app.currentScene)に追加
rect.addChildTo(app.currentScene);
// 位置をセット ※画面の中心においてみる
rect.setPosition(SCREEN_WIDTH * 0.5, SCREEN_HEIGHT * 0.5);

この3行で、四角形を描画する準備をしています。
tm.display.RectangleShapeで四角形を生成し、addChildToで画面(シーン)に追加。
setPositionで表示位置の設定をしています。

//実行
app.run();

描画更新処理が始まるようになります。

ここまでのコードはこちら

4.ボールを表示

ここからブロック崩し自体の実装になります。
いざ、ボールを描画...と思ったのですが、折角なので見やすいコードをめざして、
クラス化しながら実装してみます。

tmlibでは、クラス作成用のメソッドがあります。

tm.define();

とりあえず、ゲーム用のシーンをクラス化してみましょう。

GameSceneクラス
//=============================================
// ゲーム用のシーンクラス
//=============================================
tm.define("GameScene" , {
    //基本となるシーンクラスを継承
    superClass:"tm.app.Scene",
    //初期化処理
    init:function(){
        //継承元クラスの初期化処理
        this.superInit();
    }
});

tm.app.Sceneというクラスを継承したGameSceneクラスができました。
GameSceneを基本にしていくために、tm.mainも変更します。

tm.main
tm.main(function(){
    // キャンバスからアプリケーションクラスを作る
    var app = tm.display.CanvasApp("#world");
    // キャンバスの大きさを変更
    app.resize(SCREEN_WIDTH, SCREEN_HEIGHT);
    // キャンバスの大きさを現在のウィンドウの大きさに合わせる
    app.fitWindow();

    //ゲーム用にシーンを用意する
    var gameScene = GameScene();
    //シーンをゲーム用のシーンと差し替える
    app.replaceScene(gameScene);

    // 実行
    app.run();
});

tm.mainでGameSceneを作成して、app.replaceSceneで使用するシーンを差し替えます。
これでゲームを作る準備ができたので、同じようにボールクラスから作成していきます。

Ballクラス
//ボールのサイズ
var BALL_SIZE = 25; 
//ボールの色
var BALL_COLOR = {fillStyle:"red" , strokeStyle:"transparent"};
//==============================================================
// ブロック崩し用のボール
//==============================================================
tm.define("Ball" ,{
    //円を表示するクラスを継承
    superClass:"tm.display.CircleShape",
    //初期化処理
    init:function(){
        //継承元クラスの初期化 (幅、高さ、色)
        this.superInit(BALL_SIZE , BALL_SIZE , BALL_COLOR);
    },
});

ボールクラスは円を描画してくれるtm.display.CircleShapeを継承しています。
先ほど作成したGameSceneにボールを追加

GameSceneクラス
//=============================================
// ゲーム用のシーンクラス
//=============================================
tm.define("GameScene" , {
    //基本となるシーンクラスを継承
    superClass:"tm.app.Scene",
    //初期化処理
    init:function(){
        //継承元クラスの初期化処理
        this.superInit();
        //ボールを追加
        var ball = Ball();
        //ゲームシーン内に追加
        ball.addChildTo(this);
        //表示位置を設定
        ball.setPosition(SCREEN_CENTER_X , SCREEN_CENTER_Y);
        //ゲームシーンでボールを保持
        this.ball = ball;
    }
});

表示されたのが下の画像です。
photo02.jpg

ただの円を表示しただけなので、なに作ってるかわからないですね。
ここまでのコードはこちら

5.パドルを表示

ボールを跳ね返すパドルを作ります。
ボールと同じように、パドルクラスを下のように作成

Paddleクラス
//パドルの幅
var PADDLE_WIDTH = 120;
//パドルの高さ
var PADDLE_HEIGHT = 20;
//パドルの色
var PADDLE_COLOR = {fillStyle:"yellow" , strokeStyle:"transparent"};
//=============================================
// ブロック崩し用のパドル
//=============================================
tm.define("Paddle" , {
    //四角を表示するクラスを継承
    superClass:"tm.display.RectangleShape",
    init:function(){
        //継承元クラスの初期化 (幅、高さ、色)
        this.superInit(PADDLE_WIDTH , PADDLE_HEIGHT , PADDLE_COLOR);
    }
});

パドルは四角形なので、tm.display.RectangleShapeを継承しました。
パドルをGameSceneに追加します。

GameSceneクラス
//=============================================
// ゲーム用のシーンクラス
//=============================================
tm.define("GameScene" , {
    //基本となるシーンクラスを継承
    superClass:"tm.app.Scene",
    init:function(){
        //継承元クラスの初期化処理
        this.superInit();

        //======== ボール ================
        //ボールを追加
        var ball = Ball();
        //ゲームシーン内に追加
        ball.addChildTo(this);
        //表示位置を設定
        ball.setPosition(SCREEN_CENTER_X , SCREEN_CENTER_Y);
        //ゲームシーンでボールを保持
        this.ball = ball;

        //======== パドル ================
        //パドルを追加
        var paddle = Paddle();
        //ゲームシーン内に追加
        paddle.addChildTo(this);
        //表示位置を設定
        paddle.setPosition(SCREEN_CENTER_X , SCREEN_HEIGHT - 80);
        //ゲームシーンでパドルを保持
        this.paddle = paddle;

    }
});

ボールのときと同じですね。
表示されたのが下の画像です。
photo03.jpg

まだ肝心なものが描画されていませんね。
ここまでのコードはこちら

6.ブロックを表示

次はブロックを表示してみます。
ひとまず、1つのブロックを表示していきます。
まずは、ブロッククラスを作ってみましょう。

Blockクラス
//ブロックの幅
var BLOCK_WIDTH = 140;
//ブロックの高さ
var BLOCK_HEIGHT = 30;
//ブロックの色
var BLOCK_COLOR = {fillStyle:"blue" , strokeStyle:"white" , lineWidth:2};
//=============================================
// ブロック崩し用のブロック
//=============================================
tm.define("Block" , {
    //四角を表示するクラスを継承
    superClass:"tm.display.RectangleShape",
    init:function(){
        //継承元クラスの初期化 (幅、高さ、色)
        this.superInit(BLOCK_WIDTH, BLOCK_HEIGHT , BLOCK_COLOR);

    }
});

ブロックも四角形なので、tm.display.RectangleShapeを継承しました。
色とサイズ以外は、パドルと同じですね。
これを、GameSceneに追加します。

GameSceneクラス
//=============================================
// ゲーム用のシーンクラス
//=============================================
tm.define("GameScene" , {
    //基本となるシーンクラスを継承
    superClass:"tm.app.Scene",
    init:function(){
        //継承元クラスの初期化処理
        this.superInit();

        //======== ボール ================
        //ボールを追加
        var ball = Ball();
        //ゲームシーン内に追加
        ball.addChildTo(this);
        //表示位置を設定
        ball.setPosition(SCREEN_CENTER_X , SCREEN_HEIGHT - 100);
        //ゲームシーンでボールを保持
        this.ball = ball;

        //======== パドル ================
        //パドルを追加
        var paddle = Paddle();
        //ゲームシーン内に追加
        paddle.addChildTo(this);
        //表示位置を設定
        paddle.setPosition(SCREEN_CENTER_X , SCREEN_HEIGHT - 80);
        //ゲームシーンでパドルを保持
        this.paddle = paddle;

        //======== ブロック ================
        //ブロックを追加
        var block = Block();
        //ゲームシーン内に追加
        block.addChildTo(this);
        //表示位置を設定
        block.setPosition(SCREEN_CENTER_X , 100);

    }
});

表示されたのが下の画像です。
ボールの位置もパドルに近づけました。
photo04.jpg

やっとブロック崩しっぽくなってきました。
ここまでのコードはこちら

7.ブロックを複数表示

先ほど作成したブロックを、複数表示してみましょう。

GameSceneクラス
//ブロックの表示数(横)
var BLOCK_LINE_NUM_X = 4;
//ブロックの表示数(縦)
var BLOCK_LINE_NUM_Y = 4;
//全ブロック合わせた横幅
var BLOCK_TOTAL_WIDTH = BLOCK_LINE_NUM_X * BLOCK_WIDTH;
//ブロックの表示位置(X)
var BLOCK_OFFSET_X = (SCREEN_WIDTH - BLOCK_TOTAL_WIDTH) * 0.5 + BLOCK_WIDTH * 0.5;
//ブロックの表示位置(Y)
var BLOCK_OFFSET_Y = 50;
//=============================================
// ゲーム用のシーンクラス
//=============================================
tm.define("GameScene" , {

        //~~~ 省略 ~~~

        //======== パドル ================
        //パドルを追加
        var paddle = Paddle();
        //ゲームシーン内に追加
        paddle.addChildTo(this);
        //表示位置を設定
        paddle.setPosition(SCREEN_CENTER_X , SCREEN_HEIGHT - 80);
        //ゲームシーンでパドルを保持
        this.paddle = paddle;

        //======== ブロック ================
        var blockArray = [];        
        //縦
        for(var y = 0 ; y < BLOCK_LINE_NUM_Y ; y++){
            //横
            for(var x = 0; x < BLOCK_LINE_NUM_X ; x++){
                var block = Block();
                //ゲームシーン内に追加
                block.addChildTo(this);
                //表示位置を設定
                block.setPosition(
                    BLOCK_OFFSET_X + x * BLOCK_WIDTH , 
                    BLOCK_OFFSET_Y + y * BLOCK_HEIGHT
                );
                //作成したブロックは配列で保持
                blockArray.push(block);
            }            
        }
    }
});

for文で縦と横の数だけブロックを表示しました。
結果が下の画像
photo05.jpg

見た目は完全にブロック崩しになりましたね。
ここまでのコードはこちら

8.パドルを動かす

ここから遊べるようにするために動きをつけていきます。
画像では結果が説明しづらいため、
動いている状態はrunstantのリンクから確認してみて下さい。

まずはパドルをキーボードで動かせるようにしましょう。
作成したPaddleクラスとGameSceneクラスを変更していきます。

Paddleクラス
//パドルの移動量
var PADDLE_MOVE_VALUE = 6;
//=============================================
// ブロック崩し用のパドル
//=============================================
tm.define("Paddle" , {
    //四角を表示するクラスを継承
    superClass:"tm.display.RectangleShape",
    init:function(){
        //継承元クラスの初期化 (幅、高さ、色)
        this.superInit(PADDLE_WIDTH , PADDLE_HEIGHT , PADDLE_COLOR);
    },
    //移動処理
    move:function(app){
        //左キーが押されている場合
        if (app.keyboard.getKey("left")){
            this.x -= PADDLE_MOVE_VALUE;
        }
        //右キーが押されている場合
        else if (app.keyboard.getKey("right")){
            this.x += PADDLE_MOVE_VALUE;
        }
    },
});
GameSceneクラス
//=============================================
// ゲーム用のシーンクラス
//=============================================
tm.define("GameScene" , {
    //基本となるシーンクラスを継承
    superClass:"tm.app.Scene",
    init:function(){

        //~~~ 省略 ~~~

    },
    //定期更新処理
    update:function(app){
        //パドルの移動 appをパドルクラスの移動処理に渡す
        this.paddle.move(app);
    },
});

update()は、毎フレーム呼ばれるため、

定期的な更新処理を書くことができます。

updateの引数のappから、

キーボードの状態を知ることができます。

app.keyboard.getKey("left")

左キーが押されていればtrueが返ってきます。

app.keyboard.getKey("right")

右キーが押されていればtrueが返ってきます。

☆ここまでのコードはこちら

9.ボールを動かす

パドルを動かしたので、今度はボールを動かしましょう。
BallクラスとGameSceneクラスを変更していきます。

Ballクラス
//ボールの移動量(X)
var BALL_MOVE_VALUE_X = 6;
//ボールの移動量(Y)
var BALL_MOVE_VALUE_Y = -6;
//=============================================
// ブロック崩し用のボール
//=============================================
tm.define("Ball" ,{
    //円を表示するクラスを継承
    superClass:"tm.display.CircleShape",
    init:function(){
        //継承元クラスの初期化 (幅、高さ、色)
        this.superInit(BALL_SIZE , BALL_SIZE , BALL_COLOR);
        this.isMove = true;
        this.addValueX = BALL_MOVE_VALUE_X;
        this.addValueY = BALL_MOVE_VALUE_Y;
    },
    //ボールの移動処理
    move:function(){
        //移動可能な場合
        if(this.isMove){
            //座標を更新する
            this.x += this.addValueX;
            this.y += this.addValueY;
        }
    }
});
GameSceneクラス
//=============================================
// ゲーム用のシーンクラス
//=============================================
tm.define("GameScene" , {
    //基本となるシーンクラスを継承
    superClass:"tm.app.Scene",
    init:function(){

        //~~~ 省略 ~~~

    },
    //定期更新処理
    update:function(app){
        //パドルの移動 appをパドルクラスの移動処理に渡す
        this.paddle.move(app);
        //ボールの移動
        this.ball.move();
    },
});

BallクラスのmoveをGameSceneのupdateで呼ぶことによって、
定期的にBallのxとy座標が更新されるため、
ボールが右上に向かって動くようになります。

ちなみに、Ballクラスでupdateを作成しても同じように動きますが、
定期更新する際に、処理の順番がよくわからなくなってしまうことがあるので、
GameSceneのupdateでまとめたほうが、後々複雑になったときに楽になります。

ここまでのコードはこちら

10.ボールと画面の当たり判定

ボールが動くようにはなりましたが、
右上に向かって、そのまま画面外まで飛んでいってしまうため、
画面内でバウンドするようにしましょう。

BallクラスとGameSceneクラスを変更していきます。

Ballクラス
//=============================================
// ブロック崩し用のボール
//=============================================
tm.define("Ball" ,{
    //円を表示するクラスを継承
    superClass:"tm.display.CircleShape",
    init:function(){
        //~~~ 省略 ~~~
    },
    //ボールの移動処理
    move:function(){
        //~~~ 省略 ~~~
    },
    //画面とボールのバウンド処理
    boundScreen:function(){
        //画面左側
        if(this.left < 0){
            //移動量を逆にする
            this.addValueX *= -1;
            //画面端にめり込み続けないように補正する
            this.x = BALL_SIZE * 0.5;
        }
        //画面右側
        else if(this.right > SCREEN_WIDTH){
            //移動量を逆にする
            this.addValueX *= -1;
            //画面端にめり込み続けないように補正する
            this.x = SCREEN_WIDTH - BALL_SIZE * 0.5;
        }
        //画面上側
        if(this.top < 0){
            //移動量を逆にする
            this.addValueY *= -1;
            //画面端にめり込み続けないように補正する
            this.y = BALL_SIZE * 0.5;
        }
        //画面下側
        else if(this.bottom > SCREEN_HEIGHT){
            //移動量を逆にする
            this.addValueY *= -1;
            //画面端にめり込み続けないように補正する
            this.y = SCREEN_HEIGHT - BALL_SIZE * 0.5;
        }
    },
});
GameSceneクラス
//=============================================
// ゲーム用のシーンクラス
//=============================================
tm.define("GameScene" , {
    //基本となるシーンクラスを継承
    superClass:"tm.app.Scene",
    init:function(){

        //~~~ 省略 ~~~

    },
    //定期更新処理
    update:function(app){
        //パドルの移動 appをパドルクラスの移動処理に渡す
        this.paddle.move(app);
        //ボールの移動
        this.ball.move();
        //ボールと画面のバウンド処理
        this.ball.boundScreen();
    },
});

とりあえず、画面の右、上、左、下とボールの位置によってバウンドの処理を作りました。
判定の処理については、あまり詳しく書きませんが、
図形や画像の基準点が、中心となっているため、
右側の壁と判定する場合、そのまま処理を書こうとすると

if( (this.x + this.width * 0.5 ) > SCREEN_WIDTH)

のように、
ボールの右側を計算してあげないといけないのですが、

tmlibでは

if( this.right > SCREEN_WIDTH)

this.rightで、右側の座標が取得できます。
これ、すごく楽です。

this.left
左の座標
this.top
上の座標
this.bottom
下の座標
this.x
中心の座標

が取得できます。

これで、ボールが画面内をバウンドして動き続けるようになったかと思います。
ここまでのコードはこちら

11.ボールとパドルの当たり判定

さて、もう少しです。
パドルでボールを打ち返せるようにしましょう。
BallクラスとGameSceneクラスを変更します。

Ballクラス
//=============================================
// ブロック崩し用のボール
//=============================================
tm.define("Ball" ,{
    //円を表示するクラスを継承
    superClass:"tm.display.CircleShape",
    init:function(){
        //~~~ 省略 ~~~
    },
    //ボールの移動処理
    move:function(){
        //~~~ 省略 ~~~
    },
    //画面とボールのバウンド処理
    boundScreen:function(){
        //~~~ 省略 ~~~
    },
    //パドルとボールのバウンド処理
    boundPaddle:function(paddle){
        //パドルとの判定は移動が下方向だった場合のみ処理する
        if(this.addValueY > 0){
            if(this.isHitElement(paddle)){
                this.addValueY *= -1;
                this.y = paddle.top - BALL_SIZE * 0.5;
            }
        }
    }
});
Paddleクラス
//=============================================
// ブロック崩し用のパドル
//=============================================
tm.define("Paddle" , {
    //四角を表示するクラスを継承
    superClass:"tm.display.RectangleShape",
    init:function(){
        //継承元クラスの初期化 (幅、高さ、色)
        this.superInit(PADDLE_WIDTH , PADDLE_HEIGHT , PADDLE_COLOR);
        //形の種類を四角に設定する
        this.setBoundingType("rect");
    },
    move:function(app){
        //~~~ 省略 ~~~
    },
});

GameSceneクラス
//=============================================
// ゲーム用のシーンクラス
//=============================================
tm.define("GameScene" , {
    //基本となるシーンクラスを継承
    superClass:"tm.app.Scene",
    init:function(){
        //~~~ 省略 ~~~
    },
    //定期更新処理
    update:function(app){
        //パドルの移動 appをパドルクラスの移動処理に渡す
        this.paddle.move(app);
        //ボールの移動
        this.ball.move();
        //ボールと画面のバウンド処理
        this.ball.boundScreen();
        //ボールとパドルのバウンド処理
        this.ball.boundPaddle(this.paddle);
    },
});

今回は、ボールの移動方向が下向きの場合のみ打ち返すようにしました。
isHitElement()でElement(ボールとかパドルとかブロックとか)同士の当たり判定ができます。

ここでワンポイント
Paddleクラスに追加したsetBoundingTypeで当たり判定の形を設定するのを忘れないようにしましょう。

setBoundingType("rect")
判定の形を四角に設定する
setBoundingType("circle")
判定の形を円に設定する

 
初期値ではcircleになっているため、
パドルではsetBoundingType("rect")で設定しました。

これでパドルでボールが打ち返せるようになりました。

ここまでのコードはこちら

12.ボールとブロックの当たり判定

最後にボールとブロックの当たり判定を実装します。

この当たり判定については、
比較的簡単な判定方法で作成してみました。
BlockクラスとGameSceneクラスを変更していきます。

Ballクラス
//=============================================
// ブロック崩し用のボール
//=============================================
tm.define("Ball" ,{
    //円を表示するクラスを継承
    superClass:"tm.display.CircleShape",
    init:function(){
        //継承元クラスの初期化 (幅、高さ、色)
        this.superInit(BALL_SIZE , BALL_SIZE , BALL_COLOR);
        //形の種類を円に設定する
        this.setBoundingType("circle");
        //移動可能フラグ
        this.isMove = true;
        //ボールの初期移動量と方向
        this.addValueX = BALL_MOVE_VALUE_X;
        this.addValueY = BALL_MOVE_VALUE_Y;
        //ボールに攻撃力を設定
        this.attack = 1;
    },
    //ボールの移動処理
    move:function(){
        //~~~ 省略 ~~~
    },
    //画面とボールのバウンド処理
    boundScreen:function(){
        //~~~ 省略 ~~~
    },
    //パドルとボールのバウンド処理
    boundPaddle:function(paddle){
        //パドルとの判定は移動が下方向だった場合のみ処理する
        if(this.addValueY > 0){
            if(this.isHitElement(paddle)){
                this.addValueY *= -1;
                this.y = paddle.top - BALL_SIZE * 0.5;
            }
        }
    }
});
Blockクラス
//=============================================
// ブロック崩し用のブロック
//=============================================
tm.define("Block" , {
    //四角を表示するクラスを継承
    superClass:"tm.display.RectangleShape",
    init:function(){
        //継承元クラスの初期化 (幅、高さ、色)
        this.superInit(BLOCK_WIDTH, BLOCK_HEIGHT , BLOCK_COLOR);
        //形の種類を四角に設定する
        this.setBoundingType("rect");
        //ブロックに耐久力を設定
        this.hp = 1;
    },
    //ボールとブロックの判定
    damage:function(ball){
        //耐久力が残っている場合のみ判定
        if(this.hp > 0){
            //ボールとブロックがあたっているか判定
            if(this.isHitElement(ball)){
                //ブロックの耐久値をボールの攻撃力分減らす
                this.hp -= ball.attack;
                //ブロックの耐久値が0ならば非表示にする
                if(this.hp <= 0){
                    this.setVisible(false);
                }
                //上方向に進んでいるとき
                if(ball.addValueY < 0){
                    //右方向に進んでいるとき
                    if(ball.addValueX > 0){
                        if(ball.y < this.bottom){
                            ball.addValueX *= -1;
                        }else {
                            ball.addValueY *= -1;
                        }
                    }
                    //左方向に進んでいるとき
                    else{
                        if(ball.y < this.bottom){
                            ball.addValueX *= -1;
                        }else {
                            ball.addValueY *= -1;
                        }

                    }
                }
                //下方向に進んでいるとき
                else{
                    //右方向に進んでいるとき
                    if(ball.addValueX > 0){
                        if(ball.y > this.top){
                            ball.addValueX *= -1;
                        }else {
                            ball.addValueY *= -1;
                        }
                    }
                    //左方向に進んでいるとき
                    else{
                        if(ball.y > this.top){
                            ball.addValueX *= -1;
                        }else {
                            ball.addValueY *= -1;
                        }
                    }
                }
            }
        }
    },
});
GameSceneクラス
//=============================================
// ゲーム用のシーンクラス
//=============================================
tm.define("GameScene" , {
    //基本となるシーンクラスを継承
    superClass:"tm.app.Scene",
    init:function(){
        //~~~ 省略 ~~~

        //ブロックのリストをGameSceneで保持する
        //(複数のブロックを表示する際に忘れてました)
        this.blockArray = blockArray
    },
    update:function(app){
        //パドルの移動
        this.paddle.move(app);
        //ボールの移動
        this.ball.move();
        //ボールと画面のバウンド処理
        this.ball.boundScreen();
        //ボールrとパドルのバウンド処理
        this.ball.boundPaddle(this.paddle);
        //ボールとブロックの衝突判定
        this.blockArray.each(function(block){
            block.damage(this.ball);
        }.bind(this));
    },
});

判定の方法ですが、
ボールの移動方向と、ブロックから見たボールの位置で処理を分けました。

結構単純な処理ですが、いい感じに動いてくれます。
これで、ブロック崩しの最低限の処理は実装されました。

ここまでのコードはこちら

さいごに

こんなに長い記事を読んで頂きありがとうございます。

ゲームつくってみよう系を全部説明すると一回じゃ無理ですね。

実際にはゲーム開始やゲームオーバー処理まで書きたかったのですが、
長すぎるため、次回続きを書こうかと思います。

初めて記事書いてみましたが、
javascriptの記事書く際にranstantって便利すぎじゃありません?

Advent Calendar 12/3担当のh_mjlifeでした。

遅くなってすいません。

17
16
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
16