第31回コインの表示処理

コインの表示処理(プログラムでマリオを作る第31回)

前回はコインの取得処理を書いたので、今回は取得したコイン数を表示させたいと思います。

解説

前回コインの取得処理を書いたので、今回はコインの枚数を表示させる処理を書きたいと思います。
まずは、数字のテクスチャを用意したので、テクスチャをresouceフォルダ内においてください。

数字のドット絵

画像は、横が20縦が17になっていて、0から9まで並んでいます。
数値を切り取る際にコイン数とマッチさせることで、目的の数値を切り取ることができます。

例えば、コイン数が3だった場合3 * 20で、切り取る始点のX座標を計算できる。

スコアの描画ですが、main.jsに処理を書くので、
main.jsを開いてください。

main.js

先ほどのテクスチャを格納するグローバル変数の定義をします。

// chapter24
var gKuriboTex;
// chapter31追加
var gCoinTex;

loadTexture関数でテクスチャのロードをします。

/*
	テクスチャのロード
*/
function loadTexture(){
  // ...
  gCoinTex = new Image();
  gCoinTex.src = "resource/white_number.png";
}

次に、コインを描画したいんですが、
必要な関数の定義からしていきます。

まずは、コインの桁数を返す関数を定義したいので、
新しいファイルutils.jsを作成してください。

utils.js

ここに、与えられた数値の桁数を返す関数を書きます。

関数の中身ですが、数値を10で割っていき桁数を割り出すというものです。

/**
  与えられた数字の桁数を返す
  number : 桁数を返す数字
*/
function getDigits(number){
  if(number == NaN)return 0;
  var digits = 1;
  while(1){
    number /= 10;
    if(Math.floor(number) < 1)break;
    digits++;
  }
  return digits;  // 桁数
}

続いて、桁数に応じた割る単位を返す関数を定義します。

この関数の使い道としては、例えばコインの数が87枚だった場合
最大桁から順に描画したいので、10の位である8という数が取得したいので、
10の位の数値10で割りたいわけです。

次に桁数を下げて一の位の数値である7を描画したいので、1で割りたいのです。
そのための桁数に応じた割る単位を返すのがこの関数です。

/**
  桁数に応じた割る単位を返す

  例:2桁 10,3桁 100
  digits = 桁数
*/
function getMaxNumber(digits){
  var maxNum = 1;
  while(digits > 1){
    maxNum *= 10;
    digits--;
  }
  return maxNum;
}

材料が揃ったので、コインを描画する関数を書きます。
コインは画面の右端を基準に描画するようにして、
コインの枚数分描画するようにします。

コイン数83を例にとると、以下のようなロジックで描画されます。

1.まず、全体の桁数を割り出して、最初に描画するX座標を決める

2.83の最上位桁8を割り出すために10で割る。

3.最上位桁の次の桁である3を割り出すために、80を引く

4.最上位桁3を割り出すために1で割る

コインは100になると0に戻る仕様なので、3桁には届きませんが、
3桁以上でも同じ処理が繰り返されます。

/**
   コインの枚数の描画
*/
function drawCoin(posX,posY,coinNum){
  var digits = getDigits(coinNum);
  var maxNumber = getMaxNumber(digits);
  // 描画位置X
  var numberPosX = posX - (digits * 25);
  // 全て描画するまで
  while(maxNumber >= 1){
    // 一番上の桁数から描画する
    g_Ctx.drawImage(gCoinTex,Math.floor((coinNum / maxNumber)) * 20,0,20,17,numberPosX,posY,20,17);
    coinNum -= Math.floor(coinNum / maxNumber) * maxNumber;   // 一番上の桁数を引く(111だったら100引いて11)
    maxNumber = Math.floor(maxNumber / 10);   // 111だった場合11にする
    numberPosX += 25;
  }
}

続いて、drawCoin関数をDraw関数内で呼びます。

/*
	Draw
	描画
*/
function Draw(){
  // ...
  // コインの描画
  drawCoin(630,10,gMario.coinNum);
}

次に、コインの取得して、1upする処理が間違っていたので、修正します。

mario.jsを開いてください。

maio.js

>を>=に修正します。

/**
  コインを取得した時の処理
*/
Mario.prototype.getCoin = function(){
  // コインを100枚とったら1upさせる
  if(++this.coinNum >= 100){
    this.coinNum = 0;
    this.playerNum++;
  }
}

最後に、新しく作ったutils.jsをindex.htmlファイル内で読み込ませます。

index.html

<script lang="JavaScript" src=collisionUtils.js></script>
<script lang="JavaScript" src=utils.js></script>

実行して確かめてみましょう。

今回は、コイン数が正しく表示されているのかを、ファイルに直接デバッグの数値を埋め込んで確認しましたが、
手動でデバッグせずに済むようにテストコードを書く方法がメジャーです。

いずれできれば。

github