Monaca Docs
  • Monaca とは
  • 最初のアプリを作る
  • アプリをテストする
  • Monaca リリース情報
    • iOS プライバシーマニフェスト対応
    • 「ニフクラ mobile backend」終了に関するお知らせ
    • プラグイン uses-permission タグの重複修正機能
    • Cordova 12 の変更点
    • iOSストア版Monaca デバッガー配信停止と代替機能のご案内
    • iOS App Store への送信エラー (ITMS-90165)
    • cordova-custom-configのビルドエラー
    • Cordova 11 の変更点
    • Cordova 10 の変更点
    • Cordova 9.0 の変更点
    • 利用規約の変更
    • 新しい Monaca CLI と Localkit
    • CordovaからCapacitorへの移行
  • Monacaガイド
    • Monaca での開発の概要
    • Monaca クラウド IDE
      • 概要
      • Monaca クラウド IDE の機能
      • ターミナル機能
      • エディターのショートカット一覧
      • プロジェクトの構成
        • ファイル・フォルダー構成
        • JS/CSS コンポーネント
        • Cordova プラグイン
        • ユーザー Cordova プラグイン
      • バージョン管理
        • 概要
        • GitHub との連携
        • Git SSH との連携
      • Monaca CI
        • 概要
        • アプリ配信 / 配布サービス (デプロイサービス)
        • Appetize.ioへの配信
        • DeployGateへの配信
        • Firebase への配信
      • ビルド
        • iOS アプリのビルド
          • iOS アプリのビルド
          • Monaca と Xcode 間でのビルド設定の再利用
        • Android アプリのビルド
        • Windows アプリのビルド
        • Electron アプリのビルド
          • Windows アプリのビルド
        • PWA アプリのビルド
        • ビルド環境の設定
        • ビルド履歴一覧
        • 一般的なビルドとアップロードエラー
      • 配布方法
        • App Store での配布
          • App Store Connect ガイド
          • iOS アプリ アップロード機能
        • Google Play での配布
        • 公式ストア経由以外での配布
      • パッケージダウンロード機能
      • チュートリアル
    • Monaca Localkit
      • 概要
      • ペアリングとデバッグ
      • リモートビルドと配布申請
      • トラブルシューティング
        • インストール ( Windows の場合 )
        • インストール ( Mac OS X の場合 )
        • アンインストール時 ( Windows の場合 )
        • 不完全なファイル・フォルダー構成
        • プレビューウィンドウが更新されない
        • Error while installing
        • nodeのインストールが必要です
      • チュートリアル
    • Monaca CLI
      • 概要
      • Monaca CLI コマンド
      • ペアリングとデバッグ
      • リモートビルドと配布申請
      • トラブルシューティング ガイド
      • チュートリアル
    • Monaca デバッガー
      • 機能の概要
      • インストール方法
        • Android 向けの Monaca デバッガー
        • iOS 向け Monaca デバッガー
        • Android エミュレーター向け Monaca デバッガー
      • 使用例
      • iOS カスタムビルド版デバッガー
      • iOS シミュレータービルド
      • トラブルシューティング ガイド
      • チュートリアル
    • チームダッシュボード
    • クイックビューア
    • 他のプラットフォームからの移行
      • 移行時の確認ポイント
      • クラウドIDE プレビュー機能の設定
      • Angular からの移行
      • Ionic からの移行
      • React からの移行
      • Vue からの移行
      • Telerik からの移行
  • 🛠️アプリビルド
    • iOS ビルド
      • 秘密鍵とCSRの作成
      • 証明書の作成
      • プロビジョニング・プロファイルの更新
  • チュートリアル
    • Monaca クラウド IDE チュートリアル
      • パート 1 : プロジェクトの作成
      • パート 2 : Monaca クラウド IDE と Monaca デバッガーとの連携
      • パート 3 : Monaca アプリのビルド
      • パート 4 : Monaca アプリの配布申請
    • Monaca Localkit チュートリアル
      • パート 1 : プロジェクトの作成
      • パート 2 : Monaca Localkit と Monaca デバッガーとの連携
      • パート 3 : Monaca アプリのビルド
      • パート 4 : Monaca アプリの配布申請
    • Monaca CLI チュートリアル
      • パート 1 : プロジェクトの作成
      • パート 2 : Monaca CLI と Monaca デバッガーとの連携
      • パート 3 : Monaca アプリのビルド
      • パート 4 : Monaca アプリの配布申請
    • Electron アプリ開発
      • NPMパッケージの利用方法
      • Web APIの利用方法
    • バーコードスキャナープラグイン
    • Cordova Sqlite Storage プラグイン
    • Cordova Google Analytics プラグイン
    • Cordova Firebase プラグイン
    • Cordova In-app Purchase プラグイン
    • Cordova AppVersion プラグイン
    • Cordova Ionic Keyboard プラグイン
    • Cordova Social Sharing プラグイン
    • Phonegap Push プラグイン
  • APIの解説
    • Monaca API
      • Monaca クラウド & リモートビルド API
      • ユーティリティ
    • 基本プラグイン
      • Cordova 12.0
        • Battery プラグイン
        • Camera プラグイン
        • Device プラグイン
        • Device Motion プラグイン
        • Device Orientation プラグイン
        • Dialog プラグイン
        • File プラグイン
        • Geolocation プラグイン
        • InAppBrowser プラグイン
        • Media プラグイン
        • Media Capture プラグイン
        • Network Information プラグイン
        • Vibration プラグイン
        • StatusBar プラグイン
      • Cordova 11.0
        • Battery プラグイン
        • Camera プラグイン
        • Device プラグイン
        • Device Motion プラグイン
        • Device Orientation プラグイン
        • Dialog プラグイン
        • File プラグイン
        • Geolocation プラグイン
        • InAppBrowser プラグイン
        • Media プラグイン
        • Media Capture プラグイン
        • Network Information プラグイン
        • Splashscreen プラグイン
        • Vibration プラグイン
        • StatusBar プラグイン
      • Cordova 10.0
        • Battery プラグイン
        • Camera プラグイン
        • Device プラグイン
        • Device Motion プラグイン
        • Device Orientation プラグイン
        • Dialog プラグイン
        • File プラグイン
        • Geolocation プラグイン
        • InAppBrowser プラグイン
        • Media プラグイン
        • Media Capture プラグイン
        • Network Information プラグイン
        • Splashscreen プラグイン
        • Vibration プラグイン
        • StatusBar プラグイン
        • Whitelist プラグイン ( Android 専用 )
      • Cordova 9.0
        • バッテリー情報の取得 プラグイン
        • カメラ操作 プラグイン
        • 住所録の取得 プラグイン
        • 端末情報の取得 プラグイン
        • 端末のモーション検知 プラグイン
        • 端末のオリエンテーション検知 プラグイン
        • ダイアログの制御 プラグイン
        • ファイル操作 プラグイン
        • ファイル転送 プラグイン
        • 位置情報の取得 プラグイン
        • 表記の国際化対応 プラグイン
        • InAppBrowser プラグイン
        • メディア操作 プラグイン
        • メディアキャプチャー プラグイン
        • ネットワーク情報の取得 プラグイン
        • スプラッシュスクリーンの制御 プラグイン
        • バイブレーションの制御 プラグイン
        • ステータスバーの制御 プラグイン
        • ホワイトリストへの登録 プラグイン ( Android 専用 )
    • サードパーティー製プラグイン
      • AdvancedHTTPプラグイン
      • PhoneGap BarcodeScanner
      • Custom Config
      • Datepicker
      • Share ( Android 向け )
      • WebIntent ( Android 向け )
    • Monaca 提供プラグイン
      • アプリロジック暗号化 (Encrypt プラグイン)
      • In-App アップデーター (In-App Updater)
      • セキュア ストレージ
      • NFC リーダー
      • バーコードスキャナー
      • Androidビルドメモリサイズ設定
    • 外部サービス連携
      • Repro
      • AppsFlyer
    • 設定ファイル
      • Android
        • Android の設定
        • config.xml
        • AndroidManifest.xml
      • iOS
        • iOS の設定
        • config.xml
        • MonacaApp-info.plist
  • サンプル & Tips
    • Firestoreを利用する
    • サンプルアプリ
      • Twitter アプリ
      • Facebook アプリ
      • 広告 アプリ (AdMob)
      • Hello World アプリ
      • メモ帳アプリ
      • ブロック崩しゲーム
      • Flickrアプリ
      • TODO管理 アプリ
      • 電車図鑑アプリ
      • 時計アプリ
      • 誕生年の計算アプリ
      • おみくじ占いアプリ
      • RSS リーダーアプリ
    • 開発 Tips
      • 音楽の再生方法
      • スプラッシュ画像の制御方法
      • データベースの利用方法
  • Webpack5への更新
  • 機能
    • SNS 認証
    • プッシュ通知
    • データベース
  • 外部サービス連携ガイド
    • Firebase
      • アプリの登録と設定ファイルの取得
  • 移行ガイド
    • ニフクラ mobile backend
      • プッシュ通知
        • Firebaseサービスの設定
        • ソースコードの移行
      • データストア
        • ソースコードの移行
        • データの移行
        • データ移行スクリプト実行手順
      • 会員管理・認証
        • 会員管理 データの移行
        • Firebase Authentication パスワード再設定サンプル
        • Firebase Authenticationを使用したユーザー名認証の方法
      • スクリプト
        • Firebase Functions開発環境の作成
        • サンプル共通項目
        • サンプル1(GETサンプル)
        • サンプル2(POSTサンプル)
        • サンプル3(DELETEサンプル)
        • エミュレータでのテスト
      • ファイルストア
        • ファイルアップロード
        • ファイル検索
        • ファイル一覧表示
        • ファイル削除
  • FAQ
    • 概要
    • IDE
    • ビルド
    • リリース
    • 契約プラン
    • アプリケーション
    • 使用方法
    • Freeプラン
    • デバッガー
  • 対応環境
  • トラブルシューティング
    • プレビューログがリロードを繰り返す (Vue packages version mismatch error)
  • Monaca製品サイト
  • 運営会社
  • English
GitBook提供
このページ内
  • デモ
  • ファイル構成
  • 必要な JS/CSS コンポーネント
  • ソースコードの解説
  • js/main.js

役に立ちましたか?

  1. サンプル & Tips
  2. サンプルアプリ

ブロック崩しゲーム

前へメモ帳アプリ次へFlickrアプリ

最終更新 2 年前

役に立ちましたか?

pixi.js を使用したサンプルゲームです。 pixi.js は、非常に高速な、HTML5 の 2D レンダリング エンジンです。WebGL を基盤としています [ WebGL 未対応のブラウザーでは、Canvas にフォールバック ( fallback / 切り替え ) します ]。Pixi の詳細は、 をご確認ください。このゲームでは、ボールが画面下に落ちないように、パドルを操作しながら、煉瓦状に積まれたブロックを崩していきます。すべてのブロックを崩し終えたところで、ゲームクリアとなります。

デモ

テスト環境

  • Android 11.0

  • iOS 14.3

ファイル構成

ファイル

説明

index.html

スタート画面のページ ( ホーム画面のページ )

js/main.js

アプリ内でさまざまな処理を行う JavaScript ファイル

css/style.css

アプリに適用する共通スタイルシート

img/*.png

このテンプレートで使用する、すべてのイメージファイル

res/VT323-Regular.ttf

TrueType のフォン

必要な JS/CSS コンポーネント

  • Pixi

ソースコードの解説

js/main.js

main.js は、アプリ内のさまざまな処理を定義している JavaScript ファイルです。

BB オブジェクトのコードを次に記します。こちらが、アプリで使用する、メインのオブジェクトとなります。プロパティには、スクリーンサイズ用 ( screenSize )、パドル用 ( paddle )、ボール用 ( balls )、ブロック用 ( blocks )、スコア用 ( score ) などがあります。メソッドには、マップの作成用 ( setMap() )、ボールの配置用 ( addBall() )、パドルの配置用 ( addPaddle() )、ゲームのリセット用 ( reset() )、スコアの計算用 ( addScore() )、ゲームの終了用 ( endGame() ) などがあります。

...
var BB = {
    stage: new PIXI.Stage(0x000000),
    renderer: null,
    screenSize: null,
    paddle: null,
    balls: [],
    blocks: [],
    score: 0,
    scoreLabel: null,
    accelLabel: null,
    isMouseDown: false,

    // Create blocks map
    setMap: function() {
        var blockMap = [
            [null,      null,       null,       null,       null,       'blue',     null,       null,       null,       null],
            [null,      null,       null,       null,       'red',      'red',      'blue',     null,       null,       null],
            [null,      null,       null,       'red',      'red',      null,       null,       'blue',     null,       null],
            [null,      null,       'red',      'red',      null,       null,       null,       null,       'blue',     null],
            [null,      'red',      'red',      null,       null,       'gold',     null,       null,       'silver',   'silver'],
            [null,      null,       'red',      'red',       null,       null,       null,       'silver',   'silver',   null],
            [null,      null,       null,       'red',      'red',       null,       'silver',   'silver',   null,       null],
            [null,      null,       null,       null,       'silver',   'silver',   'silver',   null,       null,       null],
            [null,      null,       null,       null,       null,       'silver',   null,       null,       null,       null]
        ];

        for(j = 0; j < blockMap.length; j++) {
            for(i = 0; i < blockMap[j].length; i++) {
                if(blockMap[j][i] !== null) {
                    var block = BB.addBlock(10 + (30 * i), 80 + (12 * j), blockMap[j][i]);
                }
            }
        }
    },

    /**
     * @param {int} x
     * @param {int} y
     * @param {String} color red,blue,silver,gold
     * @return {Object} block
     **/
    addBlock: function(x, y, color) {
        switch (color) {
            case "red":
            case "blue":
                var point = SETTINGS_POINT;
                break;
            case "silver":
                var point = SETTINGS_POINT_SILVER;
                break;
            case "gold":
                var point = SETTINGS_POINT_GOLD;
                break;
            default:
                var point = SETTINGS_POINT;
                color = "red";
                break;
        }

        var texture = PIXI.Texture.fromImage(imgPath["block_" + color], false);
        var block = new PIXI.Sprite(texture);

        block.anchor.x = 0.5;
        block.anchor.y = 0.5;

        block.position.x = x;
        block.position.y = y;

        block.width = 30;
        block.height = 12;

        block.point = point;

        BB.stage.addChild(block);
        BB.blocks.push(block);

        return block;
    },

    // Create a ball and add it to PIXI.Stage
    addBall: function() {
        var texture = PIXI.Texture.fromImage(imgPath["ball"], false);
        var ball = new PIXI.Sprite(texture);

        ball.anchor.x = 0.5;
        ball.anchor.y = 0.5;

        ball.position.x = parseInt(BB.renderer.width * 0.5);
        ball.position.y = 200;

        ball.width = 10;
        ball.height = 10;

        ball.delta = {
            'x' : Math.random() - 0.5,
            'y' : -0.4
        };

        BB.stage.addChild(ball);
        BB.balls.push(ball);
    },

    // Create a paddle and add it to PIXI.Stage
    addPaddle: function() {
        var texture = PIXI.Texture.fromImage(imgPath["paddle"], false);
        BB.paddle = new PIXI.Sprite(texture);

        BB.paddle.anchor.x = 0.5;
        BB.paddle.anchor.y = 0.5;

        BB.paddle.position.x = parseInt(BB.renderer.width * 0.5);
        BB.paddle.position.y = BB.renderer.height - 60;

        BB.paddle.width = 60;
        BB.paddle.height = 10;

        BB.paddle.accel = 0;
        BB.paddle.delta = {
            'x' : Math.random() - 0.5,
            'y' : -3.8
        };

        BB.stage.addChild(BB.paddle);
    },

    /**
     * Add points to current score
     * @param {int} val points to add
     */
    addScore: function(val) {
        BB.score += parseInt(val);
        BB.scoreLabel.setText(BB.score);
    },

    /**
     * Set score
     * @param {int} val new score
     */
    setScore: function(val) {
        BB.score = val;
        BB.scoreLabel.setText(BB.score);
    },

    /**
     * callback for Core Cordova Plugins Acceleration Watch
     * @param {Object} a a.x, a.y, a.z
     */
    updateAcceleration: function(a) {
        var accelText = "", ac = a.x.toFixed(2);

        if(a.x > 0) accelText = '+' + String(ac);
        else accelText = String(ac);

        // Use parameter x to move paddle
        if (BB.paddle !== null) {
          if (BB.paddle.accel / ac > 2.0) {

          } else if (BB.paddle.accel / ac > 0) {
            BB.paddle.accel += ac * SETTINGS_PADDLE_ACCEL;
          } else {
            BB.paddle.accel = ac * SETTINGS_PADDLE_ACCEL;
          }
        }

        BB.accelLabel.setText(accelText);
    },

    // Reset current game and start new one
    reset: function() {
        //Reset (remove all children in the stage if exists)
        for (var i = BB.stage.children.length - 1; i >= 0; i--) {
            BB.stage.removeChildAt(i);
        }

        BB.balls = [];
        BB.blocks = [];
        BB.setMap();
        for (var i = 0; i < SETTINGS_BALL_NUM; i++) {
            BB.addBall();
        }
        BB.addPaddle();

        var resetLabel = new PIXI.Text("RESET", {font: "24px/1.2 vt", fill: "red"});
        resetLabel.position.x = 18;
        resetLabel.position.y = BB.renderer.height - 52;
        BB.stage.addChild(resetLabel);
        resetLabel.buttonMode = true;
        resetLabel.interactive = true;
        resetLabel.click = resetLabel.tap = function(data) {
            BB.reset();
        };
        setTimeout(function() {
            resetLabel.setText("RESET"); //for Android
        }, 1000, resetLabel);

        var label = new PIXI.Text("SCORE:", {font: "24px/1.2 vt", fill: "red"});
        label.position.x = 20;
        label.position.y = 20;
        BB.stage.addChild(label);
        setTimeout(function() {
            label.setText("SCORE:"); //for Android
        }, 1000, label);

        BB.scoreLabel = new PIXI.Text("0", {font: "24px/1.2 vt", fill: "white"});
        BB.scoreLabel.position.x = 90;
        BB.scoreLabel.position.y = 20;
        BB.stage.addChild(BB.scoreLabel);
        BB.setScore(0);

        /*
        var label = new PIXI.Text("ACCEL:", {font: "24px/1.2 vt", fill: "red"});
        label.position.x = 160;
        label.position.y = 20;
        BB.stage.addChild(label);
        label.setText("ACCEL:"); //for Android

        BB.accelLabel = new PIXI.Text("0", {font: "24px/1.2 vt", fill: "white"});
        BB.accelLabel.position.x = 230;
        BB.accelLabel.position.y = 20;
        BB.stage.addChild(BB.accelLabel);
        */

        BB.gameState = GAMESTATE_PLAY;
    },

    /**
     * Check whether the ball hits the object
     * @param {PIXI.Sprite} ball
     * @param {PIXI.Sprite} obj target object
     */
    isBallHit: function(ball, obj) {
        return (ball.position.x > (obj.position.x - (obj.width * 0.5))) &&
            (ball.position.x < (obj.position.x + (obj.width * 0.5))) &&
            (ball.position.y > (obj.position.y - (obj.height * 0.5))) &&
            (ball.position.y < (obj.position.y + (obj.height * 0.5)));
    },

    // Game Over
    endGame: function() {
        BB.gameState = GAMESTATE_STOP;
        vibrate();
    },

    // Game Clear
    clearGame: function() {
        if(typeof navigator.notification !== 'undefined') navigator.notification.alert("Cleared!", function(){}, "Congraturations");
        else alert("Cleared!");

        BB.gameState = GAMESTATE_STOP;
    }
}
...

このページの読み込みが開始されると、 init() が呼び出されます。Cordova 側の準備が完了したとき、または、端末の種類を検知できなかったとき、いずれの場合でも、init() が呼び出されます。

...
window.onload = function() {
    if(getUa() === false) init();
    else document.addEventListener("deviceready", init, false);
}
...

init() 関数のコードを次に記します。この関数では、使用されている端末の種類に応じた、BB オブジェクトのレンダリングを行います。次に、パドルに対して、リスナーを設定します。そして、各イベントに応じて、パドルの位置を決めます。

...
function init() {
    // Accelerometer
    /*
    if (typeof navigator.accelerometer !== 'undefined' && !accelerationWatch) {
        accelerationWatch = navigator.accelerometer.watchAcceleration(
            BB.updateAcceleration,
            function(ex) {
                alert("accel fail (" + ex.name + ": " + ex.message + ")");
            },
            {frequency: SETTINGS_ACCELEROMETER_RELOAD_FREQ}
        );
    }
    */
    BB.screenSize = setBound();

    BB.renderer = (getUa() === "Android") ? new PIXI.CanvasRenderer(BB.screenSize.width, BB.screenSize.height) : new PIXI.autoDetectRenderer(BB.screenSize.width, BB.screenSize.height),
    BB.renderer.transparent = false;
    document.body.appendChild(BB.renderer.view);

    setScale(BB.screenSize);

    BB.reset();

    // Event listeners to control the paddle
    window.addEventListener("touchmove", function(e) {
        BB.paddle.position.x = e.touches[0].clientX / BB.screenSize.zoom;
    });

    window.addEventListener("mousedown", function(e) {
        BB.isMouseDown = true;
    });

    window.addEventListener("mouseup", function(e) {
        BB.isMouseDown = false;
    });

    window.addEventListener("mousemove", function(e) {
        if(BB.isMouseDown) BB.paddle.position.x = e.clientX;
    });

    window.addEventListener("keydown", function(e) {
        switch (e.which) {
            case 37:
                BB.paddle.position.x -= 4;
                BB.paddle.accel += (SETTINGS_PADDLE_ACCEL * 0.1);
                break;
            case 39:
                BB.paddle.position.x += 4;
                BB.paddle.accel -= (SETTINGS_PADDLE_ACCEL * 0.1);
                break;
            case 38:
                BB.paddle.position.y -= 1;
                break;
        }
    });

    requestAnimFrame(animate);
}
...

getUa() 関数を使用して、端末の種類を検知します。検知できない場合には、 false を返します。

...
function getUa() {
    if ((navigator.userAgent.indexOf('iPhone') > 0 && navigator.userAgent.indexOf('iPad') == -1) || navigator.userAgent.indexOf('iPod') > 0 ) {
        return 'iPhone';
    } else if(navigator.userAgent.indexOf('iPad') > 0) {
        return 'iPad';
    } else if(navigator.userAgent.indexOf('Android') > 0) {
        return 'Android';
    } else return false;
}
...
こちら
プロジェクトをインポート