ゲーム開発をenchant.js(HTML5 + JavaScript)で! 【RPG(ロールプレイングゲーム)篇】 戦闘シーンにステータスゲージ(HPゲージ)を表示する

enchant.js
enchant.js / Ubiquitous Entertainment Inc.

 ”ゲーム開発をenchant.js(HTML5 + JavaScript)で! 【RPG(ロールプレイングゲーム)篇】 戦闘シーンにステータスウィンドウ(状態表示枠)を表示する”の記事でステータスウィンドウ(状態表示枠)を表示したが、その時に、最大数値と現状数値の把握もしたかったので、HPとSPにそれぞれゲージ枠も用意していた。以下だ。

windowstatus

 今回は、このゲージを現在のHP、SPに応じて動くようにしてみよう。

■実現方法は数多ある

 やり方はいっぱいある。canvasを使っても描けるし、画像を使ってもできる。とにかく色々な方法があるので、作ろうとしているゲームの特性や好みで、その方法を選んでほしい。

 今回、私は、背景画像にMAX状態のゲージを描いてしまって、それを現在のHP、SPに応じて「隠していく」という方法を取った。

■背景画像を修正する

 まず、背景画像を以下のように修正している。MAX状態のゲージを描いた。3DS版のドラクエ7風だ。

windowstatus

■ゲージを隠すための画像を用意する

 次に、ゲージを隠すための画像を用意する。1pxのゲージ精度を出したいので、「1px×4px」のサイズとし、色は、ステータスウィンドウ(状態表示枠)の背景と同じ、「#484848」とする。

 canvas等の制御ではなく画像にしておけば、後でデザインを変更したくなったときに、画像の差し替えだけで済む。

windowstatusgauge
 ※40倍に拡大表示して掲載

 ゲージ幅が96pxなのだが、この画像が1pxだからといって、この画像を最大で96個、配置するわけではない。この画像のwidthに0~96pxまでを設定して、拡縮して用いるのだ。

■ゲージを表示する

 では新しく用意した背景画像とゲージを使って、表示を確認してみよう。

[javascript firstline=”1″ highlight=”8″ title=”main.js”]
enchant();

var SCREEN_WIDTH = 480; // ゲーム画面の幅.
var SCREEN_HEIGHT = 640; // ゲーム画面の高さ.

var IMG_BG_SCENE_BATTLE = ‘./img/bgbattle.png’; // 戦闘シーン背景画像.
var IMG_BG_WINDOW_STATUS = ‘./img/windowstatus.png’; // ステータスウィンドウ背景画像.
var IMG_GAUGE_STATUS_HIDDEN = ‘./img/windowstatusgauge.png’; // ステータスゲージ隠し画像.

// バーチャルボタンを作成するクラス.
var Button = enchant.Class.create( enchant.Sprite, {
[/javascript]
[javascript firstline=”33″ highlight=”34″]
// pre(前)-load(読み込み)、ゲームで使用する素材を予め読込.
game.preload( ‘./img/xxx.png’, ‘./img/button.png’, IMG_BG_SCENE_BATTLE, IMG_BG_WINDOW_STATUS, IMG_GAUGE_STATUS_HIDDEN );

// メイン処理を実行.
game.onload = function() {
[/javascript]
[javascript firstline=”155″ highlight=”165,166,167,168″]
// ステータスウィンドウを作成するクラス.
var StatusWindow = enchant.Class.create( enchant.Sprite, {
// コンストラクタ.
initialize: function( scene, x, y ) {
enchant.Sprite.call( this, 120, 124 ); // 継承元をコール、幅と高さを設定.
this.image = game.assets[ IMG_BG_WINDOW_STATUS ]; // ステータスウィンドウ画像を設定.
this.x = x; // X座標.
this.y = y; // Y座標.
scene.addChild( this ); // シーンにステータスウィンドウを追加.

hp = 9999; // HPの初期化.
hpMax = 9999; // 最大HPの初期化.
sp = 9999; // SPの初期化.
spMax = 9999; // 最大SPの初期化.
[/javascript]
[javascript firstline=”218″ highlight=”226,227,228,229,230,231,232,234,235,236,237,238,239,240,246,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,268,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287″]
lv = new Label("1");
lv.color = ‘#f8f8f8’;
lv.x = this.x + 32;
lv.y = this.y + 96;
lv.width = 80;
lv.textAlign = "right";
scene.addChild( lv );

// HPゲージ隠し.
hpHiddenGauge = new Sprite( 1, 4 );
hpHiddenGauge.image = game.assets[ IMG_GAUGE_STATUS_HIDDEN ];
hpHiddenGauge.x = this.x + 108;
hpHiddenGauge.y = this.y + 58;
hpHiddenGauge.width = 0;
scene.addChild( hpHiddenGauge );

// SPゲージ隠し.
spHiddenGauge = new Sprite( 1, 4 );
spHiddenGauge.image = game.assets[ IMG_GAUGE_STATUS_HIDDEN ];
spHiddenGauge.x = this.x + 108;
spHiddenGauge.y = this.y + 88;
spHiddenGauge.width = 0;
scene.addChild( spHiddenGauge );
},
setName: function( value ) {
nameLabel.text = value;
},
setHP: function( value ) {
hp = value; // HP更新.
hpLabel.text = hp.toString().toTwoByteAlphaNumeric(); // 半角英数字文字列を全角文字列に変換する.
this.setHPGauge(); // HPゲージ更新.
},
setHPMax: function( value ) {
hpMax = value; // 最大HP更新.
this.setHPGauge(); // HPゲージ更新.
},
setHPGauge: function() {
var hiddenGaugeX = 108 – ( 96 – ( ( hp * 96 ) / hpMax ) );
if ( 107 < hiddenGaugeX ) {
hpHiddenGauge.width = 0; // 隠しゲージ幅を0にして見えないようにする.
//hpHiddenGauge.visible = false;
} else if ( 13 > hiddenGaugeX ) {
hpHiddenGauge.x = this.x + 12;
hpHiddenGauge.width = 96;
} else {
hpHiddenGauge.x = this.x + hiddenGaugeX;
hpHiddenGauge.width = 108 – hiddenGaugeX;
}
},
setSP: function( value ) {
sp = value; // SP更新.
spLabel.text = sp.toString().toTwoByteAlphaNumeric(); // 半角英数字文字列を全角文字列に変換する.
this.setSPGauge(); // SPゲージ更新.
},
setSPMax: function( value ) {
spMax = value; // 最大SP更新.
this.setSPGauge(); // SPゲージ更新.
},
setSPGauge: function() {
var hiddenGaugeX = 108 – ( 96 – ( ( sp * 96 ) / spMax ) );
if ( 107 < hiddenGaugeX ) {
spHiddenGauge.width = 0; // 隠しゲージ幅を0にして見えないようにする.
//spHiddenGauge.visible = false;
} else if ( 13 > hiddenGaugeX ) {
spHiddenGauge.x = this.x + 12;
spHiddenGauge.width = 96;
} else {
spHiddenGauge.x = this.x + hiddenGaugeX;
spHiddenGauge.width = 108 – hiddenGaugeX;
}
},
setLV: function( value ) {
lv.text = value.toString().toTwoByteAlphaNumeric(); // 半角英数字文字列を全角文字列に変換する.
}
});
[/javascript]

 「現在のHP/SP」と「最大のHP/SP」をメンバに保持するようにして、それら値を基にゲージの”隠し幅”を「setHPGauge()/setSPGauge()」にて算出している。

 「現在のHP/SP」、或いは、「最大のHP/SP」が更新されたら、「setHPGauge()/setSPGauge()」を呼び出すようにしている。例えば、ドラクエなら、命の木の実を食べて最大HPだけが上がった(現在のHPはそのまま)、なんていうケースでは、「setHPMax()」だけをコールすれば、ゲージも更新されるというわけだ。

 ちょっと注意だが、「setHPGauge()/setSPGauge()」は、「this.setHPGauge()/this.setSPGauge()」としないとアクセスできない。意外と付け忘れるものだ。

 また、現在と最大のHP/SPが同一の場合は、ゲージ隠し用の画像を「width = 0;」として非表示にしている。上記コード内でコメントで記載しているが、「visible = false;」という方法もある。

enchant81

 最大HPが9999、最大SPが9999として表示した場合の画像が上記だ。うまくゲージが表示されている。

■限界値の判定を設けておく

 最大HPが0は有り得ないし、現在のHPが最大値を超えているのも有り得ないので、もしものことを想定して、丸める判定を設けておこう。SPも同様だ。

[javascript firstline=”246″ highlight=”247,248,249,250,251,257,258,259″ title=”main.js”]
setHP: function( value ) {
if ( 0 > value ) { // マイナス値が設定された場合.
value = 0;
} else if ( hpMax < value ) { // 最大HPを超えた値が設定された場合.
value = hpMax;
}
hp = value; // HP更新.
hpLabel.text = hp.toString().toTwoByteAlphaNumeric(); // 半角英数字文字列を全角文字列に変換する.
this.setHPGauge(); // HPゲージ更新.
},
setHPMax: function( value ) {
if ( 1 > value ) { // 1未満の値が設定された場合.
value = 1;
}
hpMax = value; // 最大HP更新.
this.setHPGauge(); // HPゲージ更新.
},
[/javascript]

 しかし、SP(スキルポイント)は0が有り得る。例えばドラクエなら、戦士は魔法が使えない為、MPが0だったと思うが、SPもこういう考えだ。

[javascript firstline=”275″ highlight=”286,287,288″ title=”main.js”]
setSP: function( value ) {
if ( 0 > value ) { // マイナス値が設定された場合.
value = 0;
} else if ( spMax < value ) { // 最大SPを超えた値が設定された場合.
value = spMax;
}
sp = value; // SP更新.
spLabel.text = sp.toString().toTwoByteAlphaNumeric(); // 半角英数字文字列を全角文字列に変換する.
this.setSPGauge(); // SPゲージ更新.
},
setSPMax: function( value ) {
if ( 0 > value ) { // マイナス値が設定された場合.
value = 0;
}
spMax = value; // 最大SP更新.
this.setSPGauge(); // SPゲージ更新.
},
[/javascript]

 実はこれではまだ不十分なことにお気づきだろうか。以下の実行結果を見てほしい。このままでは、0なのにゲージがMAXになってしまう。

enchant82

■0除算に気をつける!

 ゲージの隠し幅を求める為に「setSPGauge()」では「spMax」で除算しているが、これが”0除算”となり、結果が「NaN」になってしまう。「NaN」の為、widthが0となり、隠しゲージ無しになって最大ゲージ表示となっている。

 以下のように修正しよう。

[javascript firstline=”292″ highlight=”293,294,295,296,297″ title=”main.js”]
setSPGauge: function() {
if ( 1 > spMax ) { // 最大SPが0の場合.
spHiddenGauge.x = this.x + 12; // SPゲージを
spHiddenGauge.width = 96; // すべて隠してしまう.
return;
}
var hiddenGaugeX = 108 – ( 96 – ( ( sp * 96 ) / spMax ) );
if ( 107 < hiddenGaugeX ) {
spHiddenGauge.width = 0; // 隠しゲージ幅を0にして見えないようにする.
} else if ( 13 > hiddenGaugeX ) {
spHiddenGauge.x = this.x + 12;
spHiddenGauge.width = 96;
} else {
spHiddenGauge.x = this.x + hiddenGaugeX;
spHiddenGauge.width = 108 – hiddenGaugeX;
}
},
[/javascript]

 これでうまくできた。

enchant83

 ちなみに、今回参考にした3DS版のドラクエ7は、これだ。

ドラゴンクエストVII エデンの戦士たち

 賛否両論あるようだが、私はドラクエ7のお話はあまり好きではない。石版ごとにストーリーが独立して存在しているので、頭の中で纏まって話が理解できないのと、主人公が旅をする目的がまったく分からない。キーファならまだしも、共感できない。

【関連記事】
 ≫ ゲーム開発をenchant.js(HTML5 + JavaScript)で! 【RPG(ロールプレイングゲーム)篇】 戦闘シーンにステータスウィンドウ(状態表示枠)を表示する
 ≫ ゲーム開発をenchant.js(HTML5 + JavaScript)で! 【RPG(ロールプレイングゲーム)篇】 戦闘シーンに切り替える
 ≫ ゲーム開発をenchant.js(HTML5 + JavaScript)で! 【導入篇】 バーチャルボタン(Aボタン/Bボタン/Xボタン/Yボタン)を表示してみる
 ≫ ゲーム開発をenchant.js(HTML5 + JavaScript)で! 【導入篇】 キャラクター画像をバーチャルパッド(十字方向キーパッド)で動かしてみる
 ≫ ゲーム開発をenchant.js(HTML5 + JavaScript)で! 【導入篇】 キャラクター画像をキー入力で動かしてみる
 ≫ ゲーム開発をenchant.js(HTML5 + JavaScript)で! 【導入篇】 キャラクター画像を表示してみる
 ≫ ゲーム開発をenchant.js(HTML5 + JavaScript)で! 【導入篇】 enchant.jsのダウンロードと開発準備

(アシベズヘア@ashibehair_m

ゲーム開発をenchant.js(HTML5 + JavaScript)で! 【RPG(ロールプレイングゲーム)篇】 戦闘シーンにステータスゲージ(HPゲージ)を表示する」への7件のフィードバック

  1. ピンバック: materialize.jp » ゲーム開発をenchant.js(HTML5 + JavaScript)で! 【RPG(ロールプレイングゲーム)篇】 戦闘シーンにステータスウィンドウ(状態表示枠)を表示する

  2. ピンバック: materialize.jp » ゲーム開発をenchant.js(HTML5 + JavaScript)で! 【導入篇】 enchant.jsのダウンロードと開発準備

  3. ピンバック: materialize.jp » ゲーム開発をenchant.js(HTML5 + JavaScript)で! 【RPG(ロールプレイングゲーム)篇】 戦闘シーンにバーチャルパッド(十字方向キーパッド)を表示する

  4. ピンバック: materialize.jp » ゲーム開発をenchant.js(HTML5 + JavaScript)で! 【RPG(ロールプレイングゲーム)篇】 戦闘シーンに表示する敵キャラのステータス情報を作成して、その名前をメッセージウ

  5. ピンバック: materialize.jp » ゲーム開発をenchant.js(HTML5 + JavaScript)で! 【RPG(ロールプレイングゲーム)篇】 戦闘シーンに戦闘用コマンド一覧(攻撃/特技/道具/防御/逃走)を表示する

  6. ピンバック: materialize.jp » WebViewで画面の右横にできる隙間を消す方法(スクロールバー表示領域を消す方法)

  7. ピンバック: ゲーム開発をenchant.js(HTML5 + JavaScript)で! 【導入篇】 enchant.jsのダウンロードと開発準備 | materialize.jp

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です