このページの本文へ

CanvasとJavaScriptで作るブロック崩しの完成

2012年05月16日 13時33分更新

萩原伸悟/jAction

  • この記事をはてなブックマークに追加
本文印刷
Facebookapp

 FacebookのGraph APIとJavaScriptライブラリー「jAction」を使ったFacebookモバイルアプリの作り方を解説する本連載。前回に続き、「ブロック崩しゲーム」アプリの核となるゲームの処理を作っていきます。

ブロック崩し(iPhone/Androidスマートフォン用)
http://tadashiku.sunnyday.jp/ASCII/03/index.html

Step 7:ブロックを崩す

 前回作成したボールを動かす処理に、ブロックと衝突したときにブロックを崩す(削除する)処理を加えます。

 this.onEnterFrame = function(){}内に、以下のコードを追加しましょう。


for(var i = 0 ; i < blockContainer.numChildren() ; i++)
{
 var blockObj = blockContainer.getChildAt(i);
 if(ja.hitObj.intersect(boxObject,blockObj)){
  blockContainer.removeChildAt(i);
  yinc = -yinc;
  break;
 }
}

 this.onEnterFrame = function(){}内に記述した処理は、1フレームごと、つまり1秒間に10回実行されます。処理の内容を1行ずつ見ていきましょう。


for(var i = 0 ; i < blockContainer.numChildren() ; i++)

 A.numChildren()は、Aに格納されている(addChildされている)オブジェクトの数を返すメソッドです。blockContainer内のブロックの数をカウントし、for文でブロックの数だけ処理を繰り返します。


var blockObj = blockContainer.getChildAt(i);

 A.getChildAt(i)は、Aに格納されているi番目のオブジェクトを返します。blockContainer.getChildAt(i)でblockContainer内にあるi番目のオブジェクトを取得し、blockObjに格納します。


if(ja.hitObj.intersect(boxObject,blockObj)){

 ja.hitObj.intersect(A,B)は、当たり判定のためのメソッドです。AとBが衝突していれば1、そうでなければ0を返します。ここでは、ja.hitObj.intersect(boxObject,blockObj)でボール(boxObject)とブロック(blockObj)が衝突しているかどうかを調べます。


blockContainer.removeChildAt(i);

 ボールとブロックが衝突していたらblockContainer内のi番目のオブジェクトを取り除きます。A.removeChildAt(i)は、Aに含まれるi番目のオブジェクトを取り除くメソッドです。


yinc = -yinc;

 ブロックを崩したボールは逆方向に跳ね返えさせるため、座標の値をマイナスに変更します。ここまでをまとめたのがサンプル6です。

サンプル6の実行画面。ボールがブロックに当たるとブロックが消える

■サンプル6[Main.js](実行画面


Main = function()
{ 
  var boxObject = new ja.BoxClass(20,20,"#000000"); //ブロックを崩すボールを描画します。
  boxObject.x = 150; //ブロックを位置を指定します。
  boxObject.y = 200;
  var barObj = new ja.BoxClass(100,15,"#000000"); //自分の指で動かすを描画します。
  barObj.x = 110; //バーを位置を指定します。
  barObj.y = 350;
  
  var xinc = 10; //フレームごとにボールを動かすx方向のピクセル数です。
  var yinc = 10; //フレームごとにボールを動かすy方向のピクセル数です。
    
  //このゲームで使用する画像の準備をします。
  ja.imageUnitObj.addEventListener("onLoad", this); //imageObjがonLoadされたらthisのonLoadを実行します。
  ja.imageUnitObj.load(["Image/Bg.png""Image/block.png"]); //画像を読み込みます。
  
  var blockContainer = new ja.Container(); //表示させるブロックをまとめておくオブジェクトを生成します。
  
  //画像が読み込み終わったあとに以下が実行されます。
  this.onLoad = function()
  {
    window.scrollTo(0, 1); //アドレスバーを消します。
    
    ja.imageUnitObj.removeEventListener("onLoad", this); //onLoadは既に呼ばれたのでリスナーを解除します。
    ja.stage.addChild(ja.imageUnitObj["Bg"]); //読み込んでおいた画像を表示させます。
    ja.stage.addChild(boxObject); //ボールを表示させます。
    ja.stage.addChild(barObj); //バーを表示させます。
    ja.stage.addChild(blockContainer); //ブロックをまとめておくオブジェクトを表示します。
    //ブロックを表示させます。
    var x = 10;
    for(var i = 0 ; i < 5 ; i++)
    {
      var y = 0;
      for(var j = 0 ; j < 3 ; j++)
      {
        var block = new ja.ImageClass(ja.imageUnitObj["block"]); //ブロックを生成します。
        block.x = x;
        block.y = y;
        blockContainer.addChild(block); //ブロックを表示させます。
        y += block.h + 10; //Y方向に表示位置をずらします。
      }
      x += block.w + 10; //X方向に表示位置をずらします。
    }
    
    //タッチしたときの命令を追加します。
    ja.imageUnitObj["Bg"].addEventListener("touchUp", this);
  }
  
  //touchUpは画面から指が離れた瞬間に呼ばれます。
  this.touchUp = function()
  {
    ja.imageUnitObj["Bg"].removeEventListener("touchUp", this);
        
    boxObject.addEventListener("onEnterFrame" , this); //タッチが離れた瞬間にゲームをスタートさせます。
  }
  
  //ゲームスタート後、1秒間に10回この命令が呼ばれます。
  this.onEnterFrame = function(){
    //毎回のそれぞれの増加量を設定します。
    boxObject.x += xinc;
    boxObject.y += yinc;
    
    /***追加部分***/
    //当たり判定を使ってブロックを崩します。
    for(var i = 0 ; i < blockContainer.numChildren() ; i++) //blockContainerに残っているブロックの数だけ処理を繰り返します。
    {
      var blockObj = blockContainer.getChildAt(i); //blockContainerからブロックをひとつ指定します。
      if(ja.hitObj.intersect(boxObject,blockObj)) //ボールとブロックが衝突しているかを判定します。
      {
        blockContainer.removeChildAt(i); //ブロックを取り除きます。
        yinc = -yinc; //方向を反転させます。
        break;
      }
    }
    /***追加部分***/
    
    //ボールが壁に衝突したときに方向を変化させます。
    if(boxObject.x >= 300)
    {
      boxObject.x = 300;
      xinc = -xinc;
    }
    else if(boxObject.x <= 0)
    {
      boxObject.x = 0;
      xinc = -xinc;
    }
    
    if(boxObject.y <= 0)
    {
      boxObject.y = 0;
      yinc = -yinc;
    }
    else if(boxObject.y >= 460)
    {
      boxObject.y = 460;
      yinc = -yinc;
    }
  }
}
Web Professionalトップページバナー

この記事の編集者は以下の記事をオススメしています

ASCII.jp会員サービス 週刊Web Professional登録

Webディレクター江口明日香が行く

ランキング