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

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

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

##1.どこに書こう

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

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

**runStantは[こちら](http://phi-jp.github.io/runstant/release/alpha/)**

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

![photo00.jpg](https://qiita-image-store.s3.amazonaws.com/0/58681/79dc6ff8-46eb-1c91-faa3-100f4ad568f6.jpeg)

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

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

```html
<!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**タブをクリック

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

```

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

**できない場合は[こちら](http://goo.gl/R4Mp29)**

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

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

![photo01.jpg](https://qiita-image-store.s3.amazonaws.com/0/58681/a19cd211-84e4-cb2c-56e6-e9da82e764fe.jpeg)


```js
var app = tm.display.CanvasApp("#World")
```
tmlibで使用するアプリケーションクラスを作成します。
指定している**#world**はhtmlで記述した**canvasタグのid**です。

```js
// キャンバスの大きさを変更
app.resize(SCREEN_WIDTH, SCREEN_HEIGHT);
// キャンバスの大きさを現在のウィンドウの大きさに合わせる
app.fitWindow();
```
キャンバスサイズを変更して、比率を変えずに現在のブラウザに合わせてくれます。

```js
// 四角を作る
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**で表示位置の設定をしています。

```js
//実行
app.run();
```
**描画**や**更新処理**が始まるようになります。

**ここまでのコードは[こちら](http://goo.gl/xr4Ry2)**

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

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

```js
tm.define();
```

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

```js:GameSceneクラス
//=============================================
// ゲーム用のシーンクラス
//=============================================
tm.define("GameScene" , {
    //基本となるシーンクラスを継承
    superClass:"tm.app.Scene",
    //初期化処理
    init:function(){
        //継承元クラスの初期化処理
        this.superInit();
    }
});
```
**tm.app.Scene**というクラスを継承した**GameSceneクラス**ができました。
GameSceneを基本にしていくために、tm.mainも変更します。

```js: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**で使用するシーンを差し替えます。
これでゲームを作る準備ができたので、同じようにボールクラスから作成していきます。

```js: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にボールを追加

```js: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](https://qiita-image-store.s3.amazonaws.com/0/58681/15008ee2-edc5-b7aa-a9b4-2517ef03e853.jpeg)

ただの円を表示しただけなので、なに作ってるかわからないですね。
**ここまでのコードは[こちら](http://goo.gl/e07rKy)**

##5.パドルを表示

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

```js: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に追加します。

```js: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](https://qiita-image-store.s3.amazonaws.com/0/58681/26c8d02b-c0e5-a5e0-a700-9fcb1ce4a865.jpeg)

まだ肝心なものが描画されていませんね。
**ここまでのコードは[こちら](http://goo.gl/mpEs5K)**

##6.ブロックを表示

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

```js: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に追加します。

```js: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](https://qiita-image-store.s3.amazonaws.com/0/58681/cab10ee0-7d92-3504-c8e8-b06912b146f3.jpeg)

やっとブロック崩しっぽくなってきました。
**ここまでのコードは[こちら](http://goo.gl/qESC6V)**
##7.ブロックを複数表示

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

```js: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](https://qiita-image-store.s3.amazonaws.com/0/58681/dfa2ca66-6a33-166d-7fbd-6a1c97cfc6f3.jpeg)

見た目は完全にブロック崩しになりましたね。
**ここまでのコードは[こちら](http://goo.gl/CBJxSQ)**
##8.パドルを動かす

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

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

```js: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;
        }
    },
});
```

```js:GameSceneクラス
//=============================================
// ゲーム用のシーンクラス
//=============================================
tm.define("GameScene" , {
    //基本となるシーンクラスを継承
    superClass:"tm.app.Scene",
    init:function(){

        //~~~ 省略 ~~~

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

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

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

**update**の引数の**app**から、

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

```js
app.keyboard.getKey("left")
```
**左キー**が押されていれば**true**が返ってきます。

```js
app.keyboard.getKey("right")
```
**右キー**が押されていれば**true**が返ってきます。

**☆ここまでのコードは[こちら](http://goo.gl/kl9fuu)**

##9.ボールを動かす

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

```js: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;
        }
    }
});
```

```js: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でまとめたほうが、後々複雑になったときに楽になります。

**ここまでのコードは[こちら](http://goo.gl/8kO0by)**

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

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

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

```js: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;
        }
    },
});
```

```js:GameSceneクラス
//=============================================
// ゲーム用のシーンクラス
//=============================================
tm.define("GameScene" , {
    //基本となるシーンクラスを継承
    superClass:"tm.app.Scene",
    init:function(){

        //~~~ 省略 ~~~

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

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

```js
if( (this.x + this.width * 0.5 ) > SCREEN_WIDTH)
```
のように、
ボールの右側を計算してあげないといけないのですが、

tmlibでは

```js
if( this.right > SCREEN_WIDTH)
```

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

<dl>
  <dt>this.left</dt>
  <dd>左の座標</dd>
  <dt>this.top</dt>
  <dd>上の座標</dd>
  <dt>this.bottom</dt>
  <dd>下の座標</dd>
  <dt>this.x</dt>
  <dd>中心の座標</dd>
</dl>

が取得できます。

これで、ボールが画面内をバウンドして動き続けるようになったかと思います。
**ここまでのコードは[こちら](http://goo.gl/bua8E4)**

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

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

```js: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;
            }
        }
    }
});
```

```js:Paddleクラス
//=============================================
// ブロック崩し用のパドル
//=============================================
tm.define("Paddle" , {
    //四角を表示するクラスを継承
    superClass:"tm.display.RectangleShape",
    init:function(){
        //継承元クラスの初期化 （幅、高さ、色）
        this.superInit(PADDLE_WIDTH , PADDLE_HEIGHT , PADDLE_COLOR);
        //形の種類を四角に設定する
        this.setBoundingType("rect");
    },
    move:function(app){
        //~~~ 省略 ~~~
    },
});

```

```js: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で**当たり判定の形**を設定するのを忘れないようにしましょう。

<dl>
  <dt>setBoundingType("rect")</dt>
  <dd>判定の形を四角に設定する</dd>
  <dt>setBoundingType("circle")</dt>
  <dd>判定の形を円に設定する</dd>
</dl>
 　
初期値では**circle**になっているため、
パドルでは**setBoundingType("rect")**で設定しました。

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

**ここまでのコードは[こちら](http://goo.gl/V1Xkmh)**

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

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

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

```js: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;
            }
        }
    }
});
```

```js: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;
                        }
                    }
                }
            }
        }
    },
});
```

```js: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));
    },
});
```
判定の方法ですが、
ボールの移動方向と、ブロックから見たボールの位置で処理を分けました。

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

**ここまでのコードは[こちら](http://goo.gl/Lqk0S9)**

##さいごに

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

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

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

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

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

遅くなってすいません。