メッセージ管理クラスの追加
<div id="message">(以後これをメッセージボックスと呼ぶことにする)には、現在の得点やゲームオーバーのメッセージなど表示しています。
しかし、メッセージボックスの変更は複数の場所で行っています。現在は数が少ないので大丈夫ですが、このまま、メッセージボックスを変更する場所があちこちに増えてくると、不具合の温床になりかねません。
そこでメッセージボックスを管理するクラスを追加し、表示処理を統一します。
/**
* <div id="message">を管理するクラス
*/
class MessageMng {
/**
* id="message"に対するDIV要素
*/
private _element: HTMLDivElement | undefined;
/**
* コンストラクタ
*/
constructor() {
document.addEventListener("DOMContentLoaded", () => {
let element = document.getElementById("message");
if (element instanceof HTMLDivElement) {
this._element = element;
}
});
}
/**
* テキストを変更する。
* @param text
*/
public ChangeText(text: string) {
if (this._element) {
this._element.innerText = text;
}
}
}
let Message = new MessageMng();
これまでメッセージボックスの変更は、ChangeMessage()で行っていましたが、Message.ChangeText()でも同様に変更できます。(単なる置き換えなので、コードは省略。)
しかし、このまま置き換えるだけでは表示処理の統一にはなりませんので、もう少しコードを整理します。
タイミングを合わせる
- 球を表示する:プレイヤーに球の場所を教えるため。
- ラケットを表示する:プレイヤーにラケットの場所を教えるため。
- メッセージボックスを表示する:プレイヤーにゲームの状況を教えるため。
このように考えると、メッセージボックスは球やラケットと同じように処理できるはずです。そうすることで、プログラムの流れが統一されます。
つまり、次のように球やラケットとメッセージボックスの処理のタイミングを合わせたコードにしたいと考えました。
function GameLoop(timestamp: number) {
// 変更のない部分は省略
if (frame > FrameCounter) {
// ゲームの状況を更新する。
UpdateGameSituation();
// メッセージボックスを更新する。
Message.Update();
// フレーム数が更新されたので、描画を行う。
DrawGameCanvas();
// メッセージボックスを表示する。
Message.Show();
}
}
メッセージボックスに表示する内容の整理
メッセージボックスには、スコアとゲームの状態を表示しています。そして、ゲーム状態(GameStatus)によって内容を切り替えています。
整理すると次のようになっていました。
GameStatus | 表示内容 |
---|---|
start | ボタンを押すとゲーム開始 |
game | スコア |
stop | ポーズ中であること ボタンを押すと再開 |
gameover | ゲームオーバーしたこと 最終スコア ボタンを押すと次のゲームを開始 |
したがって、Message.Update()はGameStatusによって表示内容を更新すればよいです。
MessageMngの実装例
最終的なMessageMngクラスのコードを以下に示します。
/**
* メッセージボックス(<div id="message">)を管理するクラス
*/
class MessageMng {
/**
* id="message"に対するDIV要素
*/
private _element: HTMLDivElement | undefined;
/**
* innerTextに表示するテキスト
*/
private _text = "";
/**
* コンストラクタ
*/
constructor() {
document.addEventListener("DOMContentLoaded", () => {
let element = document.getElementById("message");
if (element instanceof HTMLDivElement) {
this._element = element;
}
else{
console.log("id=\"message\"のdiv要素がありません。");
}
});
}
/**
* メッセージボックスを更新する。
*/
public Update() {
switch (GameStatus) {
case "start":
this._text = "ボタンを押すとゲームを開始します。";
break;
case "game":
this._text = "スコア:" + Score;
break;
case "stop":
this._text = "ゲームポーズ中\nボタンを押すと再開します。";
break;
case "gameover":
this._text = "ゲームオーバー\n" +
"あなたのスコアは" + Score + "でした。\n" +
"ボタンを押すと次のゲームを開始します。";
break;
}
}
/**
* メッセージボックスを表示する。
*/
public Show() {
if (this._element) {
this._element.innerText = this._text;
}
}
}
Message.ChangeText()は不要になったので、削除しました。
ChangeMessage()も削除し、それを使用していたコードも下に示すように、すっきりすることができました。
//変更前
document.addEventListener("DOMContentLoaded", () => {
let button1 = document.getElementById("button1");
if (button1) {
button1.addEventListener("click", () => {
switch (Game.Status) {
case "game":
Game.Status = "stop";
ChangeButton1Text("スタート");
ChangeMessage("ゲームポーズ中\nボタンを押すと再開します。");
break;
case "stop":
Game.Status = "game";
ChangeButton1Text("ストップ");
ChangeMessage("");
break;
case "start":
case "gameover":
Game.Status = "game";
InitGameSituation();
ChangeButton1Text("ストップ");
ChangeMessage("");
break;
}
})
}
});
// 変更後
document.addEventListener("DOMContentLoaded", () => {
let button1 = document.getElementById("button1");
if (button1) {
button1.addEventListener("click", () => {
switch (GameStatus) {
case "game":
GameStatus = "stop";
ChangeButton1Text("スタート");
break;
case "stop":
GameStatus = "game";
ChangeButton1Text("ストップ");
break;
case "start":
case "gameover":
GameStatus = "game";
InitGameSituation();
ChangeButton1Text("ストップ");
break;
}
})
}
});
ボタン1管理クラスの追加
ボタン1のテキストを変更する処理も目的はメッセージボックスと同じです。それならば同様にしたほうがよいでしょう。そこで、ボタン1の管理クラスを追加します。
/**
* ボタン1(<button id="button1">)を管理するクラス
*/
class Button1Mng {
/**
* id="message"に対するDIV要素
*/
private _element: HTMLButtonElement | undefined;
/**
* innerTextに表示するテキスト
*/
private _text = "";
/**
* コンストラクタ
*/
constructor() {
document.addEventListener("DOMContentLoaded", () => {
let element = document.getElementById("button1");
if (element instanceof HTMLButtonElement) {
this._element = element;
}
else {
console.log("id=\"button1\"のbutton要素がありません。");
}
});
}
/**
* メッセージボックスを更新する。
*/
public Update() {
switch (GameStatus) {
case "start":
this._text = "スタート";
break;
case "game":
this._text = "ストップ";
break;
case "stop":
this._text = "スタート";
break;
case "gameover":
this._text = "NEXTゲーム";
break;
}
}
/**
* メッセージボックスを表示する。
*/
public Show() {
if (this._element) {
this._element.innerText = this._text;
}
}
}
let Button1 = new Button1Mng();
そして、Button1.Update()とButton1.Show()をMessageのときと同じように実行います。また、既存コードのChangeButton1Text()を削除します。(変更は簡単なため、ソースの記載は省略する。)
コメント