Undefined

この記事は1年以上前に書かれたものです。現在の状況にそぐわない場合がございますのでご注意ください。

JavaScriptで三目並べゲームをつくる 第4回

プレイヤークラスオブジェクトを実装する

この記事について

今回は過去回の記事でご紹介したクラスモジュールを使用して、プレイヤークラスオブジェクトの実装をご紹介したいと思います。

三目並べゲームの完成形はこちらです。

クラスオブジェクト

クラスの概要

概要
プレイヤーの状態を受け持つクラスオブジェクトです。
プレイヤーの設定情報や選択したマス目の状態を管理します。ゲームスタート時にはプレイヤーの準備をします。

どんな情報を受け持つ? (プロパティ) どんな仕事を受け持つ? (メソッド)
  • プレイヤーの名前
  • プレイヤーが選択したときのマス目の色
  • オートプレイヤーかどうか
  • プレイヤーが選択したマス目
  • (リ)スタート時プレイデータを(リ)セットする
  • プレイヤーが選択したマス目を保持する
  • オートプレイかどうか確認する
  • オートプレイ時、マス目を自動選択する

コンストラクタ

/* コンストラクタ */
var that = function Player(player) {
  :
}

ゲームプレイ初回のプレイ開始時に実行されます。引数playerはゲーム設定オプションのプレイヤーひとり分の設定データです。

プレイヤーの設定データ

{
    name : 'プレイヤー1', // プレイヤー表示名
    color: '#d43c32', // マス目の色
    auto : false       // オートプレイかどうか
}

どんな情報を持っているか (プロパティ)

// 表示名
this.name  = player.name;
// マス目色
this.color = player.color;
// オートプレイ
this.auto  = player.auto;
// 選択したマス目
this.ownUnits;
// カスタムイベント
this.ev = {};

/* DOMアクセス */
// プレイヤー(DOMツリーには追加しない)
this.playerEl = document.createElement('div');

プレイヤークラスオブジェクトが受け持つ情報はシンプルです。各プロパティが保持する情報はコメントの通りですー。

どんな通知を受け取るか(イベント)

/* カスタムイベント設定 */
// ゲームのターンが進んだとき
this.ev.turn = document.createEvent('Event');
this.ev.turn.initEvent('player.turn', false, true);

// プレイヤーがマス目を選択したとき
this.ev.add = document.createEvent('Event');
this.ev.add.initEvent('player.add', false, true);

// リスタートするとき 
this.ev.reset = document.createEvent('Event');
this.ev.reset.initEvent('player.reset', false, true);

/* イベント */
// ゲームのターンが進んだとき
this.playerEl.addEventListener('player.turn', this.turn.bind(this), false);

// プレイヤーがマス目を選択したとき
this.playerEl.addEventListener('player.add', this.add.bind(this), false);

// リスタートするとき 
this.playerEl.addEventListener('player.reset', this.reset.bind(this), false);

みっつのカスタムイベントを使用しています。

  1. イベントタイプplayer.turnは、ゲームが開始されたときターンが進んだときに発生します。
  2. イベントタイプplayer.addは、マス目を選択したときに発生します。
  3. イベントタイプplayer.resetは、ゲームが開始されたときに発生します。

どんな仕事道具を持っているか

turnメソッド

/**
 * turn
 * ターン毎の処理を実行する
 */
turn: function() {
  // ゲームボードに通知する
  GAME.board.disabledEl.dispatchEvent(GAME.board.ev.disabled);

  // オートプレイヤーだったら
  if(this.isAuto()) {
    // マス目を自動で選択する
    this.autoPlay();
  }
},

ゲームが開始されたときとターンが進んだときに実行されるメソッドです。現在のプレイヤーがオートプレイヤーだったときはマス目の自動選択処理に入ります。そうでない場合はプレイヤーのマス目選択待ちに入ります。

先頭にあるゲームボードへの通知は、オートプレイヤー時にマス目の選択を不可能にしているのですが、プレイヤーの持つ処理の中に唐突に置かれているのは不適切ですね。本来はゲーム進行管理クラスに置くべき処理だと思います。

isAutoメソッド

/**
 * isAuto
 *  オートプレイかどうか
 *
 * @return boolean オートプレイかどうか
 */
isAuto: function() {
  return this.auto;
},

現在のプレイヤーがオートプレイヤーかどうか判定するメソッドです。プレイヤー設定のthis.autoプロパティを返しているだけですね。

addメソッド

/**
 * add
 * 現在のプレイヤーが選択したマス目を追加する
 */
add: function() {
  // 追加
  this.ownUnits.push(GAME.board.curSelect);

  // 昇順でソートする
  this.ownUnits.sort(function(a, b) {
    return a - b;
  });
},

選択したマス目をthis.ownUnitsプロパティに追加するメソッドです。マス目を選択したときに実行されます。

resetメソッド

/**
 * reset
 *  プレイデータをリセットする
 */
reset: function() {
  this.ownUnits = [];
},

プレイヤーの持つプレイ状態をリセットするメソッドです。ゲームが開始されたときに実行されます。プレイヤーの持つ状態はthis.ownUnitsプロパティの選択したマス目リストのみです。

autoPlayメソッド

/**
 * autoPlay
 * マス目を自動で選択する
 */
autoPlay: function() {
  var canPutArr = this.getCanPut(),
      random    = Math.floor(Math.random() * canPutArr.length),
      selectInd = canPutArr[random],
      SECONDS   = 1000,
      min       = 0.5 * SECONDS,
      max       = 2.5 * SECONDS,
      thinking  = Math.ceil(Math.random() * (max - min) + min);

  // 考えてる風な演出
  setTimeout(function() {
    GAME.board.unitsEls[selectInd].dispatchEvent(GAME.board.ev.autoClick);
  }, thinking);
},

マス目を自動選択するメソッドです。ゲームが開始されたときとターンが進んだとき、オートプレイヤーの場合に実行されます。自動選択といっても単に選択されてないマス目をランダムにピックアップしているだけです^^;

6〜8行目:選択されていないマス目リストからマス目を取得しています。

9〜17行目:minmaxの間でランダムな秒数thinkingを作って、その秒数後にマス目のクリックイベントを起こすことで(15〜17行目)オートプレイヤーが考えてるような間をとってます。

getCanPutメソッド

/**
 * getCanPut
 * まだ選択されていないマス目リストを取得する
 * 
 * @return array まだ選択されていないマス目リスト
 */
getCanPut: function() {
  var canPutArr = GAME.board.allUnitsArray.filter(function(el, ind, arr) {
    return -1 === GAME.board.selectedNum.indexOf(arr[ind]);
  });
  return canPutArr;
}

マス目を自動で選択するにあたって選択されていないマス目のリストを決定するメソッドです。

ゲームボードインスタンスの持つ選択済みマス目リストにあるインデックスを、マス目リストから取り除いています。しかし、選択されていないマス目の情報はプレイヤーとは関わりがないので、本来はこの処理はゲームボードインスタンスが持つべきものですね。


お読みいただきありがとうございました!次回はゲームボードクラスオブジェクトを実装していきたいと思います。

to top