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やアドベンチャーゲームでこのウインドウクラスを使う場合は、キーの管理をどうするかを少し考えないといけませんね。どの要素のフォーカス(イベント)でキー管理を行うか、今回は下キーに割り当てた操作キーをリターンキーやスペースキーなどどのキーに割り当てるか……。


創作プログラミングの街 > ゲーム開発室 > Webゲーム開発室