JavaScriptメッセージ表示ウインドウに、文字の逐次表示機能と複数ページ管理機能を追加してみましょう。設定されたメッセージ文字列を一文字ずつ順次表示する機能、長い文章を複数のページに分割して表示する機能です。
これで、RPGやアドベンチャーゲームで使うためのメッセージウインドウの基本機能はほぼ実現できたと思います。
今回は、複数のページに分割表示するために、表示する文字列を「ページ配列内の行配列」に格納することにします。メッセージ表示ウインドウクラスにページ配列pagesを用意し、文字列設定関数setText()で渡された文字列はこのpagesの各要素に「行配列」として格納するわけです。
たとえば、最初のページの一行目の文字列はpages[0][0]に格納されることになります。
今回は逐次表示やページ移動など状態の管理、更新を行う必要があるので、ウインドウクラス側の定時処理関数action()を用意しました。メッセージ表示クラスを使う際は、このaction()を呼び出すことで「現在の表示位置」を更新したり「キー入力に応じた処理」を行います。
現在の表示位置は、変数drawingPage(現在表示中のページ)/drawingLine(現在表示中の行)/drawingChar(現在表示中の文字位置)で管理します。drawingCharが行の文字数を超えたらdrawingLineを更新し、drawingLineがページ内の行数を超えたらdrawingPageを更新する、という感じですね。
JavaScriptの遅延実行機能setTimeout()などで一定時間ごとにaction()を呼び出せば、少しずつ文字列の文字が表示されていき、ページ全体が表示されたら次のページへ行く処理を行うことができます。
ただ、時には少しずつ表示されるのはうっとうしくなるので、特定のキー(今回は下キー)を押すとまとめてページ全体を表示するようにしました。また、ページ全体の表示が終わってまだ次のページがある場合は、三角形のマークを出して下キーが押されるのを待ち、下キーが押されたら次のページの表示へと移ります。
下キーの状態は、現在のキー状態(下キーが押されていたら1、押されていなければ0)をaction()の引数に渡すことでメッセージ表示クラスのオブジェクトに通知します。
「文字表示中」「次ページへの移動待機中」といった状態は、変数statusで管理しています。
実際の表示は、以下のような感じです(Canvas未対応ブラウザでは表示されません)。
今回は、「テキスト設定」ボタンのキーイベントで下キーの状態を管理しているので、テキスト設定ボタンをクリックしたらそのまま(他の場所をクリックしたりTabキーを押したりせず)下キーでページ移動やページ全体表示を試してみてください。
JavaScriptコードとHTMLは、以下のとおりです。
<div style="text-align: center;">
<canvas id="testCanvas" width="300" height="180" style="background: #0000cc;"></canvas><br>
<textarea id="testText" rows="6" style="width: 290px;"></textarea><br>
<button id="testButton" onClick="setText()" disabled onKeyDown="onKeyDown(event)" onKeyUp="onKeyUp(event)">テキスト設定</button>
</div>
<script type="text/javascript" src="canvas_meswinc.js">
</script>
<script type="text/javascript">
var testCanvas = document.getElementById('testCanvas');
var testContext;
var mesWin;
var key;
var timer;
var testText = document.getElementById('testText');
testText.value = 'テキスト1行目。<:br>setTextで渡す文字列の改行指定は、brタグで行います。連続改行テスト<:br><:br>文字表示中に下キー押下でページ全体を表示します。<:br>下キーで次ページ<:br>ページ送り<:br>フォントは環境依存なので、正常に表示されない文字もあるかもしれません。<:br><:br>文字列表示完了。下キーでウインドウを非表示にします。';
if (testCanvas.getContext) {
testContext = testCanvas.getContext('2d');
// テキスト設定ボタン有効化
document.getElementById("testButton").disabled = false;
}
function loop() {
// action()にキー状態を通知
mesWin.action(key);
// Canvas全体をクリア
testContext.fillStyle = '#0000cc';
testContext.fillRect(0, 0, 300, 180);
// メッセージ表示ウインドウの描画
mesWin.draw(testContext);
// ループ
timer = setTimeout("loop()", 60);
}
// テキスト設定ボタンクリック時
function setText() {
// 以前のループ処理を停止
clearTimeout(timer);
// ウインドウオブジェクト作成
mesWin = new MessageWindow();
mesWin.init();
// 表示領域設定
mesWin.setPosition(20, 20);
mesWin.setSize(260, 140);
// メッセージ表示ウインドウを可視化
mesWin.show();
// テキストエリアの文字列をメッセージとして設定
mesWin.setText(testText.value, testContext);
// ウインドウ再描画
mesWin.draw(testContext);
document.getElementById("testButton").focus();
// ループ開始
loop();
}
function onKeyDown(e) {
// 下キーが押されたらキー状態変数を1に
if (e.keyCode == 40) {
e.preventDefault();
key =1;
}
}
function onKeyUp(e) {
// 下キーが離されたらキー状態変数を0に
if (e.keyCode == 40) {
e.preventDefault();
key =0;
}
}
</script>
実際にJavaScriptで作成するRPGやアドベンチャーゲームでこのウインドウクラスを使う場合は、キーの管理をどうするかを少し考えないといけませんね。どの要素のフォーカス(イベント)でキー管理を行うか、今回は下キーに割り当てた操作キーをリターンキーやスペースキーなどどのキーに割り当てるか……。