これは、将来のゲーム開発に使用する予定のステート マシンです。
このようなものを使用すると、さまざまな状態の描画と、コールバックでの状態の変更を実装できるはずです。div を表示/非表示にするか、別のバッファー/グラフィックをキャンバスに描画します。
状態を作成するには:
// initially hide the divs using css or js
state.add("welcome",
function () {
document.getElementById("Welcome").style.display = "block";
},
function () {
document.getElementById("Welcome").style.display = "none";
}
);
state.add("level01",
function () {
document.getElementById("Game").style.display = "block";
},
function () {
document.getElementById("Game").style.display = "none";
}
);
state.add("end",
function () {
document.getElementById("GameOver").style.display = "block";
}
);
2 番目の関数はオプションです (実際にはどちらもオプションですが、そのような状態では何も起こりません)。
状態を切り替えるには ("welcome"、"level01"、"end" の 3 つの状態を追加したと仮定します):
state.enter("welcome");
//... at some point welcome changes state using following:
state.enter("level01");
//... at the end of level1:
state.enter("end");
コード:
var state = (function () {
"use strict";
var currentState = -1,
stateNames = [],
stateCallbacks = [];
return {
current: function () {
if (currentState >= 0) {
return stateNames[currentState];
}
},
add: function (name, onEnter, onExit) {
var index = stateNames.indexOf(name);
if (index !== -1) {
throw "State " + name + " already exist!";
}
stateCallbacks.push({
enterState: onEnter || false,
exitState: onExit || false
});
stateNames.push(name);
},
remove: function (name) {
var index = stateNames.indexOf(name);
if (index === -1) {
throw "State " + name + " not found!";
}
stateNames.splice(index, 1);
stateCallbacks.splice(index, 1);
},
enter: function (name) {
var index = stateNames.indexOf(name);
if (index === -1) {
throw "State " + name + " not found!";
}
if (stateCallbacks[currentState].exitState) {
stateCallbacks[currentState].exitState();
}
currentState = index;
if (stateCallbacks[index].enterState) {
stateCallbacks[index].enterState();
}
},
exit: function () {
if (currentState === -1) {
throw "Not currently in any state";
}
if (stateCallbacks[currentState].exitState) {
stateCallbacks[currentState].exitState();
}
currentState = -1;
}
};
}());
追加コメント:
コードを匿名関数でラップした構造は、http: //www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html の JavaScript のモジュール パターンです。これは、他の言語の名前空間に似ています。
ルックアップ (ここでは Array.indexOf(name) として実装) のパフォーマンスを向上させるために、特に多数の状態 (つまり、100 以上のレベルを持つゲーム、または状態がより集中的に切り替わる別の使用例)。ただし、これをベンチマークしていないため、非常に推測的です。理論的には、配列検索はハッシュテーブル検索よりも n - 1 倍遅くなります (どのオブジェクトが実装されている可能性がありますか)。
編集:
- コードのバグを修正しました。state.add は、既存の名前をチェックするようになりました。
- 免責事項を追加しました。
- コールバックから div を表示/非表示にする方法の例を追加しました。
- 免責事項を削除し、コードを改良版に置き換えました。