enchant.js / Ubiquitous Entertainment Inc.
戦闘中、ドラクエにしてもFFにしても、プレイヤーキャラの現在のHPやMPが画面上に表示されていると思う。それをステータスウィンドウ(状態表示枠)と呼んで、今回は、このステータスウィンドウ(状態表示枠)を表示してみることにする。
コードは、”ゲーム開発をenchant.js(HTML5 + JavaScript)で! 【RPG(ロールプレイングゲーム)篇】 戦闘シーンに切り替える”の記事で用いたものをベースに使う。
■ステータスウィンドウ(状態表示枠)の背景画像を用意する
すべてを描画するよりも、背景画像を用意した方が楽だと思ったので、私は以下のような背景画像を用意した。
表示する内容は、以下を想定した。最大数値と現状数値の把握もしたかったので、HPとMPにそれぞれゲージ枠も用意している。
・プレイヤー名
・HP(ヒットポイント)
・SP(スキルポイント)
・レベル
最大4人で戦うことを想定して、横幅は画面幅480pxの4等分、120pxにしている。そうすると、全角一文字20pxのフォントを表示したとして、名前が全角で5文字しか入らないので、今回作成するRPGの名前の制限文字数は5文字とすることに私はこの時点で決めた。
■ステータスウィンドウ(状態表示枠)の背景画像を表示する
では、この背景画像だけを戦闘シーンに表示(追加)してみよう。コードは以下の通りだ。
”ゲーム開発をenchant.js(HTML5 + JavaScript)で! 【導入篇】 バーチャルボタン(Aボタン/Bボタン/Xボタン/Yボタン)を表示してみる“の記事でバーチャルボタンを作成した際に、4つ同じボタンを作成するのは面倒だということでボタン作成をクラス化したが、今回も同様に、最大で4人分のステータス表示が必要になるので、予めクラス化してあるぞ。
[html firstline=”1″ highlight=”7″ 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 Button = enchant.Class.create( enchant.Sprite, {
[/html]
[html firstline=”25″ highlight=”33″]
window.onload = function() {
// 表示領域を設定(幅と高さ).
game = new Game( SCREEN_WIDTH, SCREEN_HEIGHT );
// frames(フレーム)per(毎)second(秒)、ゲーム進行スピードを設定.
game.fps = 24;
// pre(前)-load(読み込み)、ゲームで使用する素材を予め読込.
game.preload( ‘./img/xxx.png’, ‘./img/button.png’, IMG_BG_SCENE_BATTLE, IMG_BG_WINDOW_STATUS );
// メイン処理を実行.
game.onload = function() {
[/html]
[html firstline=”117″ highlight=”126,132,133,134,135,136,137,138,139,140,141,142″]
/**
* 新しいシーンを作成する関数.
*/
function createScene() {
var scene = new Scene(); // シーンを作成.
var bg = new Sprite( SCREEN_WIDTH, SCREEN_HEIGHT ); // 背景画像を配置、幅と高さを設定.
bg.image = game.assets[ IMG_BG_SCENE_BATTLE ]; // 予め読込した背景画像を設定.
scene.addChild( bg ); // シーンに背景画像を追加.
var sw = new StatusWindow( scene, 0, 366 ); // ステータスウィンドウを作成.
// 作成したシーンを返却.
return scene;
}
// ステータスウィンドウを作成するクラス.
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 ); // シーンにステータスウィンドウを追加.
}
});
[/html]
お、表示されてる!
折角なので、4人分を表示してみよう。
[html firstline=”117″ highlight=”126,127,128,129″ title=”main.js”]
/**
* 新しいシーンを作成する関数.
*/
function createScene() {
var scene = new Scene(); // シーンを作成.
var bg = new Sprite( SCREEN_WIDTH, SCREEN_HEIGHT ); // 背景画像を配置、幅と高さを設定.
bg.image = game.assets[ IMG_BG_SCENE_BATTLE ]; // 予め読込した背景画像を設定.
scene.addChild( bg ); // シーンに背景画像を追加.
var sw1 = new StatusWindow( scene, 0, 366 ); // ステータスウィンドウを作成.
var sw2 = new StatusWindow( scene, 120, 366 ); // ステータスウィンドウを作成.
var sw3 = new StatusWindow( scene, 240, 366 ); // ステータスウィンドウを作成.
var sw4 = new StatusWindow( scene, 360, 366 ); // ステータスウィンドウを作成.
// 作成したシーンを返却.
return scene;
}
[/html]
■文字列は「Label」で表示する
ステータスウィンドウの背景画像を表示して、ベースができたので、当初の予定通り、
・プレイヤー名
・HP(ヒットポイント)
・SP(スキルポイント)(状態表示枠)
・レベル
をステータスウィンドウ(状態表示枠)に表示したいと思う。これらは文字列として表示するが、文字列は、enchant.jsの「Label」という概念を用いて実現する。まずはコードを見てほしい。以下のコードを表示するとこのようになる。
[html firstline=”135″ highlight=”145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193″ title=”main.js”]
// ステータスウィンドウを作成するクラス.
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 ); // シーンにステータスウィンドウを追加.
var h = new Label("HP");
h.color = ‘#f8f8f8’;
h.x = this.x + 12;
h.y = this.y + 36;
scene.addChild( h );
var s = new Label("SP");
s.color = ‘#f8f8f8’;
s.x = this.x + 12;
s.y = this.y + 66;
scene.addChild( s );
var l = new Label("Lv");
l.color = ‘#f8f8f8’;
l.x = this.x + 12;
l.y = this.y + 96;
scene.addChild( l );
var name = new Label("マザパク侍");
name.color = ‘#f8f8f8’;
name.x = this.x + 10;
name.y = this.y + 10;
name.width = 100;
name.textAlign = "center";
scene.addChild( name );
var hp = new Label("234");
hp.color = ‘#f8f8f8’;
hp.x = this.x + 32;
hp.y = this.y + 36;
hp.width = 80;
hp.textAlign = "right";
scene.addChild( hp );
var sp = new Label("9999");
sp.color = ‘#f8f8f8’;
sp.x = this.x + 32;
sp.y = this.y + 66;
sp.width = 80;
sp.textAlign = "right";
scene.addChild( sp );
var 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 );
}
});
[/html]
クラスの中にそれぞれの状態値を書いたので、4つとも同じ内容になるのは当然の結果だが、それはちょっと置いておいて、まずLabelの解説だ。
Labelのリファレンス
[browser-shot width=”240″ url=”http://wise9.github.io/enchant.js/doc/core/ja/symbols/enchant.Label.html”]
Field Detail
color
文字色の指定. CSSの’color’プロパティと同様の形式で指定できる.
font
フォントの指定. CSSの’font’プロパティと同様の形式で指定できる.
text
表示するテキスト.
textAlign
テキストの水平位置の指定. CSSの’text-align’プロパティと同様の形式で指定できる.
リファレンスにある通り、CSSのプロパティと同様の形式で指定ができるので、非常に分かり易い。有り難い。上記コードでも早速指定させてもらっている。
[html firstline=”163″ highlight=”164,168″ title=”main.js”]
var name = new Label("マザパク侍");
name.color = ‘#f8f8f8’;
name.x = this.x + 10;
name.y = this.y + 10;
name.width = 100;
name.textAlign = "center";
scene.addChild( name );
[/html]
ただし、注意が必要なのは、「line-height」に相当する数値は無視されるということだ。例えば、「Label.font = “normal normal 15px/1.2 monospace”;」としても、1.2は無視される。
Label.widthを超える文字列は改行されるのだが、「line-height」が設定できない為、改行時に”一行目の文字の下部”と”二行目の文字の上部”が重なってしまう。二行に表示する場合は、Labelを2つ用意しなければならないということだろう。非常に面倒だ。
■ステータスウィンドウ(状態表示枠)に任意の値を設定できるようにする
ステータスウィンドウ(状態表示枠)のクラスにsetterを用意して、それぞれに任意の値(状態)を設定できるようにしよう。まずはレベルを変えられるようにしてみる。以下のように変更してほしい。
[html firstline=”121″ highlight=”127,129,131,133″ title=”main.js”]
var scene = new Scene(); // シーンを作成.
var bg = new Sprite( SCREEN_WIDTH, SCREEN_HEIGHT ); // 背景画像を配置、幅と高さを設定.
bg.image = game.assets[ IMG_BG_SCENE_BATTLE ]; // 予め読込した背景画像を設定.
scene.addChild( bg ); // シーンに背景画像を追加.
var sw1 = new StatusWindow( scene, 0, 366 ); // ステータスウィンドウを作成.
sw1.setLV( 99 ); // レベルを設定.
var sw2 = new StatusWindow( scene, 120, 366 ); // ステータスウィンドウを作成.
sw2.setLV( 71 ); // レベルを設定.
var sw3 = new StatusWindow( scene, 240, 366 ); // ステータスウィンドウを作成.
sw3.setLV( 34 ); // レベルを設定.
var sw4 = new StatusWindow( scene, 360, 366 ); // ステータスウィンドウを作成.
sw4.setLV( 25 ); // レベルを設定.
// 作成したシーンを返却.
return scene;
[/html]
[html firstline=”188″ highlight=”191,198,199,200,201″]
sp.textAlign = "right";
scene.addChild( sp );
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 );
},
setLV: function( value ) {
lv.text = value.toString().toTwoByteAlphaNumeric(); // 半角英数字文字列を全角文字列に変換する.
}
});
// 半角英数字文字列を全角文字列に変換する関数.
String.prototype.toTwoByteAlphaNumeric = function() {
return this.replace( /[A-Za-z0-9]/g, function( s ) {
return String.fromCharCode( s.charCodeAt( 0 ) + 0xFEE0 );
});
}
[/html]
先程まで「var lv = new Label(“1”);」としてローカル定義してしまっていたので、「lv = new Label(“1”);」としてvarを取り除きグローバルに変更する。そうしないとsetterからはアクセスできない為、戦闘シーンが起動できなくなる。
また、setterの引数を「value」としているが、これを「lv」にしてしまうとローカル定義に置き換わってしまうので、注意が必要だ。
半角英数字文字列を全角文字列に変換しているのは、単に私が個人的な趣向で全角で文字列を表示したいだけなので、こういう方法があるんだね~へぇ~程度の参考にしてほしい。
実行結果は以下だ。ちゃんと個別にレベルが設定されている。
では、名前、HP、SPも、同様に実装しよう。
[html firstline=”120″ highlight=”127,128,129,133,134,135,139,140,141,145,146,147,182,183,184,185,186,187,188,190,198,213,214,215,216,217,218,219,220,221″ title=”main.js”]
function createScene() {
var scene = new Scene(); // シーンを作成.
var bg = new Sprite( SCREEN_WIDTH, SCREEN_HEIGHT ); // 背景画像を配置、幅と高さを設定.
bg.image = game.assets[ IMG_BG_SCENE_BATTLE ]; // 予め読込した背景画像を設定.
scene.addChild( bg ); // シーンに背景画像を追加.
var sw1 = new StatusWindow( scene, 0, 366 ); // ステータスウィンドウを作成.
sw1.setName( "アプフェル" ); // 名前を設定.
sw1.setHP( 9999 ); // HPを設定.
sw1.setSP( 999 ); // SPを設定.
sw1.setLV( 99 ); // レベルを設定.
var sw2 = new StatusWindow( scene, 120, 366 ); // ステータスウィンドウを作成.
sw2.setName( "レザン" ); // 名前を設定.
sw2.setHP( 1244 ); // HPを設定.
sw2.setSP( 678 ); // SPを設定.
sw2.setLV( 71 ); // レベルを設定.
var sw3 = new StatusWindow( scene, 240, 366 ); // ステータスウィンドウを作成.
sw3.setName( "ビスキュイ" ); // 名前を設定.
sw3.setHP( 21 ); // HPを設定.
sw3.setSP( 9990 ); // SPを設定.
sw3.setLV( 34 ); // レベルを設定.
var sw4 = new StatusWindow( scene, 360, 366 ); // ステータスウィンドウを作成.
sw4.setName( "ダマンド" ); // 名前を設定.
sw4.setHP( 337 ); // HPを設定.
sw4.setSP( 0 ); // SPを設定.
sw4.setLV( 25 ); // レベルを設定.
// 作成したシーンを返却.
return scene;
}
// ステータスウィンドウを作成するクラス.
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 ); // シーンにステータスウィンドウを追加.
var h = new Label("HP");
h.color = ‘#f8f8f8’;
h.x = this.x + 12;
h.y = this.y + 36;
scene.addChild( h );
var s = new Label("SP");
s.color = ‘#f8f8f8’;
s.x = this.x + 12;
s.y = this.y + 66;
scene.addChild( s );
var l = new Label("Lv");
l.color = ‘#f8f8f8’;
l.x = this.x + 12;
l.y = this.y + 96;
scene.addChild( l );
playerName = new Label("マザパク侍");
playerName.color = ‘#f8f8f8’;
playerName.x = this.x + 10;
playerName.y = this.y + 10;
playerName.width = 100;
playerName.textAlign = "center";
scene.addChild( playerName );
hp = new Label("234");
hp.color = ‘#f8f8f8’;
hp.x = this.x + 32;
hp.y = this.y + 36;
hp.width = 80;
hp.textAlign = "right";
scene.addChild( hp );
sp = new Label("9999");
sp.color = ‘#f8f8f8’;
sp.x = this.x + 32;
sp.y = this.y + 66;
sp.width = 80;
sp.textAlign = "right";
scene.addChild( sp );
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 );
},
setName: function( value ) {
playerName.text = value;
},
setHP: function( value ) {
hp.text = value.toString().toTwoByteAlphaNumeric(); // 半角英数字文字列を全角文字列に変換する.
},
setSP: function( value ) {
sp.text = value.toString().toTwoByteAlphaNumeric(); // 半角英数字文字列を全角文字列に変換する.
},
setLV: function( value ) {
lv.text = value.toString().toTwoByteAlphaNumeric(); // 半角英数字文字列を全角文字列に変換する.
}
});
[/html]
「name」はグローバルで使用されていたので、「playerName」に変更してからvarを外している。実行結果もちゃんと個別の情報が出るようになった。
■ステータス(HP/SP)ゲージを動かそう!
さてさて、今回の背景画像には、HP/SP用にゲージ枠を設けている。現在のHP/SP状態に応じて、可変なグラフィカルなゲージを表示したいと思う。そのやり方は、”ゲーム開発をenchant.js(HTML5 + JavaScript)で! 【RPG(ロールプレイングゲーム)篇】 戦闘シーンにステータスゲージ(HPゲージ)を表示する“の記事で!
■文字列にWEBフォントを使いたい
と、思っている。
このように。
≫ ゲーム開発をenchant.js(HTML5 + JavaScript)で! 【RPG(ロールプレイングゲーム)篇】 戦闘シーンにステータスゲージ(HPゲージ)を表示する
≫ ゲーム開発を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)
ピンバック: materialize.jp » ゲーム開発をenchant.js(HTML5 + JavaScript)で! 【RPG(ロールプレイングゲーム)篇】 戦闘シーンに切り替える
ピンバック: materialize.jp » ゲーム開発をenchant.js(HTML5 + JavaScript)で! 【RPG(ロールプレイングゲーム)篇】 戦闘シーンにステータスゲージ(HPゲージ)を表示する
ピンバック: materialize.jp » ゲーム開発をenchant.js(HTML5 + JavaScript)で! 【RPG(ロールプレイングゲーム)篇】 文字列に「8bitファミコン風のWEBフォント(漢字も使える!フリー!)」を採用する
ピンバック: materialize.jp » ゲーム開発をenchant.js(HTML5 + JavaScript)で! 【導入篇】 enchant.jsのダウンロードと開発準備
ピンバック: materialize.jp » ゲーム開発をenchant.js(HTML5 + JavaScript)で! 【RPG(ロールプレイングゲーム)篇】 戦闘シーンに戦闘用コマンド一覧(攻撃/特技/道具/防御/逃走)を表示する
ピンバック: materialize.jp » ゲーム開発をenchant.js(HTML5 + JavaScript)で! 【RPG(ロールプレイングゲーム)篇】 戦闘シーンにバーチャルボタン(Aボタン/Bボタン/Xボタン/Yボタン)を表示する
ピンバック: materialize.jp » WebViewで画面の右横にできる隙間を消す方法(スクロールバー表示領域を消す方法)
ピンバック: materialize.jp » Androidでアプリ開発をする為に、自分のパソコンが「32ビット版」か「64ビット版」かを確認しておく