2014/05/08_JavaSctiptで麻雀の牌を表示

JavaScript

はじめに、今回はJavaScriptで麻雀の手牌を表示するものを作ります。
画像表示やクラスをつくるのに「enchant.js」があると便利なので使用します。
さて、まず製作した「コチラ」を御覧ください。
このように、手牌14枚を表示させることを目的とします。

プログラムの作成
まずはメイン関数から

enchant();
var game;
/*
 * Core
 * -rootScene
 * --Sprite(bear)
 */

window.onload = function(){
  game = new Game(1280,720);
  //fps
   game.fps=30;
  //事前読み込み
  game.preload("../img/mahjong.png");
  // ゲームの背景色を白に設定
  game.rootScene.backgroundColor = "green";

  //ゲームが初めて開いた時の関数
  game.onload=function(){
      var yama = new Yama();
      var player1 = new Player();

      
      for(var i=1;i<=14;i++)
      {
          player1.randomDraw(yama.mahjongHais);
          yama.pop_yama(player1.popNumber,1); 
      }
      player1.tehaiShow();
      player1.check();
      var label1 = new Label("字牌の数:" + player1.jihaiCount);
      var label2 = new Label("数牌の数:" + player1.kazuhaiCount);
      label1.font = "30px Palatino";
      label2.font = "30px Palatino";
      label1.y=112;
      label2.y=150;
      
     game.rootScene.addChild(label1);
     game.rootScene.addChild(label2);
     
     };//game
      game.start();
 };

mainの動きとしては

  1. ゲームの初期化処理を行う。(1~16行)
  2. yamaオブジェクト、playerオブジェクトを生成する(18~21行)
  3. player1はyamaからランダムに14枚引く(24~28行)
  4. player1の手牌を表示する。(29行)
  5. その後、字牌と数牌のカウントをする。(30~36行)
  6. rootSceneにaddChildしてlabel1と2を表示させる。

では次に牌クラスのソースです。

//牌クラス
Hai = Class.create(Sprite,{
          initialize: function()
          {
              Sprite.call(this,80,112); //スプライトの初期化 
              //数字、柄、字牌、イメージナンバー
              this.num;//数字
              this.pattern;//柄
              this.honor;//字牌
              this.imgnum;//イメージナンバー
              this.frame;
              this.image = game.assets['../img/mahjong.png']; //画像の指定
          }
      });
 

これは牌クラスでして、山をつくるために牌クラスをつくりました。
牌クラスのオブジェクトを136枚つくって山をつくるようなイメージです。
プログラムの中身としては、「数字」「柄」「字牌」「イメージナンバー」「フレーム」「イメージ」をフィールドとして持っている。
こういうのって Javaならば抽象クラスとかインターフェイスでいいんですかね~。

では次に、山クラスです

//山クラス
Yama = Class.create(Sprite,{
          initialize: function()
          {
              this.mahjongHais=[];
              var i=0;
              var fr=0;
              var jihai = ["東","南","西","北","白","發","中"];
              //麻雀の柄を生成。
              for(var pat=1;pat<=3;pat++)
              {
                  //萬子:1 筒子:2 索子:3
                for(var nu=1;nu<=9;nu++)
                {
                      for(var x=1;x<=4;x++)
                      {
                        this.mahjongHais[i]=new Hai();
                        this.mahjongHais[i].num=nu;
                        this.mahjongHais[i].pattern=pat;
                        this.mahjongHais[i].honor=null;
                        this.mahjongHais[i].frame=fr;
                        this.mahjongHais[i].imgnum=fr;
                        i++;
                      }
                      fr++;
                }
              }
                  for(var tekito=0; tekito < jihai.length ; tekito++)
                  {
                      for(var x = 1;x <= 4 ; x++)
                      {
                        this.mahjongHais[i]=new Hai();
                        this.mahjongHais[i].num=null;
                        this.mahjongHais[i].pattern=null;
                        this.mahjongHais[i].honor=jihai[tekito];
                        this.mahjongHais[i].frame=fr;
                        this.mahjongHais[i].imgnum=fr;
                        i++; 
                      }
                    fr++;
                  }
          },
              pop_yama:function(index,elementNumber)
              {
                  this.mahjongHais.splice(index,elementNumber);
              }
          });
 

初期化処理:

牌クラスから山クラスを生成する。
牌クラスのオブジェクトを生成し、麻雀牌の配列に入れる。
これを136枚(麻雀の全牌)分繰り返す。

関数:

pop_yamaは麻雀牌をindex:要素番号からelementNumber:削除する要素の数までを山から削除する。
この関数はplayerクラスのrandomDraw関数を実行した時などに使う。

次に、playerクラスです

 Player = Class.create(Sprite,{
     initialize: function()
     {
          this.playerTehai=[];
          this.popNumber;
     },
     //引数:山の配列,引く数
     randomDraw:function(array)
     {
         this.popNumber=rand(array.length);
         this.playerTehai.push(array[this.popNumber]);
     },
     tehaiShow:function()
     {
         var tehaix=0;
         var tempPlayerTehai=[];
         //昇順ソート,バブルソート
         for(var out=0;out < this.playerTehai.length-1;out++)
         {
             for(var i = 0;i < this.playerTehai.length-1;i++)
             {
                 //i+1番目が比較できない時
                 if(this.playerTehai[i+1] === null)
                     break;
                 //i番目のフレームがi+1番目より大きい時交換する
                 if(this.playerTehai[i].frame>this.playerTehai[i+1].frame)
                 {
                     tempPlayerTehai[i]=this.playerTehai[i];
                     this.playerTehai[i] = this.playerTehai[i+1];
                     this.playerTehai[i+1] = tempPlayerTehai[i];
                 }  
             }
         }
        //手牌をaddChildしてシーンに追加
         for(var i=0;i < this.playerTehai.length;i++)
         {
            this.playerTehai[i].x=tehaix;
            game.rootScene.addChild(this.playerTehai[i]);
            tehaix+=80;
         }
     },
     check:function()
     {
         this.count=[];
         this.jihaiCount=0;
         this.kazuhaiCount=0;
//字牌・数牌チェック
         for(var i=0;i < this.playerTehai.length;i++)
             {
                 if(this.playerTehai[i].honor == null)
                 {
                     this.kazuhaiCount+=1;         
                 }
                 else
                 {
                     this.jihaiCount+=1;
                 }      
             }
     }
});
 

初期化処理:

プレイヤーの手牌の配列、popNumber:削除する数を宣言する。

関数:

  1. randomDraw:rand関数で0~山の配列の長さまでの数を生成。
  2. それを削除ナンバーとして持っておき、プレイヤーの手牌配列にいれる。

  1. tehaiShow:手牌をソートしてから表示する。
  2. 一つ一つの牌は、フレーム番号を覚えているのでその数で昇順ソートを行う。

  1. check:count配列、jihaiCount:字牌の数、kazuhaiCount:数牌の数を用意する。
  2. プレイヤーの手牌を順に走査していき、字牌であるかどうかを調べる。
  3. 一つ一つの牌には字牌であるかどうかを判断するものが付いているのでそれを使用する。

このような感じです。

最後に、ランダム関数です。

      //ランダム関数
   function rand(n){
     return parseInt(Math.random() * (n));
   }

Math.random()と引数をかけてparseIntするだけ。