Help us understand the problem. What is going on with this article?

【phina.js】ゲーム作成チュートリアル(マインスイーパー)(その2)【爆弾の配置】

More than 1 year has passed since last update.

※これまでのチュートリアルはphina.js チュートリアル集にまとめています。

今回の目標

前回はパネルをグリッド状に配置しました。
今回はマインスイーパーの主役とも言える爆弾を配置します。爆弾はランダムな場所に配置されるようにします。

minesweeper-tut-2.png

今回のコード

phina.globalize();
// 定数
var SCREEN_WIDTH = 640; // 画面横サイズ
var PANEL_NUM_XY = 9; // 縦横のパネル数
var GRID_SIZE = (SCREEN_WIDTH - 10) / PANEL_NUM_XY; // グリッドのサイズ
var SCREEN_HEIGHT = GRID_SIZE * 11; // 画面縦サイズ
var PANEL_SIZE = GRID_SIZE * 0.9; // パネルの大きさ
var PANEL_OFFSET = (GRID_SIZE + 10) / 2; // オフセット値
var BOMB_NUM = 10; // 爆弾数
// メインシーン
phina.define('MainScene', {
  superClass: 'DisplayScene',
  // コンストラクタ
  init: function() {
    // 親クラス初期化
    this.superInit({
      width: SCREEN_WIDTH,
      height: SCREEN_HEIGHT,
    });
    // 背景色
    this.backgroundColor = 'gray';
    // グリッド
    var grid = Grid(GRID_SIZE * PANEL_NUM_XY, PANEL_NUM_XY);
    // グループ
    var panelGroup = DisplayElement().addChildTo(this);
    // 爆弾位置をランダムに決めた配列を作成
    var bombs = [];
    (PANEL_NUM_XY * PANEL_NUM_XY).times(function() {
      bombs.push(false);
    });
    bombs.fill(true, 0, 10).shuffle();
    // ピース配置
    PANEL_NUM_XY.times(function(spanX) {
      PANEL_NUM_XY.times(function(spanY) {
        // パネル作成
        var panel = Panel().addChildTo(panelGroup);
        // Gridを利用して配置
        panel.x = grid.span(spanX) + PANEL_OFFSET;
        panel.y = grid.span(spanY) + PANEL_OFFSET;
        // パネルに爆弾情報を紐づける
        panel.isBomb = bombs[spanX * PANEL_NUM_XY + spanY];
        // 爆弾なら表示
        if (panel.isBomb) Bomb().addChildTo(panel);
      });
    });
  },
});
// パネルクラス
phina.define('Panel', {
  // RectangleShapeを継承
  superClass: 'RectangleShape',
    // コンストラクタ
    init: function() {
      // 親クラス初期化
      this.superInit({
        width: PANEL_SIZE,
        height: PANEL_SIZE,
        fill: 'silver', // 塗りつぶし色
        stroke: 'white', // 枠の色
        cornerRadius: 2, // 角の丸み
      });
    },
});
// 爆弾クラス
phina.define('Bomb', {
  // Shapeを継承
  superClass: 'Shape',
    // コンストラクタ
    init: function() {
      // 親クラス初期化
      this.superInit({
        width: GRID_SIZE,
        height: GRID_SIZE,
        backgroundColor: 'transparent',
      });
      // 導線
      RectangleShape({
        width: PANEL_SIZE / 8,
        height: PANEL_SIZE / 8,
        fill: "navy",
        stroke: 'white',
        y: -20,
      }).addChildTo(this);
      // 本体
      CircleShape({
        radius: PANEL_SIZE / 4,
        fill: "navy",
        stroke: 'white',
      }).addChildTo(this);
    },
});
// メイン
phina.main(function() {
  var app = GameApp({
    startLabel: 'main', // メイン画面からスタート
    width: SCREEN_WIDTH,
    height: SCREEN_HEIGHT,
  });
  app.run();
});

[runstantで確認]

コード説明

定数の定義

// 定数

var BOMB_NUM = 10; // 爆弾数

設置する爆弾数を定義します。

爆弾位置情報の作成

init: function() {
  
  // 爆弾位置をランダムに決めた配列を作成
  var bombs = [];
  (PANEL_NUM_XY * PANEL_NUM_XY).times(function() {
    bombs.push(false);
  });
  bombs.fill(true, 0, 10).shuffle();
  • 爆弾位置格納用の配列を作ります。
  • 一旦falseで埋めて、先頭の10個までtrueに置き換えてからshuffle関数で要素をランダムに並び替えています。

爆弾位置情報をパネルに紐づける

  // ピース配置
  PANEL_NUM_XY.times(function(spanX) {
    PANEL_NUM_XY.times(function(spanY) {
      
      // パネルに爆弾情報を紐づける
      panel.isBomb = bombs[spanX * PANEL_NUM_XY + spanY];
      // 爆弾なら表示
      if (panel.isBomb) Bomb().addChildTo(panel);
    });
  });
},
  • パネルのisBombプロパティに爆弾かどうかの情報true or falseを設定しています。
  • isBombプロパティがtrueなら、爆弾を配置します。

爆弾クラス

// 爆弾クラス
phina.define('Bomb', {
  // Shapeを継承
  superClass: 'Shape',
    // コンストラクタ
    init: function() {
      // 親クラス初期化
      this.superInit({
        width: GRID_SIZE,
        height: GRID_SIZE,
        backgroundColor: 'transparent',
      });
      // 導線
      RectangleShape({
        width: PANEL_SIZE / 8,
        height: PANEL_SIZE / 8,
        fill: "navy",
        stroke: 'white',
        y: -20,
      }).addChildTo(this);
      // 本体
      CircleShape({
        radius: PANEL_SIZE / 4,
        fill: "navy",
        stroke: 'white',
      }).addChildTo(this);
    },
});
  • 新たにBombクラスを作成しています。
  • 爆弾はスプライト画像を使っても良いのですが、今回は敢えてShapeを組み合わせて表現してみました。
  • 素のShapebackgroundColorが設定されているので、これを透明にします。
  • 導線は本体の少し上になるようにy座標を指定しています。この場合、親から見た相対座標になるということに注意してください。

今回はここまで

ここまでで、爆弾をランダムに配置することができました。読み込まれる度に配置が異なることが確認できるかと思います。
次回は、パネルを開く処理を追加します。

alkn203
javascriptのゲームライブラリphina.jsを愛用している趣味プログラマ。ファミコン世代。 Hobbyist programmer javascript/html5/phina.js/retro games
http://qiita.com/alkn203/items/bca3222f6b409382fe20
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away