var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Array.prototype.findIndex = function (predicate) {
function findIndex(array, predicate) {
for (var i = 0, len = array.length; i < len; i++) {
if (predicate.call(arguments[2], array[i], i, array)) {
return i;
}
}
return -1;
}
return findIndex(this, predicate);
};
Array.prototype.any = function (predicate) {
function any(array, predicate) {
return array.findIndex(predicate) > -1;
}
return any(this, predicate);
};
Array.prototype.firstOrDefault = function (predicate) {
function firstOrDefault(array, predicate) {
var index = array.findIndex(predicate);
return index == -1 ? null : array[index];
}
return firstOrDefault(this, predicate);
};
Array.prototype.find = function (predicate) {
function find(array, predicate) {
return array.firstOrDefault(predicate);
}
return find(this, predicate);
};
Array.prototype.where = function (predicate) {
function where(array, predicate) {
if (typeof (array.reduce) === "function") {
return array.reduce(function (ret, element, index) {
if (predicate.call(arguments[2], element, index, array)) {
ret.push(element);
}
return ret;
}, []);
}
else {
var ret = [];
for (var i = 0, len = array.length; i < len; i++) {
var element = array[i];
if (predicate.call(arguments[2], element, i, array)) {
ret.push(element);
}
}
return ret;
}
}
return where(this, predicate);
};
Array.prototype.count = function (predicate) {
function count(array, predicate) {
return array.where(predicate).length;
}
return count(this, predicate);
};
Array.prototype.findAll = function (predicate) {
function findAll(array, predicate) {
return array.where(predicate);
}
return findAll(this, predicate);
};
Array.prototype.contains = function (value) {
function contains(array, value) {
for (var i = 0, len = array.length; i < len; i++) {
if (array[i] == value) {
return true;
}
}
return false;
}
return contains(this, value);
};
Array.prototype.removeAll = function (predicate) {
function removeAll(array, predicate) {
var index;
do {
index = array.findIndex(predicate);
if (index >= 0) {
array.splice(index, 1);
}
} while (index >= 0);
}
removeAll(this, predicate);
};
Array.prototype.remove = function (element) {
function remove(array, element) {
var index = array.findIndex(function (x) {
return x === element;
});
if (index >= 0) {
array.splice(index, 1);
return true;
}
else {
return false;
}
}
return remove(this, element);
};
Array.prototype.removeAt = function (index) {
function removeAt(array, index) {
array.splice(index, 1);
}
return removeAt(this, index);
};
Array.prototype.removeRange = function (index, count) {
function removeRange(array, index, count) {
array.splice(index, count);
}
return removeRange(this, index, count);
};
Array.prototype.select = function (selector) {
function select(array, selector) {
if (typeof (array.reduce) === "function") {
return array.reduce(function (ret, element, index) {
ret.push(selector.call(arguments[2], element, index, array));
return ret;
}, []);
}
else {
var ret = [];
for (var i = 0, len = array.length; i < len; i++) {
ret.push(selector.call(arguments[2], array[i], i, array));
}
return ret;
}
}
return select(this, selector);
};
Array.prototype.orderBy = function (keySelector, comparer) {
function orderBy(array, keySelector, comparer) {
array.sort(function (x, y) {
var v1 = keySelector(x);
var v2 = keySelector(y);
if (comparer) {
return comparer(v1, v2);
}
else {
return (v1 > v2) ? 1 : -1;
}
});
return array;
}
return orderBy(this, keySelector, comparer);
};
Array.prototype.orderByDescending = function (keySelector, comparer) {
function orderByDescending(array, keySelector, comparer) {
array.sort(function (x, y) {
var v1 = keySelector(x);
var v2 = keySelector(y);
if (comparer) {
return -comparer(v1, v2);
}
else {
return (v1 < v2) ? 1 : -1;
}
});
return array;
}
return orderByDescending(this, keySelector, comparer);
};
Array.prototype.groupBy = function (keySelector) {
function groupBy(array, keySelector) {
if (typeof (array.reduce) === "function") {
var keys_1 = [];
return array.reduce(function (groups, element, index) {
var key = JSON.stringify(keySelector.call(arguments[1], element, index, array));
var index2 = keys_1.findIndex(function (x) {
return x === key;
});
if (index2 < 0) {
index2 = keys_1.push(key) - 1;
}
if (!groups[index2]) {
groups[index2] = [];
}
groups[index2].push(element);
return groups;
}, []);
}
else {
var groups = [];
var keys = [];
var _loop_1 = function (i, len) {
var key = JSON.stringify(keySelector.call(arguments_1[1], array[i], i, array));
var index = keys.findIndex(function (x) {
return x === key;
});
if (index < 0) {
index = keys.push(key) - 1;
}
if (!groups[index]) {
groups[index] = [];
}
groups[index].push(array[i]);
};
var arguments_1 = arguments;
for (var i = 0, len = array.length; i < len; i++) {
_loop_1(i, len);
}
return groups;
}
}
return groupBy(this, keySelector);
};
Array.prototype.sum = function (selector) {
function sum(array, selector) {
var ret;
for (var i = 0, len = array.length; i < len; i++) {
if (i == 0) {
if (selector) {
ret = selector.call(arguments[2], array[i], i, array);
}
else {
ret = array[i];
}
}
else {
if (selector) {
ret += selector.call(arguments[2], array[i], i, array);
}
else {
ret += array[i];
}
}
}
return ret;
}
return sum(this, selector);
};
var es;
(function (es) {
/**
* 执行顺序
* - onAddedToEntity
* - OnEnabled
*
* 删除执行顺序
* - onRemovedFromEntity
*/
var Component = /** @class */ (function () {
function Component() {
/**
* 更新该组件的时间间隔。这与实体的更新间隔无关。
*/
this.updateInterval = 1;
this._enabled = true;
this._updateOrder = 0;
}
Object.defineProperty(Component.prototype, "transform", {
/**
* 快速访问 this.entity.transform
*/
get: function () {
return this.entity.transform;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Component.prototype, "enabled", {
/**
* 如果组件和实体都已启用,则为。当启用该组件时,将调用该组件的生命周期方法。状态的改变会导致调用onEnabled/onDisable。
*/
get: function () {
return this.entity ? this.entity.enabled && this._enabled : this._enabled;
},
/**
* 如果组件和实体都已启用,则为。当启用该组件时,将调用该组件的生命周期方法。状态的改变会导致调用onEnabled/onDisable。
* @param value
*/
set: function (value) {
this.setEnabled(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Component.prototype, "updateOrder", {
/** 更新此实体上组件的顺序 */
get: function () {
return this._updateOrder;
},
/** 更新此实体上组件的顺序 */
set: function (value) {
this.setUpdateOrder(value);
},
enumerable: true,
configurable: true
});
/**
* 当此组件已分配其实体,但尚未添加到实体的活动组件列表时调用。有用的东西,如物理组件,需要访问转换来修改碰撞体的属性。
*/
Component.prototype.initialize = function () {
};
/**
* 在提交所有挂起的组件更改后,将该组件添加到场景时调用。此时,设置了实体字段和实体。场景也设定好了。
*/
Component.prototype.onAddedToEntity = function () {
};
/**
* 当此组件从其实体中移除时调用。在这里做所有的清理工作。
*/
Component.prototype.onRemovedFromEntity = function () {
};
/**
* 当实体的位置改变时调用。这允许组件知道它们由于父实体的移动而移动了。
* @param comp
*/
Component.prototype.onEntityTransformChanged = function (comp) {
};
/**
*当父实体或此组件启用时调用
*/
Component.prototype.onEnabled = function () {
};
/**
* 禁用父实体或此组件时调用
*/
Component.prototype.onDisabled = function () {
};
Component.prototype.setEnabled = function (isEnabled) {
if (this._enabled != isEnabled) {
this._enabled = isEnabled;
if (this._enabled) {
this.onEnabled();
}
else {
this.onDisabled();
}
}
return this;
};
Component.prototype.setUpdateOrder = function (updateOrder) {
if (this._updateOrder != updateOrder) {
this._updateOrder = updateOrder;
}
return this;
};
return Component;
}());
es.Component = Component;
})(es || (es = {}));
var es;
(function (es) {
/**
* 全局核心类
*/
var Core = /** @class */ (function () {
function Core(width, height, enableEntitySystems) {
if (enableEntitySystems === void 0) { enableEntitySystems = true; }
/**
* 全局访问系统
*/
this._globalManagers = [];
this._timerManager = new es.TimerManager();
this._frameCounterElapsedTime = 0;
this._frameCounter = 0;
this.width = width;
this.height = height;
Core._instance = this;
Core.emitter = new es.Emitter();
Core.emitter.addObserver(es.CoreEvents.FrameUpdated, this.update, this);
Core.registerGlobalManager(this._timerManager);
Core.entitySystemsEnabled = enableEntitySystems;
this.initialize();
}
Object.defineProperty(Core, "Instance", {
/**
* 提供对单例/游戏实例的访问
* @constructor
*/
get: function () {
return this._instance;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Core, "scene", {
/**
* 当前活动的场景。注意,如果设置了该设置,在更新结束之前场景实际上不会改变
*/
get: function () {
if (!this._instance)
return null;
return this._instance._scene;
},
/**
* 当前活动的场景。注意,如果设置了该设置,在更新结束之前场景实际上不会改变
* @param value
*/
set: function (value) {
if (!value) {
console.error("场景不能为空");
return;
}
if (this._instance._scene == null) {
this._instance._scene = value;
this._instance._scene.begin();
Core.Instance.onSceneChanged();
}
else {
this._instance._nextScene = value;
}
},
enumerable: true,
configurable: true
});
/**
* 临时运行SceneTransition,允许一个场景过渡到另一个平滑的自定义效果。
* @param sceneTransition
*/
Core.startSceneTransition = function (sceneTransition) {
if (this._instance._sceneTransition) {
console.warn("在前一个场景完成之前,不能开始一个新的场景转换。");
return;
}
this._instance._sceneTransition = sceneTransition;
return sceneTransition;
};
/**
* 添加一个全局管理器对象,它的更新方法将调用场景前的每一帧。
* @param manager
*/
Core.registerGlobalManager = function (manager) {
this._instance._globalManagers.push(manager);
manager.enabled = true;
};
/**
* 删除全局管理器对象
* @param manager
*/
Core.unregisterGlobalManager = function (manager) {
this._instance._globalManagers.remove(manager);
manager.enabled = false;
};
/**
* 获取类型为T的全局管理器
* @param type
*/
Core.getGlobalManager = function (type) {
for (var i = 0; i < this._instance._globalManagers.length; i++) {
if (this._instance._globalManagers[i] instanceof type)
return this._instance._globalManagers[i];
}
return null;
};
/**
* 调度一个一次性或重复的计时器,该计时器将调用已传递的动作
* @param timeInSeconds
* @param repeats
* @param context
* @param onTime
*/
Core.schedule = function (timeInSeconds, repeats, context, onTime) {
if (repeats === void 0) { repeats = false; }
if (context === void 0) { context = null; }
return this._instance._timerManager.schedule(timeInSeconds, repeats, context, onTime);
};
Core.prototype.onOrientationChanged = function () {
Core.emitter.emit(es.CoreEvents.OrientationChanged);
};
Core.prototype.draw = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!(this._sceneTransition != null)) return [3 /*break*/, 5];
this._sceneTransition.preRender();
if (!(this._sceneTransition != null)) return [3 /*break*/, 4];
if (!(this._scene != null && !this._sceneTransition.hasPreviousSceneRender)) return [3 /*break*/, 2];
this._scene.render();
this._scene.postRender();
return [4 /*yield*/, this._sceneTransition.onBeginTransition()];
case 1:
_a.sent();
return [3 /*break*/, 3];
case 2:
if (this._scene != null && this._sceneTransition.isNewSceneLoaded) {
this._scene.render();
this._scene.postRender();
}
_a.label = 3;
case 3:
this._sceneTransition.render();
_a.label = 4;
case 4: return [3 /*break*/, 6];
case 5:
if (this._scene) {
this._scene.render();
// 如如果我们没有一个活动的SceneTransition,就像往常一样渲染
this._scene.postRender();
}
_a.label = 6;
case 6: return [2 /*return*/];
}
});
});
};
/**
* 在一个场景结束后,下一个场景开始之前调用
*/
Core.prototype.onSceneChanged = function () {
Core.emitter.emit(es.CoreEvents.SceneChanged);
es.Time.sceneChanged();
};
/**
* 当屏幕大小发生改变时调用
*/
Core.prototype.onGraphicsDeviceReset = function () {
// 我们用这些来避免垃圾事件的发生
if (this._graphicsDeviceChangeTimer != null) {
this._graphicsDeviceChangeTimer.reset();
}
else {
this._graphicsDeviceChangeTimer = Core.schedule(0.05, false, this, function (t) {
t.context._graphicsDeviceChangeTimer = null;
Core.emitter.emit(es.CoreEvents.GraphicsDeviceReset);
});
}
};
Core.prototype.initialize = function () {
};
Core.prototype.update = function (currentTime) {
return __awaiter(this, void 0, void 0, function () {
var i;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (currentTime != null)
es.Time.update(currentTime);
if (this._scene != null) {
for (i = this._globalManagers.length - 1; i >= 0; i--) {
if (this._globalManagers[i].enabled)
this._globalManagers[i].update();
}
// 仔细阅读:
// 当场景转换发生时,我们不更新场景
// - 除非是不改变场景的SceneTransition(没有理由不更新)
// - 或者是一个已经切换到新场景的SceneTransition(新场景需要做它的事情)
if (!this._sceneTransition ||
(this._sceneTransition &&
(!this._sceneTransition.loadsNewScene || this._sceneTransition.isNewSceneLoaded))) {
this._scene.update();
}
if (this._nextScene != null) {
this._scene.end();
this._scene = this._nextScene;
this._nextScene = null;
this.onSceneChanged();
this._scene.begin();
}
}
return [4 /*yield*/, this.draw()];
case 1:
_a.sent();
return [2 /*return*/];
}
});
});
};
/**
* 启用/禁用焦点丢失时的暂停。如果为真,则不调用更新或渲染方法
*/
Core.pauseOnFocusLost = true;
/**
* 是否启用调试渲染
*/
Core.debugRenderEndabled = false;
return Core;
}());
es.Core = Core;
})(es || (es = {}));
var es;
(function (es) {
var CoreEvents;
(function (CoreEvents) {
/**
* 在图形设备重置时触发。当这种情况发生时,任何渲染目标或其他内容的VRAM将被擦除,需要重新生成
*/
CoreEvents[CoreEvents["GraphicsDeviceReset"] = 0] = "GraphicsDeviceReset";
/**
* 当场景发生变化时触发
*/
CoreEvents[CoreEvents["SceneChanged"] = 1] = "SceneChanged";
/**
* 当设备方向改变时触发
*/
CoreEvents[CoreEvents["OrientationChanged"] = 2] = "OrientationChanged";
/**
* 当每帧事件触发时
*/
CoreEvents[CoreEvents["FrameUpdated"] = 3] = "FrameUpdated";
})(CoreEvents = es.CoreEvents || (es.CoreEvents = {}));
})(es || (es = {}));
var es;
(function (es) {
var Entity = /** @class */ (function () {
function Entity(name) {
/**
* 指定应该调用这个entity update方法的频率。1表示每一帧,2表示每一帧,以此类推
*/
this.updateInterval = 1;
this._tag = 0;
this._enabled = true;
this._updateOrder = 0;
this.components = new es.ComponentList(this);
this.transform = new es.Transform(this);
this.name = name;
this.id = Entity._idGenerator++;
if (es.Core.entitySystemsEnabled)
this.componentBits = new es.BitSet();
}
Object.defineProperty(Entity.prototype, "isDestroyed", {
/**
* 如果调用了destroy,那么在下一次处理实体之前这将一直为true
*/
get: function () {
return this._isDestroyed;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Entity.prototype, "tag", {
/**
* 你可以随意使用。稍后可以使用它来查询场景中具有特定标记的所有实体
*/
get: function () {
return this._tag;
},
/**
* 你可以随意使用。稍后可以使用它来查询场景中具有特定标记的所有实体
* @param value
*/
set: function (value) {
this.setTag(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Entity.prototype, "enabled", {
/**
* 启用/禁用实体。当禁用碰撞器从物理系统和组件中移除时,方法将不会被调用
*/
get: function () {
return this._enabled;
},
/**
* 启用/禁用实体。当禁用碰撞器从物理系统和组件中移除时,方法将不会被调用
* @param value
*/
set: function (value) {
this.setEnabled(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Entity.prototype, "updateOrder", {
/**
* 更新此实体的顺序。updateOrder还用于对scene.entities上的标签列表进行排序
*/
get: function () {
return this._updateOrder;
},
/**
* 更新此实体的顺序。updateOrder还用于对scene.entities上的标签列表进行排序
* @param value
*/
set: function (value) {
this.setUpdateOrder(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Entity.prototype, "parent", {
get: function () {
return this.transform.parent;
},
set: function (value) {
this.transform.setParent(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Entity.prototype, "childCount", {
get: function () {
return this.transform.childCount;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Entity.prototype, "position", {
get: function () {
return this.transform.position;
},
set: function (value) {
this.transform.setPosition(value.x, value.y);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Entity.prototype, "localPosition", {
get: function () {
return this.transform.localPosition;
},
set: function (value) {
this.transform.setLocalPosition(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Entity.prototype, "rotation", {
get: function () {
return this.transform.rotation;
},
set: function (value) {
this.transform.setRotation(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Entity.prototype, "rotationDegrees", {
get: function () {
return this.transform.rotationDegrees;
},
set: function (value) {
this.transform.setRotationDegrees(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Entity.prototype, "localRotation", {
get: function () {
return this.transform.localRotation;
},
set: function (value) {
this.transform.setLocalRotation(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Entity.prototype, "localRotationDegrees", {
get: function () {
return this.transform.localRotationDegrees;
},
set: function (value) {
this.transform.setLocalRotationDegrees(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Entity.prototype, "scale", {
get: function () {
return this.transform.scale;
},
set: function (value) {
this.transform.setScale(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Entity.prototype, "localScale", {
get: function () {
return this.transform.localScale;
},
set: function (value) {
this.transform.setLocalScale(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Entity.prototype, "worldInverseTransform", {
get: function () {
return this.transform.worldInverseTransform;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Entity.prototype, "localToWorldTransform", {
get: function () {
return this.transform.localToWorldTransform;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Entity.prototype, "worldToLocalTransform", {
get: function () {
return this.transform.worldToLocalTransform;
},
enumerable: true,
configurable: true
});
Entity.prototype.onTransformChanged = function (comp) {
// 通知我们的子项改变了位置
this.components.onEntityTransformChanged(comp);
};
/**
* 设置实体的标记
* @param tag
*/
Entity.prototype.setTag = function (tag) {
if (this._tag != tag) {
// 我们只有在已经有场景的情况下才会调用entityTagList。如果我们还没有场景,我们会被添加到entityTagList
if (this.scene)
this.scene.entities.removeFromTagList(this);
this._tag = tag;
if (this.scene)
this.scene.entities.addToTagList(this);
}
return this;
};
/**
* 设置实体的启用状态。当禁用碰撞器从物理系统和组件中移除时,方法将不会被调用
* @param isEnabled
*/
Entity.prototype.setEnabled = function (isEnabled) {
if (this._enabled != isEnabled) {
this._enabled = isEnabled;
if (this._enabled)
this.components.onEntityEnabled();
else
this.components.onEntityDisabled();
}
return this;
};
/**
* 设置此实体的更新顺序。updateOrder还用于对scene.entities上的标签列表进行排序
* @param updateOrder
*/
Entity.prototype.setUpdateOrder = function (updateOrder) {
if (this._updateOrder != updateOrder) {
this._updateOrder = updateOrder;
if (this.scene) {
this.scene.entities.markEntityListUnsorted();
this.scene.entities.markTagUnsorted(this.tag);
}
return this;
}
};
/**
* 从场景中删除实体并销毁所有子元素
*/
Entity.prototype.destroy = function () {
this._isDestroyed = true;
this.scene.entities.remove(this);
this.transform.parent = null;
// 销毁所有子项
for (var i = this.transform.childCount - 1; i >= 0; i--) {
var child = this.transform.getChild(i);
child.entity.destroy();
}
};
/**
* 将实体从场景中分离。下面的生命周期方法将被调用在组件上:OnRemovedFromEntity
*/
Entity.prototype.detachFromScene = function () {
this.scene.entities.remove(this);
this.components.deregisterAllComponents();
for (var i = 0; i < this.transform.childCount; i++)
this.transform.getChild(i).entity.detachFromScene();
};
/**
* 将一个先前分离的实体附加到一个新的场景
* @param newScene
*/
Entity.prototype.attachToScene = function (newScene) {
this.scene = newScene;
newScene.entities.add(this);
this.components.registerAllComponents();
for (var i = 0; i < this.transform.childCount; i++) {
this.transform.getChild(i).entity.attachToScene(newScene);
}
};
/**
* 在提交了所有挂起的实体更改后,将此实体添加到场景时调用
*/
Entity.prototype.onAddedToScene = function () {
};
/**
* 当此实体从场景中删除时调用
*/
Entity.prototype.onRemovedFromScene = function () {
// 如果已经被销毁了,移走我们的组件。如果我们只是分离,我们需要保持我们的组件在实体上。
if (this._isDestroyed)
this.components.removeAllComponents();
};
/**
* 每帧进行调用进行更新组件
*/
Entity.prototype.update = function () {
this.components.update();
};
/**
* 将组件添加到组件列表中。返回组件。
* @param component
*/
Entity.prototype.addComponent = function (component) {
component.entity = this;
this.components.add(component);
component.initialize();
return component;
};
/**
* 获取类型T的第一个组件并返回它。如果没有找到组件,则返回null。
* @param type
*/
Entity.prototype.getComponent = function (type) {
return this.components.getComponent(type, false);
};
/**
* 检查实体是否具有该组件
* @param type
*/
Entity.prototype.hasComponent = function (type) {
return this.components.getComponent(type, false) != null;
};
/**
* 获取类型T的第一个组件并返回它。如果没有找到组件,将创建组件。
* @param type
*/
Entity.prototype.getOrCreateComponent = function (type) {
var comp = this.components.getComponent(es.TypeUtils.getType(type), true);
if (!comp) {
comp = this.addComponent(type);
}
return comp;
};
/**
* 获取typeName类型的所有组件,但不使用列表分配
* @param typeName
* @param componentList
*/
Entity.prototype.getComponents = function (typeName, componentList) {
return this.components.getComponents(typeName, componentList);
};
/**
* 从组件列表中删除组件
* @param component
*/
Entity.prototype.removeComponent = function (component) {
this.components.remove(component);
};
/**
* 从组件列表中删除类型为T的第一个组件
* @param type
*/
Entity.prototype.removeComponentForType = function (type) {
var comp = this.getComponent(type);
if (comp) {
this.removeComponent(comp);
return true;
}
return false;
};
/**
* 从实体中删除所有组件
*/
Entity.prototype.removeAllComponents = function () {
for (var i = 0; i < this.components.count; i++) {
this.removeComponent(this.components.buffer[i]);
}
};
Entity.prototype.compareTo = function (other) {
var compare = this._updateOrder - other._updateOrder;
if (compare == 0)
compare = this.id - other.id;
return compare;
};
Entity.prototype.toString = function () {
return "[Entity: name: " + this.name + ", tag: " + this.tag + ", enabled: " + this.enabled + ", depth: " + this.updateOrder + "]";
};
Entity._idGenerator = 0;
return Entity;
}());
es.Entity = Entity;
})(es || (es = {}));
var es;
(function (es) {
/** 场景 */
var Scene = /** @class */ (function () {
function Scene() {
this._sceneComponents = [];
this._renderers = [];
this.entities = new es.EntityList(this);
this.renderableComponents = new es.RenderableComponentList();
if (es.Core.entitySystemsEnabled)
this.entityProcessors = new es.EntityProcessorList();
this.initialize();
}
/**
* 在场景子类中重写这个,然后在这里进行加载。
* 在场景设置好之后,但在调用begin之前,从contructor中调用这个函数
*/
Scene.prototype.initialize = function () {
};
/**
* 当Core将这个场景设置为活动场景时,这个将被调用
*/
Scene.prototype.onStart = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2 /*return*/];
});
});
};
/**
* 在场景子类中重写这个,并在这里做任何必要的卸载。
* 当Core把这个场景从活动槽中移除时,这个被调用。
*/
Scene.prototype.unload = function () {
};
Scene.prototype.begin = function () {
es.Physics.reset();
this.updateResolutionScaler();
if (this.entityProcessors != null)
this.entityProcessors.begin();
es.Core.emitter.addObserver(es.CoreEvents.GraphicsDeviceReset, this.updateResolutionScaler, this);
es.Core.emitter.addObserver(es.CoreEvents.OrientationChanged, this.updateResolutionScaler, this);
this._didSceneBegin = true;
this.onStart();
};
Scene.prototype.end = function () {
this._didSceneBegin = false;
for (var i = 0; i < this._renderers.length; i++) {
this._renderers[i].unload();
}
es.Core.emitter.removeObserver(es.CoreEvents.GraphicsDeviceReset, this.updateResolutionScaler);
es.Core.emitter.removeObserver(es.CoreEvents.OrientationChanged, this.updateResolutionScaler);
this.entities.removeAllEntities();
for (var i = 0; i < this._sceneComponents.length; i++) {
this._sceneComponents[i].onRemovedFromScene();
}
this._sceneComponents.length = 0;
es.Physics.clear();
if (this.entityProcessors)
this.entityProcessors.end();
this.unload();
};
Scene.prototype.updateResolutionScaler = function () {
};
Scene.prototype.update = function () {
// 更新我们的列表,以防它们有任何变化
this.entities.updateLists();
for (var i = this._sceneComponents.length - 1; i >= 0; i--) {
if (this._sceneComponents[i].enabled)
this._sceneComponents[i].update();
}
// 更新我们的实体解析器
if (this.entityProcessors != null)
this.entityProcessors.update();
// 更新我们的实体组
this.entities.update();
if (this.entityProcessors != null)
this.entityProcessors.lateUpdate();
// 我们在entity.update之后更新我们的renderables,以防止任何新的Renderables被添加
this.renderableComponents.updateList();
};
Scene.prototype.render = function () {
for (var i = 0; i < this._renderers.length; i++) {
this._renderers[i].render(this);
}
};
/**
* 现在的任何后处理器都要完成它的处理
* 只有在SceneTransition请求渲染时,它才会有一个值。
*/
Scene.prototype.postRender = function () {
};
/**
* 向组件列表添加并返回SceneComponent
* @param component
*/
Scene.prototype.addSceneComponent = function (component) {
component.scene = this;
component.onEnabled();
this._sceneComponents.push(component);
this._sceneComponents.sort(component.compareTo);
return component;
};
/**
* 获取类型为T的第一个SceneComponent并返回它。如果没有找到组件,则返回null。
* @param type
*/
Scene.prototype.getSceneComponent = function (type) {
for (var i = 0; i < this._sceneComponents.length; i++) {
var component = this._sceneComponents[i];
if (component instanceof type)
return component;
}
return null;
};
/**
* 获取类型为T的第一个SceneComponent并返回它。如果没有找到SceneComponent,则将创建SceneComponent。
* @param type
*/
Scene.prototype.getOrCreateSceneComponent = function (type) {
var comp = this.getSceneComponent(type);
if (comp == null)
comp = this.addSceneComponent(new type());
return comp;
};
/**
* 从SceneComponents列表中删除一个SceneComponent
* @param component
*/
Scene.prototype.removeSceneComponent = function (component) {
if (!this._sceneComponents.contains(component)) {
console.warn("SceneComponent" + component + "\u4E0D\u5728SceneComponents\u5217\u8868\u4E2D!");
return;
}
this._sceneComponents.remove(component);
component.onRemovedFromScene();
};
/**
* 为场景添加一个渲染器
* @param renderer
*/
Scene.prototype.addRenderer = function (renderer) {
this._renderers.push(renderer);
this._renderers.sort();
renderer.onAddedToScene(this);
return renderer;
};
/**
* 获取类型为T的第一个渲染器
* @param type
*/
Scene.prototype.getRenderer = function (type) {
for (var i = 0; i < this._renderers.length; i++) {
if (this._renderers[i] instanceof type)
return this._renderers[i];
}
return null;
};
/**
* 从场景中移除渲染器
* @param renderer
*/
Scene.prototype.removeRenderer = function (renderer) {
if (!this._renderers.contains(renderer))
return;
this._renderers.remove(renderer);
renderer.unload();
};
/**
* 将实体添加到此场景,并返回它
* @param name
*/
Scene.prototype.createEntity = function (name) {
var entity = new es.Entity(name);
return this.addEntity(entity);
};
/**
* 在场景的实体列表中添加一个实体
* @param entity
*/
Scene.prototype.addEntity = function (entity) {
if (this.entities.buffer.contains(entity))
console.warn("\u60A8\u8BD5\u56FE\u5C06\u540C\u4E00\u5B9E\u4F53\u6DFB\u52A0\u5230\u573A\u666F\u4E24\u6B21: " + entity);
this.entities.add(entity);
entity.scene = this;
for (var i = 0; i < entity.transform.childCount; i++)
this.addEntity(entity.transform.getChild(i).entity);
return entity;
};
/**
* 从场景中删除所有实体
*/
Scene.prototype.destroyAllEntities = function () {
for (var i = 0; i < this.entities.count; i++) {
this.entities.buffer[i].destroy();
}
};
/**
* 搜索并返回第一个具有名称的实体
* @param name
*/
Scene.prototype.findEntity = function (name) {
return this.entities.findEntity(name);
};
/**
* 返回具有给定标记的所有实体
* @param tag
*/
Scene.prototype.findEntitiesWithTag = function (tag) {
return this.entities.entitiesWithTag(tag);
};
/**
* 返回类型为T的所有实体
* @param type
*/
Scene.prototype.entitiesOfType = function (type) {
return this.entities.entitiesOfType(type);
};
/**
* 返回第一个启用加载的类型为T的组件
* @param type
*/
Scene.prototype.findComponentOfType = function (type) {
return this.entities.findComponentOfType(type);
};
/**
* 返回类型为T的所有已启用已加载组件的列表
* @param type
*/
Scene.prototype.findComponentsOfType = function (type) {
return this.entities.findComponentsOfType(type);
};
/**
* 在场景中添加一个EntitySystem处理器
* @param processor 处理器
*/
Scene.prototype.addEntityProcessor = function (processor) {
processor.scene = this;
this.entityProcessors.add(processor);
return processor;
};
/**
* 从场景中删除EntitySystem处理器
* @param processor
*/
Scene.prototype.removeEntityProcessor = function (processor) {
this.entityProcessors.remove(processor);
};
/**
* 获取EntitySystem处理器
*/
Scene.prototype.getEntityProcessor = function () {
return this.entityProcessors.getProcessor();
};
return Scene;
}());
es.Scene = Scene;
})(es || (es = {}));
var transform;
(function (transform) {
var Component;
(function (Component) {
Component[Component["position"] = 0] = "position";
Component[Component["scale"] = 1] = "scale";
Component[Component["rotation"] = 2] = "rotation";
})(Component = transform.Component || (transform.Component = {}));
})(transform || (transform = {}));
var es;
(function (es) {
var DirtyType;
(function (DirtyType) {
DirtyType[DirtyType["clean"] = 0] = "clean";
DirtyType[DirtyType["positionDirty"] = 1] = "positionDirty";
DirtyType[DirtyType["scaleDirty"] = 2] = "scaleDirty";
DirtyType[DirtyType["rotationDirty"] = 3] = "rotationDirty";
})(DirtyType = es.DirtyType || (es.DirtyType = {}));
var Transform = /** @class */ (function () {
function Transform(entity) {
/**
* 值会根据位置、旋转和比例自动重新计算
*/
this._localTransform = es.Matrix2D.identity;
/**
* 值将自动从本地和父矩阵重新计算。
*/
this._worldTransform = es.Matrix2D.identity;
this._rotationMatrix = es.Matrix2D.identity;
this._translationMatrix = es.Matrix2D.identity;
this._scaleMatrix = es.Matrix2D.identity;
this._worldToLocalTransform = es.Matrix2D.identity;
this._worldInverseTransform = es.Matrix2D.identity;
this._position = es.Vector2.zero;
this._scale = es.Vector2.one;
this._rotation = 0;
this._localPosition = es.Vector2.zero;
this._localScale = es.Vector2.one;
this._localRotation = 0;
this.entity = entity;
this.scale = this._localScale = es.Vector2.one;
this._children = [];
}
Object.defineProperty(Transform.prototype, "childCount", {
/**
* 这个转换的所有子元素
*/
get: function () {
return this._children.length;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Transform.prototype, "rotationDegrees", {
/**
* 变换在世界空间的旋转度
*/
get: function () {
return es.MathHelper.toDegrees(this._rotation);
},
/**
* 变换在世界空间的旋转度
* @param value
*/
set: function (value) {
this.setRotation(es.MathHelper.toRadians(value));
},
enumerable: true,
configurable: true
});
Object.defineProperty(Transform.prototype, "localRotationDegrees", {
/**
* 旋转相对于父变换旋转的角度
*/
get: function () {
return es.MathHelper.toDegrees(this._localRotation);
},
/**
* 旋转相对于父变换旋转的角度
* @param value
*/
set: function (value) {
this.localRotation = es.MathHelper.toRadians(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Transform.prototype, "localToWorldTransform", {
get: function () {
this.updateTransform();
return this._worldTransform;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Transform.prototype, "parent", {
/**
* 获取此转换的父转换
*/
get: function () {
return this._parent;
},
/**
* 设置此转换的父转换
* @param value
*/
set: function (value) {
this.setParent(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Transform.prototype, "worldToLocalTransform", {
get: function () {
if (this._worldToLocalDirty) {
if (!this.parent) {
this._worldToLocalTransform = es.Matrix2D.identity;
}
else {
this.parent.updateTransform();
this._worldToLocalTransform = es.Matrix2D.invert(this.parent._worldTransform);
}
this._worldToLocalDirty = false;
}
return this._worldToLocalTransform;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Transform.prototype, "worldInverseTransform", {
get: function () {
this.updateTransform();
if (this._worldInverseDirty) {
this._worldInverseTransform = es.Matrix2D.invert(this._worldTransform);
this._worldInverseDirty = false;
}
return this._worldInverseTransform;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Transform.prototype, "position", {
/**
* 变换在世界空间中的位置
*/
get: function () {
this.updateTransform();
if (this._positionDirty) {
if (!this.parent) {
this._position = this._localPosition;
}
else {
this.parent.updateTransform();
es.Vector2Ext.transformR(this._localPosition, this.parent._worldTransform, this._position);
}
this._positionDirty = false;
}
return this._position;
},
/**
* 变换在世界空间中的位置
* @param value
*/
set: function (value) {
this.setPosition(value.x, value.y);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Transform.prototype, "scale", {
/**
* 变换在世界空间的缩放
*/
get: function () {
this.updateTransform();
return this._scale;
},
/**
* 变换在世界空间的缩放
* @param value
*/
set: function (value) {
this.setScale(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Transform.prototype, "rotation", {
/**
* 在世界空间中以弧度旋转的变换
*/
get: function () {
this.updateTransform();
return this._rotation;
},
/**
* 变换在世界空间的旋转度
* @param value
*/
set: function (value) {
this.setRotation(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Transform.prototype, "localPosition", {
/**
* 转换相对于父转换的位置。如果转换没有父元素,则与transform.position相同
*/
get: function () {
this.updateTransform();
return this._localPosition;
},
/**
* 转换相对于父转换的位置。如果转换没有父元素,则与transform.position相同
* @param value
*/
set: function (value) {
this.setLocalPosition(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Transform.prototype, "localScale", {
/**
* 转换相对于父元素的比例。如果转换没有父元素,则与transform.scale相同
*/
get: function () {
this.updateTransform();
return this._localScale;
},
/**
* 转换相对于父元素的比例。如果转换没有父元素,则与transform.scale相同
* @param value
*/
set: function (value) {
this.setLocalScale(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Transform.prototype, "localRotation", {
/**
* 相对于父变换的旋转,变换的旋转。如果转换没有父元素,则与transform.rotation相同
*/
get: function () {
this.updateTransform();
return this._localRotation;
},
/**
* 相对于父变换的旋转,变换的旋转。如果转换没有父元素,则与transform.rotation相同
* @param value
*/
set: function (value) {
this.setLocalRotation(value);
},
enumerable: true,
configurable: true
});
/**
* 返回在索引处的转换子元素
* @param index
*/
Transform.prototype.getChild = function (index) {
return this._children[index];
};
/**
* 设置此转换的父转换
* @param parent
*/
Transform.prototype.setParent = function (parent) {
if (this._parent == parent)
return this;
if (!this._parent) {
this._parent._children.remove(this);
this._parent._children.push(this);
}
this._parent = parent;
this.setDirty(DirtyType.positionDirty);
return this;
};
/**
* 设置转换在世界空间中的位置
* @param x
* @param y
*/
Transform.prototype.setPosition = function (x, y) {
var position = new es.Vector2(x, y);
if (position.equals(this._position))
return this;
this._position = position;
if (this.parent) {
this.localPosition = es.Vector2.transform(this._position, this._worldToLocalTransform);
}
else {
this.localPosition = position;
}
this._positionDirty = false;
return this;
};
/**
* 设置转换相对于父转换的位置。如果转换没有父元素,则与transform.position相同
* @param localPosition
*/
Transform.prototype.setLocalPosition = function (localPosition) {
if (localPosition.equals(this._localPosition))
return this;
this._localPosition = localPosition;
this._localDirty = this._positionDirty = this._localPositionDirty = this._localRotationDirty = this._localScaleDirty = true;
this.setDirty(DirtyType.positionDirty);
return this;
};
/**
* 设置变换在世界空间的旋转度
* @param radians
*/
Transform.prototype.setRotation = function (radians) {
this._rotation = radians;
if (this.parent) {
this.localRotation = this.parent.rotation + radians;
}
else {
this.localRotation = radians;
}
return this;
};
/**
* 设置变换在世界空间的旋转度
* @param degrees
*/
Transform.prototype.setRotationDegrees = function (degrees) {
return this.setRotation(es.MathHelper.toRadians(degrees));
};
/**
* 旋转精灵的顶部,使其朝向位置
* @param pos
*/
Transform.prototype.lookAt = function (pos) {
var sign = this.position.x > pos.x ? -1 : 1;
var vectorToAlignTo = es.Vector2.normalize(es.Vector2.subtract(this.position, pos));
this.rotation = sign * Math.acos(es.Vector2.dot(vectorToAlignTo, es.Vector2.unitY));
};
/**
* 相对于父变换的旋转设置变换的旋转。如果转换没有父元素,则与transform.rotation相同
* @param radians
*/
Transform.prototype.setLocalRotation = function (radians) {
this._localRotation = radians;
this._localDirty = this._positionDirty = this._localPositionDirty = this._localRotationDirty = this._localScaleDirty = true;
this.setDirty(DirtyType.rotationDirty);
return this;
};
/**
* 相对于父变换的旋转设置变换的旋转。如果转换没有父元素,则与transform.rotation相同
* @param degrees
*/
Transform.prototype.setLocalRotationDegrees = function (degrees) {
return this.setLocalRotation(es.MathHelper.toRadians(degrees));
};
/**
* 设置变换在世界空间中的缩放
* @param scale
*/
Transform.prototype.setScale = function (scale) {
this._scale = scale;
if (this.parent) {
this.localScale = es.Vector2.divide(scale, this.parent._scale);
}
else {
this.localScale = scale;
}
return this;
};
/**
* 设置转换相对于父对象的比例。如果转换没有父元素,则与transform.scale相同
* @param scale
*/
Transform.prototype.setLocalScale = function (scale) {
this._localScale = scale;
this._localDirty = this._positionDirty = this._localScaleDirty = true;
this.setDirty(DirtyType.scaleDirty);
return this;
};
/**
* 对精灵坐标进行四舍五入
*/
Transform.prototype.roundPosition = function () {
this.position = this._position.round();
};
Transform.prototype.updateTransform = function () {
if (this.hierarchyDirty != DirtyType.clean) {
if (this.parent)
this.parent.updateTransform();
if (this._localDirty) {
if (this._localPositionDirty) {
this._translationMatrix = es.Matrix2D.createTranslation(this._localPosition.x, this._localPosition.y);
this._localPositionDirty = false;
}
if (this._localRotationDirty) {
this._rotationMatrix = es.Matrix2D.createRotation(this._localRotation);
this._localRotationDirty = false;
}
if (this._localScaleDirty) {
this._scaleMatrix = es.Matrix2D.createScale(this._localScale.x, this._localScale.y);
this._localScaleDirty = false;
}
this._localTransform = this._scaleMatrix.multiply(this._rotationMatrix);
this._localTransform = this._localTransform.multiply(this._translationMatrix);
if (!this.parent) {
this._worldTransform = this._localTransform;
this._rotation = this._localRotation;
this._scale = this._localScale;
this._worldInverseDirty = true;
}
this._localDirty = false;
}
if (this.parent) {
this._worldTransform = this._localTransform.multiply(this.parent._worldTransform);
this._rotation = this._localRotation + this.parent._rotation;
this._scale = es.Vector2.multiply(this.parent._scale, this._localScale);
this._worldInverseDirty = true;
}
this._worldToLocalDirty = true;
this._positionDirty = true;
this.hierarchyDirty = DirtyType.clean;
}
};
Transform.prototype.setDirty = function (dirtyFlagType) {
if ((this.hierarchyDirty & dirtyFlagType) == 0) {
this.hierarchyDirty |= dirtyFlagType;
switch (dirtyFlagType) {
case es.DirtyType.positionDirty:
this.entity.onTransformChanged(transform.Component.position);
break;
case es.DirtyType.rotationDirty:
this.entity.onTransformChanged(transform.Component.rotation);
break;
case es.DirtyType.scaleDirty:
this.entity.onTransformChanged(transform.Component.scale);
break;
}
if (!this._children)
this._children = [];
// 告诉子项发生了变换
for (var i = 0; i < this._children.length; i++)
this._children[i].setDirty(dirtyFlagType);
}
};
/**
* 从另一个transform属性进行拷贝
* @param transform
*/
Transform.prototype.copyFrom = function (transform) {
this._position = transform.position;
this._localPosition = transform._localPosition;
this._rotation = transform._rotation;
this._localRotation = transform._localRotation;
this._scale = transform._scale;
this._localScale = transform._localScale;
this.setDirty(DirtyType.positionDirty);
this.setDirty(DirtyType.rotationDirty);
this.setDirty(DirtyType.scaleDirty);
};
Transform.prototype.toString = function () {
return "[Transform: parent: " + this.parent + ", position: " + this.position + ", rotation: " + this.rotation + ",\n scale: " + this.scale + ", localPosition: " + this._localPosition + ", localRotation: " + this._localRotation + ",\n localScale: " + this._localScale + "]";
};
return Transform;
}());
es.Transform = Transform;
})(es || (es = {}));
var es;
(function (es) {
var ComponentPool = /** @class */ (function () {
function ComponentPool(typeClass) {
this._type = typeClass;
this._cache = [];
}
ComponentPool.prototype.obtain = function () {
try {
return this._cache.length > 0 ? this._cache.shift() : new this._type();
}
catch (err) {
throw new Error(this._type + err);
}
};
ComponentPool.prototype.free = function (component) {
component.reset();
this._cache.push(component);
};
return ComponentPool;
}());
es.ComponentPool = ComponentPool;
})(es || (es = {}));
var es;
(function (es) {
/**
* 用于比较组件更新排序
*/
var IUpdatableComparer = /** @class */ (function () {
function IUpdatableComparer() {
}
IUpdatableComparer.prototype.compare = function (a, b) {
return a.updateOrder - b.updateOrder;
};
return IUpdatableComparer;
}());
es.IUpdatableComparer = IUpdatableComparer;
es.isIUpdatable = function (props) { return typeof props['update'] !== 'undefined'; };
})(es || (es = {}));
var es;
(function (es) {
/** 回收实例的组件类型。 */
var PooledComponent = /** @class */ (function (_super) {
__extends(PooledComponent, _super);
function PooledComponent() {
return _super !== null && _super.apply(this, arguments) || this;
}
return PooledComponent;
}(es.Component));
es.PooledComponent = PooledComponent;
})(es || (es = {}));
var es;
(function (es) {
var SceneComponent = /** @class */ (function () {
function SceneComponent() {
/**
* 更新此场景中SceneComponents的顺序
*/
this.updateOrder = 0;
this._enabled = true;
}
Object.defineProperty(SceneComponent.prototype, "enabled", {
/**
* 如果启用了SceneComponent,则为true。状态的改变会导致调用onEnabled/onDisable。
*/
get: function () {
return this._enabled;
},
/**
* 如果启用了SceneComponent,则为true。状态的改变会导致调用onEnabled/onDisable。
* @param value
*/
set: function (value) {
this.setEnabled(value);
},
enumerable: true,
configurable: true
});
/**
* 在启用此SceneComponent时调用
*/
SceneComponent.prototype.onEnabled = function () {
};
/**
* 当禁用此SceneComponent时调用
*/
SceneComponent.prototype.onDisabled = function () {
};
/**
* 当该SceneComponent从场景中移除时调用
*/
SceneComponent.prototype.onRemovedFromScene = function () {
};
/**
* 在实体更新之前每一帧调用
*/
SceneComponent.prototype.update = function () {
};
/**
* 启用/禁用这个SceneComponent
* @param isEnabled
*/
SceneComponent.prototype.setEnabled = function (isEnabled) {
if (this._enabled != isEnabled) {
this._enabled = isEnabled;
if (this._enabled) {
}
else {
}
}
return this;
};
/**
* 设置SceneComponent的updateOrder并触发某种SceneComponent
* @param updateOrder
*/
SceneComponent.prototype.setUpdateOrder = function (updateOrder) {
if (this.updateOrder != updateOrder) {
this.updateOrder = updateOrder;
es.Core.scene._sceneComponents.sort(this.compareTo);
}
return this;
};
SceneComponent.prototype.compareTo = function (other) {
return this.updateOrder - other.updateOrder;
};
return SceneComponent;
}());
es.SceneComponent = SceneComponent;
})(es || (es = {}));
var es;
(function (es) {
var TriggerListenerHelper = /** @class */ (function () {
function TriggerListenerHelper() {
}
TriggerListenerHelper.getITriggerListener = function (entity, components) {
for (var i = 0; i < entity.components._components.length; i++) {
var component = entity.components._components.buffer[i];
if (es.isITriggerListener(component)) {
components.push(component);
}
}
for (var i = 0; i < entity.components._componentsToAdd.length; i++) {
var component = entity.components._componentsToAdd[i];
if (es.isITriggerListener(component)) {
components.push(component);
}
}
return components;
};
return TriggerListenerHelper;
}());
es.TriggerListenerHelper = TriggerListenerHelper;
es.isITriggerListener = function (props) { return typeof props['onTriggerEnter'] !== 'undefined'; };
})(es || (es = {}));
var es;
(function (es) {
/**
* 辅助类说明了一种处理移动的方法,它考虑了包括触发器在内的所有冲突。
* ITriggerListener接口用于管理对移动过程中违反的任何触发器的回调。
* 一个物体只能通过移动器移动。要正确报告触发器的move方法。
*
* 请注意,多个移动者相互交互将多次调用ITriggerListener。
*/
var Mover = /** @class */ (function (_super) {
__extends(Mover, _super);
function Mover() {
return _super !== null && _super.apply(this, arguments) || this;
}
Mover.prototype.onAddedToEntity = function () {
this._triggerHelper = new es.ColliderTriggerHelper(this.entity);
};
/**
* 计算修改运动矢量的运动,以考虑移动时可能发生的碰撞
* @param motion
* @param collisionResult
*/
Mover.prototype.calculateMovement = function (motion, collisionResult) {
if (!this.entity.getComponent(es.Collider) || !this._triggerHelper) {
return false;
}
// 移动所有的非触发碰撞器并获得最近的碰撞
var colliders = this.entity.getComponents(es.Collider);
for (var i = 0; i < colliders.length; i++) {
var collider = colliders[i];
// 不检测触发器 在我们移动后会重新访问它
if (collider.isTrigger)
continue;
// 获取我们在新位置可能发生碰撞的任何东西
var bounds = collider.bounds;
bounds.x += motion.x;
bounds.y += motion.y;
var neighbors = es.Physics.boxcastBroadphaseExcludingSelf(collider, bounds, collider.collidesWithLayers.value);
for (var j = 0; j < neighbors.size; j++) {
var neighbor = neighbors[j];
// 不检测触发器
if (neighbor.isTrigger)
continue;
var _internalcollisionResult = new es.CollisionResult();
if (collider.collidesWith(neighbor, motion, _internalcollisionResult)) {
// 如果碰撞 则退回之前的移动量
motion = motion.subtract(_internalcollisionResult.minimumTranslationVector);
// 如果我们碰到多个对象,为了简单起见,只取第一个。
if (_internalcollisionResult.collider != null) {
collisionResult = _internalcollisionResult;
}
}
}
}
es.ListPool.free(colliders);
return collisionResult.collider != null;
};
/**
* 将calculatemomovement应用到实体并更新triggerHelper
* @param motion
*/
Mover.prototype.applyMovement = function (motion) {
// 移动实体到它的新位置,如果我们有一个碰撞,否则移动全部数量。当碰撞发生时,运动被更新
this.entity.position = es.Vector2.add(this.entity.position, motion);
// 对所有是触发器的碰撞器与所有宽相位碰撞器进行重叠检查。任何重叠都会导致触发事件。
if (this._triggerHelper)
this._triggerHelper.update();
};
/**
* 通过调用calculateMovement和applyMovement来移动考虑碰撞的实体;
* @param motion
* @param collisionResult
*/
Mover.prototype.move = function (motion, collisionResult) {
this.calculateMovement(motion, collisionResult);
this.applyMovement(motion);
return collisionResult.collider != null;
};
return Mover;
}(es.Component));
es.Mover = Mover;
})(es || (es = {}));
var es;
(function (es) {
/**
* 只向itriggerlistener报告冲突的移动器
* 该对象将始终移动完整的距离
*/
var ProjectileMover = /** @class */ (function (_super) {
__extends(ProjectileMover, _super);
function ProjectileMover() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this._tempTriggerList = [];
return _this;
}
ProjectileMover.prototype.onAddedToEntity = function () {
this._collider = this.entity.getComponent(es.Collider);
if (!this._collider)
console.warn("ProjectileMover has no Collider. ProjectilMover requires a Collider!");
};
/**
* 移动考虑碰撞的实体
* @param motion
*/
ProjectileMover.prototype.move = function (motion) {
if (!this._collider)
return false;
var didCollide = false;
// 获取我们在新位置可能发生碰撞的任何东西
this.entity.position.add(motion);
// 获取任何可能在新位置发生碰撞的东西
var neighbors = es.Physics.boxcastBroadphase(this._collider.bounds, this._collider.collidesWithLayers.value);
for (var i = 0; i < neighbors.size; i++) {
var neighbor = neighbors[i];
if (this._collider.overlaps(neighbor) && neighbor.enabled) {
didCollide = true;
this.notifyTriggerListeners(this._collider, neighbor);
}
}
return didCollide;
};
ProjectileMover.prototype.notifyTriggerListeners = function (self, other) {
// 通知我们重叠的碰撞器实体上的任何侦听器
es.TriggerListenerHelper.getITriggerListener(other.entity, this._tempTriggerList);
for (var i = 0; i < this._tempTriggerList.length; i++) {
this._tempTriggerList[i].onTriggerEnter(self, other);
}
this._tempTriggerList.length = 0;
// 通知此实体上的任何侦听器
es.TriggerListenerHelper.getITriggerListener(this.entity, this._tempTriggerList);
for (var i = 0; i < this._tempTriggerList.length; i++) {
this._tempTriggerList[i].onTriggerEnter(other, self);
}
this._tempTriggerList.length = 0;
};
return ProjectileMover;
}(es.Component));
es.ProjectileMover = ProjectileMover;
})(es || (es = {}));
var es;
(function (es) {
var Collider = /** @class */ (function (_super) {
__extends(Collider, _super);
function Collider() {
var _this = _super !== null && _super.apply(this, arguments) || this;
/**
* 在处理冲突时,physicsLayer可以用作过滤器。Flags类有帮助位掩码的方法
*/
_this.physicsLayer = new es.Ref(1 << 0);
/**
* 碰撞器在使用移动器移动时应该碰撞的层
* 默认为所有层
*/
_this.collidesWithLayers = new es.Ref(es.Physics.allLayers);
/**
* 如果为true,碰撞器将根据附加的变换缩放和旋转
*/
_this.shouldColliderScaleAndRotateWithTransform = true;
/**
* 这个对撞机在物理系统注册时的边界。
* 存储这个允许我们始终能够安全地从物理系统中移除对撞机,即使它在试图移除它之前已经被移动了。
*/
_this.registeredPhysicsBounds = new es.Rectangle();
_this._isPositionDirty = true;
_this._isRotationDirty = true;
_this._localOffset = es.Vector2.zero;
return _this;
}
Object.defineProperty(Collider.prototype, "absolutePosition", {
/**
* 镖师碰撞器的绝对位置
*/
get: function () {
return es.Vector2.add(this.entity.transform.position, this._localOffset);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Collider.prototype, "rotation", {
/**
* 封装变换。如果碰撞器没和实体一起旋转 则返回transform.rotation
*/
get: function () {
if (this.shouldColliderScaleAndRotateWithTransform && this.entity)
return this.entity.transform.rotation;
return 0;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Collider.prototype, "bounds", {
get: function () {
if (this._isPositionDirty || this._isRotationDirty) {
this.shape.recalculateBounds(this);
this._isPositionDirty = this._isRotationDirty = false;
}
return this.shape.bounds;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Collider.prototype, "localOffset", {
/**
* 将localOffset添加到实体。获取碰撞器几何图形的最终位置。
* 允许向一个实体添加多个碰撞器并分别定位,还允许你设置缩放/旋转
*/
get: function () {
return this._localOffset;
},
/**
* 将localOffset添加到实体。获取碰撞器几何图形的最终位置。
* 允许向一个实体添加多个碰撞器并分别定位,还允许你设置缩放/旋转
* @param value
*/
set: function (value) {
this.setLocalOffset(value);
},
enumerable: true,
configurable: true
});
/**
* 将localOffset添加到实体。获取碰撞器的最终位置。
* 这允许您向一个实体添加多个碰撞器并分别定位它们。
* @param offset
*/
Collider.prototype.setLocalOffset = function (offset) {
if (this._localOffset != offset) {
this.unregisterColliderWithPhysicsSystem();
this._localOffset = offset;
this._localOffsetLength = this._localOffset.length();
this._isPositionDirty = true;
this.registerColliderWithPhysicsSystem();
}
return this;
};
/**
* 如果为true,碰撞器将根据附加的变换缩放和旋转
* @param shouldColliderScaleAndRotationWithTransform
*/
Collider.prototype.setShouldColliderScaleAndRotateWithTransform = function (shouldColliderScaleAndRotationWithTransform) {
this.shouldColliderScaleAndRotateWithTransform = shouldColliderScaleAndRotationWithTransform;
this._isPositionDirty = this._isRotationDirty = true;
return this;
};
Collider.prototype.onAddedToEntity = function () {
this._isParentEntityAddedToScene = true;
this.registerColliderWithPhysicsSystem();
};
Collider.prototype.onRemovedFromEntity = function () {
this.unregisterColliderWithPhysicsSystem();
this._isParentEntityAddedToScene = false;
};
Collider.prototype.onEntityTransformChanged = function (comp) {
switch (comp) {
case transform.Component.position:
this._isPositionDirty = true;
break;
case transform.Component.scale:
this._isPositionDirty = true;
break;
case transform.Component.rotation:
this._isRotationDirty = true;
break;
}
if (this._isColliderRegistered)
es.Physics.updateCollider(this);
};
Collider.prototype.onEnabled = function () {
this.registerColliderWithPhysicsSystem();
this._isPositionDirty = this._isRotationDirty = true;
};
Collider.prototype.onDisabled = function () {
this.unregisterColliderWithPhysicsSystem();
};
/**
* 父实体会在不同的时间调用它(当添加到场景,启用,等等)
*/
Collider.prototype.registerColliderWithPhysicsSystem = function () {
// 如果在将我们添加到实体之前更改了origin等属性,则实体可以为null
if (this._isParentEntityAddedToScene && !this._isColliderRegistered) {
es.Physics.addCollider(this);
this._isColliderRegistered = true;
}
};
/**
* 父实体会在不同的时候调用它(从场景中移除,禁用,等等)
*/
Collider.prototype.unregisterColliderWithPhysicsSystem = function () {
if (this._isParentEntityAddedToScene && this._isColliderRegistered) {
es.Physics.removeCollider(this);
}
this._isColliderRegistered = false;
};
/**
* 检查这个形状是否与物理系统中的其他对撞机重叠
* @param other
*/
Collider.prototype.overlaps = function (other) {
return this.shape.overlaps(other.shape);
};
/**
* 检查这个与运动应用的碰撞器(移动向量)是否与碰撞器碰撞。如果是这样,将返回true,并且结果将填充碰撞数据。
* @param collider
* @param motion
* @param result
*/
Collider.prototype.collidesWith = function (collider, motion, result) {
// 改变形状的位置,使它在移动后的位置,这样我们可以检查重叠
var oldPosition = this.entity.position;
this.entity.position.add(motion);
var didCollide = this.shape.collidesWithShape(collider.shape, result);
if (didCollide)
result.collider = collider;
// 将图形位置返回到检查前的位置
this.entity.position = oldPosition;
return didCollide;
};
return Collider;
}(es.Component));
es.Collider = Collider;
})(es || (es = {}));
///
*
* trace( StringFormat.zfill('1') );
* // 01
*
* trace( StringFormat.zfill('16', 5) );
* // 00016
*
* trace( StringFormat.zfill('-3', 3) );
* // -03
*
*
*
* @param str 要进行处理的字符串
* @param width 处理后字符串的长度,
* 如果str.length >= width,将不做任何处理直接返回原始的str。
* @return
*
*/
StringUtils.zfill = function (str, width) {
if (width === void 0) { width = 2; }
if (!str) {
return str;
}
width = Math.floor(width);
var slen = str.length;
if (slen >= width) {
return str;
}
var negative = false;
if (str.substr(0, 1) == '-') {
negative = true;
str = str.substr(1);
}
var len = width - slen;
for (var i = 0; i < len; i++) {
str = '0' + str;
}
if (negative) {
str = '-' + str;
}
return str;
};
/**
* 翻转字符串
* @param str 字符串
* @return 翻转后的字符串
*/
StringUtils.reverse = function (str) {
if (str.length > 1)
return this.reverse(str.substring(1)) + str.substring(0, 1);
else
return str;
};
/**
* 截断某段字符串
* @param str 目标字符串
* @param start 需要截断的起始索引
* @param len 截断长度
* @param order 顺序,true从字符串头部开始计算,false从字符串尾巴开始结算。
* @return 截断后的字符串
*/
StringUtils.cutOff = function (str, start, len, order) {
if (order === void 0) { order = true; }
start = Math.floor(start);
len = Math.floor(len);
var length = str.length;
if (start > length)
start = length;
var s = start;
var e = start + len;
var newStr;
if (order) {
newStr = str.substring(0, s) + str.substr(e, length);
}
else {
s = length - 1 - start - len;
e = s + len;
newStr = str.substring(0, s + 1) + str.substr(e + 1, length);
}
return newStr;
};
/**{0} 字符替换 */
StringUtils.strReplace = function (str, rStr) {
var i = 0, len = rStr.length;
for (; i < len; i++) {
if (rStr[i] == null || rStr[i] == "") {
rStr[i] = "无";
}
str = str.replace("{" + i + "}", rStr[i]);
}
return str;
};
/**
* 特殊符号字符串
*/
StringUtils.specialSigns = [
'&', '&',
'<', '<',
'>', '>',
'"', '"',
"'", ''',
'®', '®',
'©', '©',
'™', '™',
];
return StringUtils;
}());
var es;
(function (es) {
/** 提供帧定时信息 */
var Time = /** @class */ (function () {
function Time() {
}
Time.update = function (currentTime) {
var dt = (currentTime - this._lastTime) / 1000;
this.totalTime += dt;
this.deltaTime = dt * this.timeScale;
this.unscaledDeltaTime = dt;
this.timeSinceSceneLoad += dt;
this.frameCount++;
this._lastTime = currentTime;
};
Time.sceneChanged = function () {
this.timeSinceSceneLoad = 0;
};
/**
* 允许在间隔检查。只应该使用高于delta的间隔值,否则它将始终返回true。
* @param interval
*/
Time.checkEvery = function (interval) {
// 我们减去了delta,因为timeSinceSceneLoad已经包含了这个update ticks delta
return this.timeSinceSceneLoad / interval > (this.timeSinceSceneLoad - this.deltaTime) / interval;
};
/** 前一帧到当前帧的时间增量,按时间刻度进行缩放 */
Time.deltaTime = 0;
/** 时间刻度缩放 */
Time.timeScale = 1;
/** 已传递的帧总数 */
Time.frameCount = 0;
Time._lastTime = 0;
return Time;
}());
es.Time = Time;
})(es || (es = {}));
var TimeUtils = /** @class */ (function () {
function TimeUtils() {
}
/**
* 计算月份ID
* @param d 指定计算日期
* @returns 月ID
*/
TimeUtils.monthId = function (d) {
if (d === void 0) { d = null; }
d = d ? d : new Date();
var y = d.getFullYear();
var m = d.getMonth() + 1;
var g = m < 10 ? "0" : "";
return parseInt(y + g + m);
};
/**
* 计算日期ID
* @param d 指定计算日期
* @returns 日期ID
*/
TimeUtils.dateId = function (t) {
if (t === void 0) { t = null; }
t = t ? t : new Date();
var m = t.getMonth() + 1;
var a = m < 10 ? "0" : "";
var d = t.getDate();
var b = d < 10 ? "0" : "";
return parseInt(t.getFullYear() + a + m + b + d);
};
/**
* 计算周ID
* @param d 指定计算日期
* @returns 周ID
*/
TimeUtils.weekId = function (d, first) {
if (d === void 0) { d = null; }
if (first === void 0) { first = true; }
d = d ? d : new Date();
var c = new Date();
c.setTime(d.getTime());
c.setDate(1);
c.setMonth(0); //当年第一天
var year = c.getFullYear();
var firstDay = c.getDay();
if (firstDay == 0) {
firstDay = 7;
}
var max = false;
if (firstDay <= 4) {
max = firstDay > 1;
c.setDate(c.getDate() - (firstDay - 1));
}
else {
c.setDate(c.getDate() + 7 - firstDay + 1);
}
var num = this.diffDay(d, c, false);
if (num < 0) {
c.setDate(1);
c.setMonth(0); //当年第一天
c.setDate(c.getDate() - 1);
return this.weekId(c, false);
}
var week = num / 7;
var weekIdx = Math.floor(week) + 1;
if (weekIdx == 53) {
c.setTime(d.getTime());
c.setDate(c.getDate() - 1);
var endDay = c.getDay();
if (endDay == 0) {
endDay = 7;
}
if (first && (!max || endDay < 4)) {
c.setFullYear(c.getFullYear() + 1);
c.setDate(1);
c.setMonth(0); //当年第一天
return this.weekId(c, false);
}
}
var g = weekIdx > 9 ? "" : "0";
var s = year + "00" + g + weekIdx; //加上00防止和月份ID冲突
return parseInt(s);
};
/**
* 计算俩日期时间差,如果a比b小,返回负数
*/
TimeUtils.diffDay = function (a, b, fixOne) {
if (fixOne === void 0) { fixOne = false; }
var x = (a.getTime() - b.getTime()) / 86400000;
return fixOne ? Math.ceil(x) : Math.floor(x);
};
/**
* 获取本周一 凌晨时间
*/
TimeUtils.getFirstDayOfWeek = function (d) {
d = d ? d : new Date();
var day = d.getDay() || 7;
return new Date(d.getFullYear(), d.getMonth(), d.getDate() + 1 - day, 0, 0, 0, 0);
};
/**
* 获取当日凌晨时间
*/
TimeUtils.getFirstOfDay = function (d) {
d = d ? d : new Date();
d.setHours(0, 0, 0, 0);
return d;
};
/**
* 获取次日凌晨时间
*/
TimeUtils.getNextFirstOfDay = function (d) {
return new Date(this.getFirstOfDay(d).getTime() + 86400000);
};
/**
* @returns 2018-12-12
*/
TimeUtils.formatDate = function (date) {
var y = date.getFullYear();
var m = date.getMonth() + 1;
m = m < 10 ? '0' + m : m;
var d = date.getDate();
d = d < 10 ? ('0' + d) : d;
return y + '-' + m + '-' + d;
};
/**
* @returns 2018-12-12 12:12:12
*/
TimeUtils.formatDateTime = function (date) {
var y = date.getFullYear();
var m = date.getMonth() + 1;
m = m < 10 ? ('0' + m) : m;
var d = date.getDate();
d = d < 10 ? ('0' + d) : d;
var h = date.getHours();
var i = date.getMinutes();
i = i < 10 ? ('0' + i) : i;
var s = date.getSeconds();
s = s < 10 ? ('0' + s) : s;
return y + '-' + m + '-' + d + ' ' + h + ':' + i + ":" + s;
};
/**
* @returns s 2018-12-12 或者 2018-12-12 12:12:12
*/
TimeUtils.parseDate = function (s) {
var t = Date.parse(s);
if (!isNaN(t)) {
return new Date(Date.parse(s.replace(/-/g, "/")));
}
else {
return new Date();
}
};
/**
* 秒数转换为时间形式。
* @param time 秒数
* @param partition 分隔符
* @param showHour 是否显示小时
* @return 返回一个以分隔符分割的时, 分, 秒
*
* 比如: time = 4351; secondToTime(time)返回字符串01:12:31;
*/
TimeUtils.secondToTime = function (time, partition, showHour) {
if (time === void 0) { time = 0; }
if (partition === void 0) { partition = ":"; }
if (showHour === void 0) { showHour = true; }
var hours = Math.floor(time / 3600);
var minutes = Math.floor(time % 3600 / 60);
var seconds = Math.floor(time % 3600 % 60);
var h = hours.toString();
var m = minutes.toString();
var s = seconds.toString();
if (hours < 10)
h = "0" + h;
if (minutes < 10)
m = "0" + m;
if (seconds < 10)
s = "0" + s;
var timeStr;
if (showHour)
timeStr = h + partition + m + partition + s;
else
timeStr = m + partition + s;
return timeStr;
};
/**
* 时间形式转换为毫秒数。
* @param time 以指定分隔符分割的时间字符串
* @param partition 分隔符
* @return 毫秒数显示的字符串
* @throws Error Exception
*
* 用法1 trace(MillisecondTransform.timeToMillisecond("00:60:00"))
* 输出 3600000
*
*
* 用法2 trace(MillisecondTransform.timeToMillisecond("00.60.00","."))
* 输出 3600000
*/
TimeUtils.timeToMillisecond = function (time, partition) {
if (partition === void 0) { partition = ":"; }
var _ary = time.split(partition);
var timeNum = 0;
var len = _ary.length;
for (var i = 0; i < len; i++) {
var n = _ary[i];
timeNum += n * Math.pow(60, (len - 1 - i));
}
timeNum *= 1000;
return timeNum.toString();
};
return TimeUtils;
}());
var es;
(function (es) {
var Viewport = /** @class */ (function () {
function Viewport(x, y, width, height) {
this._x = x;
this._y = y;
this._width = width;
this._height = height;
this._minDepth = 0;
this._maxDepth = 1;
}
Object.defineProperty(Viewport.prototype, "width", {
get: function () {
return this._width;
},
set: function (value) {
this._width = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Viewport.prototype, "height", {
get: function () {
return this._height;
},
set: function (value) {
this._height = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Viewport.prototype, "aspectRatio", {
get: function () {
if ((this._height != 0) && (this._width != 0))
return (this._width / this._height);
return 0;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Viewport.prototype, "bounds", {
get: function () {
return new es.Rectangle(this._x, this._y, this._width, this._height);
},
set: function (value) {
this._x = value.x;
this._y = value.y;
this._width = value.width;
this._height = value.height;
},
enumerable: true,
configurable: true
});
return Viewport;
}());
es.Viewport = Viewport;
})(es || (es = {}));
var es;
(function (es) {
/**
* 渲染器被添加到场景中并处理所有对RenderableComponent的实际调用
*/
var Renderer = /** @class */ (function () {
function Renderer(renderOrder) {
/**
* 指定场景调用渲染器的顺序
*/
this.renderOrder = 0;
/**
* 这个渲染器的标志,决定它是否应该调试渲染。
* render方法接收一个bool (debugRenderEnabled),让渲染器知道全局调试渲染是否打开/关闭。
* 渲染器然后使用本地bool来决定它是否应该调试渲染。
*/
this.shouldDebugRender = true;
this.renderOrder = renderOrder;
}
/**
* 当渲染器被添加到场景时调用
* @param scene
*/
Renderer.prototype.onAddedToScene = function (scene) {
};
/**
* 当场景结束或渲染器从场景中移除时调用。使用这个进行清理。
*/
Renderer.prototype.unload = function () {
};
/**
* 当默认场景渲染目标被调整大小和当场景已经开始添加渲染器时调用
* @param newWidth
* @param newHeight
*/
Renderer.prototype.onSceneBackBufferSizeChanged = function (newWidth, newHeight) {
};
Renderer.prototype.compareTo = function (other) {
return this.renderOrder - other.renderOrder;
};
return Renderer;
}());
es.Renderer = Renderer;
})(es || (es = {}));
var es;
(function (es) {
/**
* SceneTransition用于从一个场景过渡到另一个场景或在一个有效果的场景中过渡
*/
var SceneTransition = /** @class */ (function () {
function SceneTransition(sceneLoadAction) {
this.sceneLoadAction = sceneLoadAction;
this.loadsNewScene = sceneLoadAction != null;
}
Object.defineProperty(SceneTransition.prototype, "hasPreviousSceneRender", {
get: function () {
if (!this._hasPreviousSceneRender) {
this._hasPreviousSceneRender = true;
return false;
}
return true;
},
enumerable: true,
configurable: true
});
SceneTransition.prototype.preRender = function () {
};
SceneTransition.prototype.render = function () {
};
SceneTransition.prototype.onBeginTransition = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.loadNextScene()];
case 1:
_a.sent();
this.transitionComplete();
return [2 /*return*/];
}
});
});
};
SceneTransition.prototype.transitionComplete = function () {
es.Core._instance._sceneTransition = null;
if (this.onTransitionCompleted) {
this.onTransitionCompleted();
}
};
SceneTransition.prototype.loadNextScene = function () {
return __awaiter(this, void 0, void 0, function () {
var _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
if (this.onScreenObscured)
this.onScreenObscured();
if (!this.loadsNewScene) {
this.isNewSceneLoaded = true;
}
_a = es.Core;
return [4 /*yield*/, this.sceneLoadAction()];
case 1:
_a.scene = _b.sent();
this.isNewSceneLoaded = true;
return [2 /*return*/];
}
});
});
};
return SceneTransition;
}());
es.SceneTransition = SceneTransition;
})(es || (es = {}));
var es;
(function (es) {
/** 贝塞尔帮助类 */
var Bezier = /** @class */ (function () {
function Bezier() {
}
/**
* 二次贝塞尔曲线
* @param p0
* @param p1
* @param p2
* @param t
*/
Bezier.getPoint = function (p0, p1, p2, t) {
t = es.MathHelper.clamp01(t);
var oneMinusT = 1 - t;
return es.Vector2.add(es.Vector2.add(es.Vector2.multiply(new es.Vector2(oneMinusT * oneMinusT), p0), es.Vector2.multiply(new es.Vector2(2 * oneMinusT * t), p1)), es.Vector2.multiply(new es.Vector2(t * t), p2));
};
/**
* 得到二次贝塞尔函数的一阶导数
* @param p0
* @param p1
* @param p2
* @param t
*/
Bezier.getFirstDerivative = function (p0, p1, p2, t) {
return es.Vector2.add(es.Vector2.multiply(new es.Vector2(2 * (1 - t)), es.Vector2.subtract(p1, p0)), es.Vector2.multiply(new es.Vector2(2 * t), es.Vector2.subtract(p2, p1)));
};
/**
* 得到一个三次贝塞尔函数的一阶导数
* @param start
* @param firstControlPoint
* @param secondControlPoint
* @param end
* @param t
*/
Bezier.getFirstDerivativeThree = function (start, firstControlPoint, secondControlPoint, end, t) {
t = es.MathHelper.clamp01(t);
var oneMunusT = 1 - t;
return es.Vector2.add(es.Vector2.add(es.Vector2.multiply(new es.Vector2(3 * oneMunusT * oneMunusT), es.Vector2.subtract(firstControlPoint, start)), es.Vector2.multiply(new es.Vector2(6 * oneMunusT * t), es.Vector2.subtract(secondControlPoint, firstControlPoint))), es.Vector2.multiply(new es.Vector2(3 * t * t), es.Vector2.subtract(end, secondControlPoint)));
};
/**
* 计算一个三次贝塞尔
* @param start
* @param firstControlPoint
* @param secondControlPoint
* @param end
* @param t
*/
Bezier.getPointThree = function (start, firstControlPoint, secondControlPoint, end, t) {
t = es.MathHelper.clamp01(t);
var oneMunusT = 1 - t;
return es.Vector2.add(es.Vector2.add(es.Vector2.add(es.Vector2.multiply(new es.Vector2(oneMunusT * oneMunusT * oneMunusT), start), es.Vector2.multiply(new es.Vector2(3 * oneMunusT * oneMunusT * t), firstControlPoint)), es.Vector2.multiply(new es.Vector2(3 * oneMunusT * t * t), secondControlPoint)), es.Vector2.multiply(new es.Vector2(t * t * t), end));
};
/**
* 递归地细分bezier曲线,直到满足距离校正
* 在这种算法中,平面切片的点要比曲面切片少。返回完成后应返回到ListPool的合并列表。
* @param start
* @param firstCtrlPoint
* @param secondCtrlPoint
* @param end
* @param distanceTolerance
*/
Bezier.getOptimizedDrawingPoints = function (start, firstCtrlPoint, secondCtrlPoint, end, distanceTolerance) {
if (distanceTolerance === void 0) { distanceTolerance = 1; }
var points = es.ListPool.obtain();
points.push(start);
this.recursiveGetOptimizedDrawingPoints(start, firstCtrlPoint, secondCtrlPoint, end, points, distanceTolerance);
points.push(end);
return points;
};
/**
* 递归地细分bezier曲线,直到满足距离校正。在这种算法中,平面切片的点要比曲面切片少。
* @param start
* @param firstCtrlPoint
* @param secondCtrlPoint
* @param end
* @param points
* @param distanceTolerance
*/
Bezier.recursiveGetOptimizedDrawingPoints = function (start, firstCtrlPoint, secondCtrlPoint, end, points, distanceTolerance) {
// 计算线段的所有中点
var pt12 = es.Vector2.divide(es.Vector2.add(start, firstCtrlPoint), new es.Vector2(2));
var pt23 = es.Vector2.divide(es.Vector2.add(firstCtrlPoint, secondCtrlPoint), new es.Vector2(2));
var pt34 = es.Vector2.divide(es.Vector2.add(secondCtrlPoint, end), new es.Vector2(2));
// 计算新半直线的中点
var pt123 = es.Vector2.divide(es.Vector2.add(pt12, pt23), new es.Vector2(2));
var pt234 = es.Vector2.divide(es.Vector2.add(pt23, pt34), new es.Vector2(2));
// 最后再细分最后两个中点。如果我们满足我们的距离公差,这将是我们使用的最后一点。
var pt1234 = es.Vector2.divide(es.Vector2.add(pt123, pt234), new es.Vector2(2));
// 试着用一条直线来近似整个三次曲线
var deltaLine = es.Vector2.subtract(end, start);
var d2 = Math.abs(((firstCtrlPoint.x, end.x) * deltaLine.y - (firstCtrlPoint.y - end.y) * deltaLine.x));
var d3 = Math.abs(((secondCtrlPoint.x - end.x) * deltaLine.y - (secondCtrlPoint.y - end.y) * deltaLine.x));
if ((d2 + d3) * (d2 + d3) < distanceTolerance * (deltaLine.x * deltaLine.x + deltaLine.y * deltaLine.y)) {
points.push(pt1234);
return;
}
// 继续细分
this.recursiveGetOptimizedDrawingPoints(start, pt12, pt123, pt1234, points, distanceTolerance);
this.recursiveGetOptimizedDrawingPoints(pt1234, pt234, pt34, end, points, distanceTolerance);
};
return Bezier;
}());
es.Bezier = Bezier;
})(es || (es = {}));
var es;
(function (es) {
/**
* 帮助处理位掩码的实用程序类
* 除了isFlagSet之外,所有方法都期望flag参数是一个非移位的标志
* 允许您使用普通的(0、1、2、3等)来设置/取消您的标记
*/
var Flags = /** @class */ (function () {
function Flags() {
}
/**
* 检查位标志是否已在数值中设置
* 检查期望标志是否已经移位
* @param self
* @param flag
*/
Flags.isFlagSet = function (self, flag) {
return (self & flag) != 0;
};
/**
* 检查位标志是否在数值中设置
* @param self
* @param flag
*/
Flags.isUnshiftedFlagSet = function (self, flag) {
flag = 1 << flag;
return (self & flag) != 0;
};
/**
* 设置数值标志位,移除所有已经设置的标志
* @param self
* @param flag
*/
Flags.setFlagExclusive = function (self, flag) {
self.value = 1 << flag;
};
/**
* 设置标志位
* @param self
* @param flag
*/
Flags.setFlag = function (self, flag) {
self.value = (self.value | 1 << flag);
};
/**
* 取消标志位
* @param self
* @param flag
*/
Flags.unsetFlag = function (self, flag) {
flag = 1 << flag;
self.value = (self.value & (~flag));
};
/**
* 反转数值集合位
* @param self
*/
Flags.invertFlags = function (self) {
self.value = ~self.value;
};
return Flags;
}());
es.Flags = Flags;
})(es || (es = {}));
var es;
(function (es) {
var MathHelper = /** @class */ (function () {
function MathHelper() {
}
/**
* 将弧度转换成角度。
* @param radians 用弧度表示的角
*/
MathHelper.toDegrees = function (radians) {
return radians * 57.295779513082320876798154814105;
};
/**
* 将角度转换为弧度
* @param degrees
*/
MathHelper.toRadians = function (degrees) {
return degrees * 0.017453292519943295769236907684886;
};
/**
* mapps值(在leftMin - leftMax范围内)到rightMin - rightMax范围内的值
* @param value
* @param leftMin
* @param leftMax
* @param rightMin
* @param rightMax
*/
MathHelper.map = function (value, leftMin, leftMax, rightMin, rightMax) {
return rightMin + (value - leftMin) * (rightMax - rightMin) / (leftMax - leftMin);
};
MathHelper.lerp = function (value1, value2, amount) {
return value1 + (value2 - value1) * amount;
};
MathHelper.clamp = function (value, min, max) {
if (value < min)
return min;
if (value > max)
return max;
return value;
};
/**
* 给定圆心、半径和角度,得到圆周上的一个点。0度是3点钟。
* @param circleCenter
* @param radius
* @param angleInDegrees
*/
MathHelper.pointOnCirlce = function (circleCenter, radius, angleInDegrees) {
var radians = MathHelper.toRadians(angleInDegrees);
return new es.Vector2(Math.cos(radians) * radians + circleCenter.x, Math.sin(radians) * radians + circleCenter.y);
};
/**
* 如果值为偶数,返回true
* @param value
*/
MathHelper.isEven = function (value) {
return value % 2 == 0;
};
/**
* 数值限定在0-1之间
* @param value
*/
MathHelper.clamp01 = function (value) {
if (value < 0)
return 0;
if (value > 1)
return 1;
return value;
};
MathHelper.angleBetweenVectors = function (from, to) {
return Math.atan2(to.y - from.y, to.x - from.x);
};
/**
* 增加t并确保它总是大于或等于0并且小于长度
* @param t
* @param length
*/
MathHelper.incrementWithWrap = function (t, length) {
t++;
if (t == length)
return 0;
return t;
};
/**
* 由上移量向上移。start可以小于或大于end。例如:开始是2,结束是10,移位是4,结果是6
* @param start
* @param end
* @param shift
*/
MathHelper.approach = function (start, end, shift) {
if (start < end)
return Math.min(start + shift, end);
return Math.max(start - shift, end);
};
MathHelper.Epsilon = 0.00001;
MathHelper.Rad2Deg = 57.29578;
MathHelper.Deg2Rad = 0.0174532924;
/**
* 表示pi除以2的值(1.57079637)
*/
MathHelper.PiOver2 = Math.PI / 2;
return MathHelper;
}());
es.MathHelper = MathHelper;
})(es || (es = {}));
var es;
(function (es) {
/**
* 表示右手3 * 3的浮点矩阵,可以存储平移、缩放和旋转信息。
*/
var Matrix2D = /** @class */ (function () {
/**
* 构建一个矩阵
* @param m11
* @param m12
* @param m21
* @param m22
* @param m31
* @param m32
*/
function Matrix2D(m11, m12, m21, m22, m31, m32) {
this.m11 = 0; // x 缩放
this.m12 = 0;
this.m21 = 0;
this.m22 = 0;
this.m31 = 0;
this.m32 = 0;
this.m11 = m11;
this.m12 = m12;
this.m21 = m21;
this.m22 = m22;
this.m31 = m31;
this.m32 = m32;
}
Object.defineProperty(Matrix2D, "identity", {
/**
* 返回标识矩阵
*/
get: function () {
return this._identity;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Matrix2D.prototype, "translation", {
/**
* 储存在该矩阵中的位置
*/
get: function () {
return new es.Vector2(this.m31, this.m32);
},
set: function (value) {
this.m31 = value.x;
this.m32 = value.y;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Matrix2D.prototype, "rotation", {
/**
* 以弧度为单位的旋转,存储在这个矩阵中
*/
get: function () {
return Math.atan2(this.m21, this.m11);
},
set: function (value) {
var val1 = Math.cos(value);
var val2 = Math.sin(value);
this.m11 = val1;
this.m12 = val2;
this.m21 = -val2;
this.m22 = val1;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Matrix2D.prototype, "rotationDegrees", {
/**
* 矩阵中存储的旋转度数
*/
get: function () {
return es.MathHelper.toDegrees(this.rotation);
},
set: function (value) {
this.rotation = es.MathHelper.toRadians(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Matrix2D.prototype, "scale", {
/**
* 储存在这个矩阵中的缩放
*/
get: function () {
return new es.Vector2(this.m11, this.m22);
},
set: function (value) {
this.m11 = value.x;
this.m22 = value.y;
},
enumerable: true,
configurable: true
});
/**
* 创建一个新的围绕Z轴的旋转矩阵2D
* @param radians
*/
Matrix2D.createRotation = function (radians) {
var result = this.identity;
var val1 = Math.cos(radians);
var val2 = Math.sin(radians);
result.m11 = val1;
result.m12 = val2;
result.m21 = -val2;
result.m22 = val1;
return result;
};
/**
* 创建一个新的缩放矩阵2D
* @param xScale
* @param yScale
*/
Matrix2D.createScale = function (xScale, yScale) {
var result = this.identity;
result.m11 = xScale;
result.m12 = 0;
result.m21 = 0;
result.m22 = yScale;
result.m31 = 0;
result.m32 = 0;
return result;
};
/**
* 创建一个新的平移矩阵2D
* @param xPosition
* @param yPosition
*/
Matrix2D.createTranslation = function (xPosition, yPosition) {
var result = this.identity;
result.m11 = 1;
result.m12 = 0;
result.m21 = 0;
result.m22 = 1;
result.m31 = xPosition;
result.m32 = yPosition;
return result;
};
Matrix2D.invert = function (matrix) {
var det = 1 / matrix.determinant();
var result = this.identity;
result.m11 = matrix.m22 * det;
result.m12 = -matrix.m12 * det;
result.m21 = -matrix.m21 * det;
result.m22 = matrix.m11 * det;
result.m31 = (matrix.m32 * matrix.m21 - matrix.m31 * matrix.m22) * det;
result.m32 = -(matrix.m32 * matrix.m11 - matrix.m31 * matrix.m12) * det;
return result;
};
/**
* 创建一个新的matrix, 它包含两个矩阵的和。
* @param matrix
*/
Matrix2D.prototype.add = function (matrix) {
this.m11 += matrix.m11;
this.m12 += matrix.m12;
this.m21 += matrix.m21;
this.m22 += matrix.m22;
this.m31 += matrix.m31;
this.m32 += matrix.m32;
return this;
};
Matrix2D.prototype.substract = function (matrix) {
this.m11 -= matrix.m11;
this.m12 -= matrix.m12;
this.m21 -= matrix.m21;
this.m22 -= matrix.m22;
this.m31 -= matrix.m31;
this.m32 -= matrix.m32;
return this;
};
Matrix2D.prototype.divide = function (matrix) {
this.m11 /= matrix.m11;
this.m12 /= matrix.m12;
this.m21 /= matrix.m21;
this.m22 /= matrix.m22;
this.m31 /= matrix.m31;
this.m32 /= matrix.m32;
return this;
};
Matrix2D.prototype.multiply = function (matrix) {
var m11 = (this.m11 * matrix.m11) + (this.m12 * matrix.m21);
var m12 = (this.m11 * matrix.m12) + (this.m12 * matrix.m22);
var m21 = (this.m21 * matrix.m11) + (this.m22 * matrix.m21);
var m22 = (this.m21 * matrix.m12) + (this.m22 * matrix.m22);
var m31 = (this.m31 * matrix.m11) + (this.m32 * matrix.m21) + matrix.m31;
var m32 = (this.m31 * matrix.m12) + (this.m32 * matrix.m22) + matrix.m32;
this.m11 = m11;
this.m12 = m12;
this.m21 = m21;
this.m22 = m22;
this.m31 = m31;
this.m32 = m32;
return this;
};
Matrix2D.prototype.determinant = function () {
return this.m11 * this.m22 - this.m12 * this.m21;
};
/**
* 创建一个新的Matrix2D,包含指定矩阵中的线性插值。
* @param matrix1
* @param matrix2
* @param amount
*/
Matrix2D.lerp = function (matrix1, matrix2, amount) {
matrix1.m11 = matrix1.m11 + ((matrix2.m11 - matrix1.m11) * amount);
matrix1.m12 = matrix1.m12 + ((matrix2.m12 - matrix1.m12) * amount);
matrix1.m21 = matrix1.m21 + ((matrix2.m21 - matrix1.m21) * amount);
matrix1.m22 = matrix1.m22 + ((matrix2.m22 - matrix1.m22) * amount);
matrix1.m31 = matrix1.m31 + ((matrix2.m31 - matrix1.m31) * amount);
matrix1.m32 = matrix1.m32 + ((matrix2.m32 - matrix1.m32) * amount);
return matrix1;
};
/**
* 交换矩阵的行和列
* @param matrix
*/
Matrix2D.transpose = function (matrix) {
var ret = this.identity;
ret.m11 = matrix.m11;
ret.m12 = matrix.m21;
ret.m21 = matrix.m12;
ret.m22 = matrix.m22;
ret.m31 = 0;
ret.m32 = 0;
return ret;
};
Matrix2D.prototype.mutiplyTranslation = function (x, y) {
var trans = Matrix2D.createTranslation(x, y);
return es.MatrixHelper.mutiply(this, trans);
};
/**
* 比较当前实例是否等于指定的Matrix2D
* @param other
*/
Matrix2D.prototype.equals = function (other) {
return this == other;
};
Matrix2D.prototype.toString = function () {
return "{m11:" + this.m11 + " m12:" + this.m12 + " m21:" + this.m21 + " m22:" + this.m22 + " m31:" + this.m31 + " m32:" + this.m32 + "}";
};
Matrix2D._identity = new Matrix2D(1, 0, 0, 1, 0, 0);
return Matrix2D;
}());
es.Matrix2D = Matrix2D;
})(es || (es = {}));
var es;
(function (es) {
var MatrixHelper = /** @class */ (function () {
function MatrixHelper() {
}
/**
* 创建一个新的Matrix2D,其中包含两个矩阵的和
* @param matrix1
* @param matrix2
*/
MatrixHelper.add = function (matrix1, matrix2) {
var result = es.Matrix2D.identity;
result.m11 = matrix1.m11 + matrix2.m11;
result.m12 = matrix1.m12 + matrix2.m12;
result.m21 = matrix1.m21 + matrix2.m21;
result.m22 = matrix1.m22 + matrix2.m22;
result.m31 = matrix1.m31 + matrix2.m31;
result.m32 = matrix1.m32 + matrix2.m32;
return result;
};
/**
* 将一个Matrix2D的元素除以另一个矩阵的元素
* @param matrix1
* @param matrix2
*/
MatrixHelper.divide = function (matrix1, matrix2) {
var result = es.Matrix2D.identity;
result.m11 = matrix1.m11 / matrix2.m11;
result.m12 = matrix1.m12 / matrix2.m12;
result.m21 = matrix1.m21 / matrix2.m21;
result.m22 = matrix1.m22 / matrix2.m22;
result.m31 = matrix1.m31 / matrix2.m31;
result.m32 = matrix1.m32 / matrix2.m32;
return result;
};
/**
* 创建一个新的Matrix2D,包含两个矩阵的乘法
* @param matrix1
* @param matrix2
*/
MatrixHelper.mutiply = function (matrix1, matrix2) {
var result = es.Matrix2D.identity;
if (matrix2 instanceof es.Matrix2D) {
var m11 = (matrix1.m11 * matrix2.m11) + (matrix1.m12 * matrix2.m21);
var m12 = (matrix2.m11 * matrix2.m12) + (matrix1.m12 * matrix2.m22);
var m21 = (matrix1.m21 * matrix2.m11) + (matrix1.m22 * matrix2.m21);
var m22 = (matrix1.m21 * matrix2.m12) + (matrix1.m22 * matrix2.m22);
var m31 = (matrix1.m31 * matrix2.m11) + (matrix1.m32 * matrix2.m21) + matrix2.m31;
var m32 = (matrix1.m31 * matrix2.m12) + (matrix1.m32 * matrix2.m22) + matrix2.m32;
result.m11 = m11;
result.m12 = m12;
result.m21 = m21;
result.m22 = m22;
result.m31 = m31;
result.m32 = m32;
}
else if (typeof matrix2 == "number") {
result.m11 = matrix1.m11 * matrix2;
result.m12 = matrix1.m12 * matrix2;
result.m21 = matrix1.m21 * matrix2;
result.m22 = matrix1.m22 * matrix2;
result.m31 = matrix1.m31 * matrix2;
result.m32 = matrix1.m32 * matrix2;
}
return result;
};
/**
* 创建一个新的Matrix2D,包含一个矩阵与另一个矩阵的减法。
* @param matrix1
* @param matrix2
*/
MatrixHelper.subtract = function (matrix1, matrix2) {
var result = es.Matrix2D.identity;
result.m11 = matrix1.m11 - matrix2.m11;
result.m12 = matrix1.m12 - matrix2.m12;
result.m21 = matrix1.m21 - matrix2.m21;
result.m22 = matrix1.m22 - matrix2.m22;
result.m31 = matrix1.m31 - matrix2.m31;
result.m32 = matrix1.m32 - matrix2.m32;
return result;
};
return MatrixHelper;
}());
es.MatrixHelper = MatrixHelper;
})(es || (es = {}));
var es;
(function (es) {
var Rectangle = /** @class */ (function () {
/**
* 创建一个新的Rectanglestruct实例,指定位置、宽度和高度。
* @param x 创建的矩形的左上角的X坐标
* @param y 创建的矩形的左上角的y坐标
* @param width 创建的矩形的宽度
* @param height 创建的矩形的高度
*/
function Rectangle(x, y, width, height) {
if (x === void 0) { x = 0; }
if (y === void 0) { y = 0; }
if (width === void 0) { width = 0; }
if (height === void 0) { height = 0; }
/**
* 该矩形的左上角的x坐标
*/
this.x = 0;
/**
* 该矩形的左上角的y坐标
*/
this.y = 0;
/**
* 该矩形的宽度
*/
this.width = 0;
/**
* 该矩形的高度
*/
this.height = 0;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
Object.defineProperty(Rectangle, "empty", {
/**
* 返回X=0, Y=0, Width=0, Height=0的矩形
*/
get: function () {
return this.emptyRectangle;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Rectangle, "maxRect", {
/**
* 返回一个Number.Min/Max值的矩形
*/
get: function () {
return new Rectangle(Number.MIN_VALUE / 2, Number.MIN_VALUE / 2, Number.MAX_VALUE, Number.MAX_VALUE);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Rectangle.prototype, "left", {
/**
* 返回此矩形左边缘的X坐标
*/
get: function () {
return this.x;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Rectangle.prototype, "right", {
/**
* 返回此矩形右边缘的X坐标
*/
get: function () {
return this.x + this.width;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Rectangle.prototype, "top", {
/**
* 返回此矩形顶边的y坐标
*/
get: function () {
return this.y;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Rectangle.prototype, "bottom", {
/**
* 返回此矩形底边的y坐标
*/
get: function () {
return this.y + this.height;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Rectangle.prototype, "max", {
/**
* 获取矩形的最大点,即右下角
*/
get: function () {
return new es.Vector2(this.right, this.bottom);
},
enumerable: true,
configurable: true
});
/**
* 这个矩形的宽和高是否为0,位置是否为(0,0)
*/
Rectangle.prototype.isEmpty = function () {
return ((((this.width == 0) && (this.height == 0)) && (this.x == 0)) && (this.y == 0));
};
Object.defineProperty(Rectangle.prototype, "location", {
/** 这个矩形的左上角坐标 */
get: function () {
return new es.Vector2(this.x, this.y);
},
set: function (value) {
this.x = value.x;
this.y = value.y;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Rectangle.prototype, "size", {
/**
* 这个矩形的宽-高坐标
*/
get: function () {
return new es.Vector2(this.width, this.height);
},
set: function (value) {
this.width = value.x;
this.height = value.y;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Rectangle.prototype, "center", {
/**
* 位于这个矩形中心的一个点
* 如果 "宽度 "或 "高度 "是奇数,则中心点将向下舍入
*/
get: function () {
return new es.Vector2(this.x + (this.width / 2), this.y + (this.height / 2));
},
enumerable: true,
configurable: true
});
/**
* 创建一个给定最小/最大点(左上角,右下角)的矩形
* @param minX
* @param minY
* @param maxX
* @param maxY
*/
Rectangle.fromMinMax = function (minX, minY, maxX, maxY) {
return new Rectangle(minX, minY, maxX - minX, maxY - minY);
};
/**
* 给定多边形的点,计算边界
* @param points
* @returns 来自多边形的点
*/
Rectangle.rectEncompassingPoints = function (points) {
// 我们需要求出x/y的最小值/最大值
var minX = Number.POSITIVE_INFINITY;
var minY = Number.POSITIVE_INFINITY;
var maxX = Number.NEGATIVE_INFINITY;
var maxY = Number.NEGATIVE_INFINITY;
for (var i = 0; i < points.length; i++) {
var pt = points[i];
if (pt.x < minX)
minX = pt.x;
if (pt.x > maxX)
maxX = pt.x;
if (pt.y < minY)
minY = pt.y;
if (pt.y > maxY)
maxY = pt.y;
}
return this.fromMinMax(minX, minY, maxX, maxY);
};
/**
* 获取指定边缘的位置
* @param edge
*/
Rectangle.prototype.getSide = function (edge) {
switch (edge) {
case es.Edge.top:
return this.top;
case es.Edge.bottom:
return this.bottom;
case es.Edge.left:
return this.left;
case es.Edge.right:
return this.right;
default:
throw new Error("Argument Out Of Range");
}
};
/**
* 获取所提供的坐标是否在这个矩形的范围内
* @param x 检查封堵点的X坐标
* @param y 检查封堵点的Y坐标
*/
Rectangle.prototype.contains = function (x, y) {
return ((((this.x <= x) && (x < (this.x + this.width))) &&
(this.y <= y)) && (y < (this.y + this.height)));
};
/**
* 按指定的水平和垂直方向调整此矩形的边缘
* @param horizontalAmount 调整左、右边缘的值
* @param verticalAmount 调整上、下边缘的值
*/
Rectangle.prototype.inflate = function (horizontalAmount, verticalAmount) {
this.x -= horizontalAmount;
this.y -= verticalAmount;
this.width += horizontalAmount * 2;
this.height += verticalAmount * 2;
};
/**
* 获取其他矩形是否与这个矩形相交
* @param value 另一个用于测试的矩形
*/
Rectangle.prototype.intersects = function (value) {
return value.left < this.right &&
this.left < value.right &&
value.top < this.bottom &&
this.top < value.bottom;
};
Rectangle.prototype.rayIntersects = function (ray, distance) {
distance.value = 0;
var maxValue = Number.MAX_VALUE;
if (Math.abs(ray.direction.x) < 1E-06) {
if ((ray.start.x < this.x) || (ray.start.x > this.x + this.width))
return false;
}
else {
var num11 = 1 / ray.direction.x;
var num8 = (this.x - ray.start.x) * num11;
var num7 = (this.x + this.width - ray.start.x) * num11;
if (num8 > num7) {
var num14 = num8;
num8 = num7;
num7 = num14;
}
distance.value = Math.max(num8, distance.value);
maxValue = Math.min(num7, maxValue);
if (distance.value > maxValue)
return false;
}
if (Math.abs(ray.direction.y) < 1E-06) {
if ((ray.start.y < this.y) || (ray.start.y > this.y + this.height))
return false;
}
else {
var num10 = 1 / ray.direction.y;
var num6 = (this.y - ray.start.y) * num10;
var num5 = (this.y + this.height - ray.start.y) * num10;
if (num6 > num5) {
var num13 = num6;
num6 = num5;
num5 = num13;
}
distance.value = Math.max(num6, distance.value);
maxValue = Math.max(num5, maxValue);
if (distance.value > maxValue)
return false;
}
return true;
};
/**
* 获取所提供的矩形是否在此矩形的边界内
* @param value
*/
Rectangle.prototype.containsRect = function (value) {
return ((((this.x <= value.x) && (value.x < (this.x + this.width))) &&
(this.y <= value.y)) &&
(value.y < (this.y + this.height)));
};
Rectangle.prototype.getHalfSize = function () {
return new es.Vector2(this.width * 0.5, this.height * 0.5);
};
Rectangle.prototype.getClosestPointOnBoundsToOrigin = function () {
var max = this.max;
var minDist = Math.abs(this.location.x);
var boundsPoint = new es.Vector2(this.location.x, 0);
if (Math.abs(max.x) < minDist) {
minDist = Math.abs(max.x);
boundsPoint.x = max.x;
boundsPoint.y = 0;
}
if (Math.abs(max.y) < minDist) {
minDist = Math.abs(max.y);
boundsPoint.x = 0;
boundsPoint.y = max.y;
}
if (Math.abs(this.location.y) < minDist) {
minDist = Math.abs(this.location.y);
boundsPoint.x = 0;
boundsPoint.y = this.location.y;
}
return boundsPoint;
};
/**
* 返回离给定点最近的点
* @param point 矩形上离点最近的点
*/
Rectangle.prototype.getClosestPointOnRectangleToPoint = function (point) {
// 对于每条轴,如果点在框外,就把它限制在框内,否则就不要管它
var res = new es.Vector2();
res.x = es.MathHelper.clamp(point.x, this.left, this.right);
res.y = es.MathHelper.clamp(point.y, this.top, this.bottom);
return res;
};
/**
* 获取矩形边界上与给定点最近的点
* @param point
* @param edgeNormal
* @returns 矩形边框上离点最近的点
*/
Rectangle.prototype.getClosestPointOnRectangleBorderToPoint = function (point, edgeNormal) {
edgeNormal = es.Vector2.zero;
// 对于每条轴,如果点在框外,就把它限制在框内,否则就不要管它
var res = new es.Vector2();
res.x = es.MathHelper.clamp(point.x, this.left, this.right);
res.y = es.MathHelper.clamp(point.y, this.top, this.bottom);
// 如果点在矩形内,我们需要将res推到边界上,因为它将在矩形内
if (this.contains(res.x, res.y)) {
var dl = res.x - this.left;
var dr = this.right - res.x;
var dt = res.y - this.top;
var db = this.bottom - res.y;
var min = Math.min(dl, dr, dt, db);
if (min == dt) {
res.y = this.top;
edgeNormal.y = -1;
}
else if (min == db) {
res.y = this.bottom;
edgeNormal.y = 1;
}
else if (min == dl) {
res.x = this.left;
edgeNormal.x = -1;
}
else {
res.x = this.right;
edgeNormal.x = 1;
}
}
else {
if (res.x == this.left)
edgeNormal.x = -1;
if (res.x == this.right)
edgeNormal.x = 1;
if (res.y == this.top)
edgeNormal.y = -1;
if (res.y == this.bottom)
edgeNormal.y = 1;
}
return res;
};
/**
* 创建一个新的RectangleF,该RectangleF包含两个其他矩形的重叠区域
* @param value1
* @param value2
* @returns 将两个矩形的重叠区域作为输出参数
*/
Rectangle.intersect = function (value1, value2) {
if (value1.intersects(value2)) {
var right_side = Math.min(value1.x + value1.width, value2.x + value2.width);
var left_side = Math.max(value1.x, value2.x);
var top_side = Math.max(value1.y, value2.y);
var bottom_side = Math.min(value1.y + value1.height, value2.y + value2.height);
return new Rectangle(left_side, top_side, right_side - left_side, bottom_side - top_side);
}
else {
return new Rectangle(0, 0, 0, 0);
}
};
/**
* 改变这个矩形的位置
* @param offsetX 要添加到这个矩形的X坐标
* @param offsetY 要添加到这个矩形的y坐标
*/
Rectangle.prototype.offset = function (offsetX, offsetY) {
this.x += offsetX;
this.y += offsetY;
};
/**
* 创建一个完全包含两个其他矩形的新矩形
* @param value1
* @param value2
*/
Rectangle.union = function (value1, value2) {
var x = Math.min(value1.x, value2.x);
var y = Math.min(value1.y, value2.y);
return new Rectangle(x, y, Math.max(value1.right, value2.right) - x, Math.max(value1.bottom, value2.bottom) - y);
};
/**
* 在矩形重叠的地方创建一个新的矩形
* @param value1
* @param value2
*/
Rectangle.overlap = function (value1, value2) {
var x = Math.max(Math.max(value1.x, value2.x), 0);
var y = Math.max(Math.max(value1.y, value2.y), 0);
return new Rectangle(x, y, Math.max(Math.min(value1.right, value2.right) - x, 0), Math.max(Math.min(value1.bottom, value2.bottom) - y, 0));
};
Rectangle.prototype.calculateBounds = function (parentPosition, position, origin, scale, rotation, width, height) {
if (rotation == 0) {
this.x = parentPosition.x + position.x - origin.x * scale.x;
this.y = parentPosition.y + position.y - origin.y * scale.y;
this.width = width * scale.x;
this.height = height * scale.y;
}
else {
// 我们需要找到我们的绝对最小/最大值,并据此创建边界
var worldPosX = parentPosition.x + position.x;
var worldPosY = parentPosition.y + position.y;
// 考虑到原点,将参考点设置为世界参考
this._transformMat = es.Matrix2D.createTranslation(-worldPosX - origin.x, -worldPosY - origin.y);
this._tempMat = es.Matrix2D.createScale(scale.x, scale.y);
this._transformMat = this._transformMat.multiply(this._tempMat);
this._tempMat = es.Matrix2D.createRotation(rotation);
this._transformMat = this._transformMat.multiply(this._tempMat);
this._tempMat = es.Matrix2D.createTranslation(worldPosX, worldPosY);
this._transformMat = this._transformMat.multiply(this._tempMat);
// TODO: 我们可以把世界变换留在矩阵中,避免在世界空间中得到所有的四个角
var topLeft = new es.Vector2(worldPosX, worldPosY);
var topRight = new es.Vector2(worldPosX + width, worldPosY);
var bottomLeft = new es.Vector2(worldPosX, worldPosY + height);
var bottomRight = new es.Vector2(worldPosX + width, worldPosY + height);
es.Vector2Ext.transformR(topLeft, this._transformMat, topLeft);
es.Vector2Ext.transformR(topRight, this._transformMat, topRight);
es.Vector2Ext.transformR(bottomLeft, this._transformMat, bottomLeft);
es.Vector2Ext.transformR(bottomRight, this._transformMat, bottomRight);
// 找出最小值和最大值,这样我们就可以计算出我们的边界框。
var minX = Math.min(topLeft.x, bottomRight.x, topRight.x, bottomLeft.x);
var maxX = Math.max(topLeft.x, bottomRight.x, topRight.x, bottomLeft.x);
var minY = Math.min(topLeft.y, bottomRight.y, topRight.y, bottomLeft.y);
var maxY = Math.max(topLeft.y, bottomRight.y, topRight.y, bottomLeft.y);
this.location = new es.Vector2(minX, minY);
this.width = maxX - minX;
this.height = maxY - minY;
}
};
/**
* 返回一个横跨当前矩形和提供的三角形位置的矩形
* @param deltaX
* @param deltaY
*/
Rectangle.prototype.getSweptBroadphaseBounds = function (deltaX, deltaY) {
var broadphasebox = Rectangle.empty;
broadphasebox.x = deltaX > 0 ? this.x : this.x + deltaX;
broadphasebox.y = deltaY > 0 ? this.y : this.y + deltaY;
broadphasebox.width = deltaX > 0 ? deltaX + this.width : this.width - deltaX;
broadphasebox.height = deltaY > 0 ? deltaY + this.height : this.height - deltaY;
return broadphasebox;
};
/**
* 如果发生碰撞,返回true
* moveX和moveY将返回b1为避免碰撞而必须移动的移动量
* @param other
* @param moveX
* @param moveY
*/
Rectangle.prototype.collisionCheck = function (other, moveX, moveY) {
moveX.value = moveY.value = 0;
var l = other.x - (this.x + this.width);
var r = (other.x + other.width) - this.x;
var t = (other.y - (this.y + this.height));
var b = (other.y + other.height) - this.y;
// 检验是否有碰撞
if (l > 0 || r < 0 || t > 0 || b < 0)
return false;
// 求两边的偏移量
moveX.value = Math.abs(l) < r ? l : r;
moveY.value = Math.abs(t) < b ? t : b;
// 只使用最小的偏移量
if (Math.abs(moveX.value) < Math.abs(moveY.value))
moveY.value = 0;
else
moveX.value = 0;
return true;
};
/**
* 计算两个矩形之间有符号的交点深度
* @param rectA
* @param rectB
* @returns 两个相交的矩形之间的重叠量。
* 这些深度值可以是负值,取决于矩形/相交的哪些边。
* 这允许调用者确定正确的推送对象的方向,以解决碰撞问题。
* 如果矩形不相交,则返回Vector2.Zero
*/
Rectangle.getIntersectionDepth = function (rectA, rectB) {
// 计算半尺寸
var halfWidthA = rectA.width / 2;
var halfHeightA = rectA.height / 2;
var halfWidthB = rectB.width / 2;
var halfHeightB = rectB.height / 2;
// 计算中心
var centerA = new es.Vector2(rectA.left + halfWidthA, rectA.top + halfHeightA);
var centerB = new es.Vector2(rectB.left + halfWidthB, rectB.top + halfHeightB);
// 计算当前中心间的距离和最小非相交距离
var distanceX = centerA.x - centerB.x;
var distanceY = centerA.y - centerB.y;
var minDistanceX = halfWidthA + halfWidthB;
var minDistanceY = halfHeightA + halfHeightB;
// 如果我们根本不相交,则返回(0,0)
if (Math.abs(distanceX) >= minDistanceX || Math.abs(distanceY) >= minDistanceY)
return es.Vector2.zero;
// 计算并返回交叉点深度
var depthX = distanceX > 0 ? minDistanceX - distanceX : -minDistanceX - distanceX;
var depthY = distanceY > 0 ? minDistanceY - distanceY : -minDistanceY - distanceY;
return new es.Vector2(depthX, depthY);
};
/**
* 比较当前实例是否等于指定的矩形
* @param other
*/
Rectangle.prototype.equals = function (other) {
return this === other;
};
/**
* 获取这个矩形的哈希码
*/
Rectangle.prototype.getHashCode = function () {
return (this.x ^ this.y ^ this.width ^ this.height);
};
Rectangle.emptyRectangle = new Rectangle();
return Rectangle;
}());
es.Rectangle = Rectangle;
})(es || (es = {}));
var es;
(function (es) {
/**
* 它存储值,直到累计的总数大于1。一旦超过1,该值将在调用update时添加到amount中
* 一般用法如下:
*
* let deltaMove = this.velocity * es.Time.deltaTime;
* deltaMove.x = this._x.update(deltaMove.x);
* deltaMove.y = this._y.update(deltaMove.y);
*/
var SubpixelFloat = /** @class */ (function () {
function SubpixelFloat() {
this.remainder = 0;
}
/**
* 以amount递增余数,将值截断,存储新的余数并将amount设置为当前值
* @param amount
*/
SubpixelFloat.prototype.update = function (amount) {
this.remainder += amount;
var motion = Math.floor(Math.trunc(this.remainder));
this.remainder -= motion;
amount = motion;
return amount;
};
/**
* 将余数重置为0
*/
SubpixelFloat.prototype.reset = function () {
this.remainder = 0;
};
return SubpixelFloat;
}());
es.SubpixelFloat = SubpixelFloat;
})(es || (es = {}));
var es;
(function (es) {
var SubpixelVector2 = /** @class */ (function () {
function SubpixelVector2() {
this._x = new es.SubpixelFloat();
this._y = new es.SubpixelFloat();
}
/**
* 以数量递增s/y余数,将值截断为整数,存储新的余数并将amount设置为当前值
* @param amount
*/
SubpixelVector2.prototype.update = function (amount) {
amount.x = this._x.update(amount.x);
amount.y = this._y.update(amount.y);
};
/**
* 将余数重置为0
*/
SubpixelVector2.prototype.reset = function () {
this._x.reset();
this._y.reset();
};
return SubpixelVector2;
}());
es.SubpixelVector2 = SubpixelVector2;
})(es || (es = {}));
var es;
(function (es) {
/** 2d 向量 */
var Vector2 = /** @class */ (function () {
/**
* 从两个值构造一个带有X和Y的二维向量。
* @param x 二维空间中的x坐标
* @param y 二维空间的y坐标
*/
function Vector2(x, y) {
this.x = 0;
this.y = 0;
this.x = x ? x : 0;
this.y = y != undefined ? y : this.x;
}
Object.defineProperty(Vector2, "zero", {
get: function () {
return new Vector2(0, 0);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Vector2, "one", {
get: function () {
return new Vector2(1, 1);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Vector2, "unitX", {
get: function () {
return new Vector2(1, 0);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Vector2, "unitY", {
get: function () {
return new Vector2(0, 1);
},
enumerable: true,
configurable: true
});
/**
*
* @param value1
* @param value2
*/
Vector2.add = function (value1, value2) {
var result = new Vector2(0, 0);
result.x = value1.x + value2.x;
result.y = value1.y + value2.y;
return result;
};
/**
*
* @param value1
* @param value2
*/
Vector2.divide = function (value1, value2) {
var result = new Vector2(0, 0);
result.x = value1.x / value2.x;
result.y = value1.y / value2.y;
return result;
};
/**
*
* @param value1
* @param value2
*/
Vector2.multiply = function (value1, value2) {
var result = new Vector2(0, 0);
result.x = value1.x * value2.x;
result.y = value1.y * value2.y;
return result;
};
/**
*
* @param value1
* @param value2
*/
Vector2.subtract = function (value1, value2) {
var result = new Vector2(0, 0);
result.x = value1.x - value2.x;
result.y = value1.y - value2.y;
return result;
};
/**
* 创建一个新的Vector2
* 它包含来自另一个向量的标准化值。
* @param value
*/
Vector2.normalize = function (value) {
var nValue = new Vector2(value.x, value.y);
var val = 1 / Math.sqrt((nValue.x * nValue.x) + (nValue.y * nValue.y));
nValue.x *= val;
nValue.y *= val;
return nValue;
};
/**
* 返回两个向量的点积
* @param value1
* @param value2
*/
Vector2.dot = function (value1, value2) {
return (value1.x * value2.x) + (value1.y * value2.y);
};
/**
* 返回两个向量之间距离的平方
* @param value1
* @param value2
*/
Vector2.distanceSquared = function (value1, value2) {
var v1 = value1.x - value2.x, v2 = value1.y - value2.y;
return (v1 * v1) + (v2 * v2);
};
/**
* 将指定的值限制在一个范围内
* @param value1
* @param min
* @param max
*/
Vector2.clamp = function (value1, min, max) {
return new Vector2(es.MathHelper.clamp(value1.x, min.x, max.x), es.MathHelper.clamp(value1.y, min.y, max.y));
};
/**
* 创建一个新的Vector2,其中包含指定向量的线性插值
* @param value1 第一个向量
* @param value2 第二个向量
* @param amount 加权值(0.0-1.0之间)
* @returns 指定向量的线性插值结果
*/
Vector2.lerp = function (value1, value2, amount) {
return new Vector2(es.MathHelper.lerp(value1.x, value2.x, amount), es.MathHelper.lerp(value1.y, value2.y, amount));
};
/**
* 创建一个新的Vector2,该Vector2包含了通过指定的Matrix进行的二维向量变换。
* @param position
* @param matrix
*/
Vector2.transform = function (position, matrix) {
return new Vector2((position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m31, (position.x * matrix.m12) + (position.y * matrix.m22) + matrix.m32);
};
/**
* 返回两个向量之间的距离
* @param value1
* @param value2
* @returns 两个向量之间的距离
*/
Vector2.distance = function (value1, value2) {
var v1 = value1.x - value2.x, v2 = value1.y - value2.y;
return Math.sqrt((v1 * v1) + (v2 * v2));
};
/**
* 返回两个向量之间的角度,单位是度数
* @param from
* @param to
*/
Vector2.angle = function (from, to) {
from = Vector2.normalize(from);
to = Vector2.normalize(to);
return Math.acos(es.MathHelper.clamp(Vector2.dot(from, to), -1, 1)) * es.MathHelper.Rad2Deg;
};
/**
* 创建一个包含指定向量反转的新Vector2
* @param value
* @returns 矢量反演的结果
*/
Vector2.negate = function (value) {
value.x = -value.x;
value.y = -value.y;
return value;
};
/**
*
* @param value
*/
Vector2.prototype.add = function (value) {
this.x += value.x;
this.y += value.y;
return this;
};
/**
*
* @param value
*/
Vector2.prototype.divide = function (value) {
this.x /= value.x;
this.y /= value.y;
return this;
};
/**
*
* @param value
*/
Vector2.prototype.multiply = function (value) {
this.x *= value.x;
this.y *= value.y;
return this;
};
/**
* 从当前Vector2减去一个Vector2
* @param value 要减去的Vector2
* @returns 当前Vector2
*/
Vector2.prototype.subtract = function (value) {
this.x -= value.x;
this.y -= value.y;
return this;
};
/**
* 将这个Vector2变成一个方向相同的单位向量
*/
Vector2.prototype.normalize = function () {
var val = 1 / Math.sqrt((this.x * this.x) + (this.y * this.y));
this.x *= val;
this.y *= val;
};
/** 返回它的长度 */
Vector2.prototype.length = function () {
return Math.sqrt((this.x * this.x) + (this.y * this.y));
};
/**
* 返回该Vector2的平方长度
* @returns 这个Vector2的平方长度
*/
Vector2.prototype.lengthSquared = function () {
return (this.x * this.x) + (this.y * this.y);
};
/**
* 四舍五入X和Y值
*/
Vector2.prototype.round = function () {
return new Vector2(Math.round(this.x), Math.round(this.y));
};
/**
* 比较当前实例是否等于指定的对象
* @param other 要比较的对象
* @returns 如果实例相同true 否则false
*/
Vector2.prototype.equals = function (other) {
if (other instanceof Vector2) {
return other.x == this.x && other.y == this.y;
}
return false;
};
return Vector2;
}());
es.Vector2 = Vector2;
})(es || (es = {}));
var es;
(function (es) {
var Vector3 = /** @class */ (function () {
function Vector3(x, y, z) {
this.x = x;
this.y = y;
this.z = z;
}
return Vector3;
}());
es.Vector3 = Vector3;
})(es || (es = {}));
var es;
(function (es) {
/**
* 移动器使用的帮助器类,用于管理触发器碰撞器交互并调用itriggerlistener
*/
var ColliderTriggerHelper = /** @class */ (function () {
function ColliderTriggerHelper(entity) {
/** 存储当前帧中发生的所有活动交点对 */
this._activeTriggerIntersections = new Set();
/** 存储前一帧的交点对,这样我们就可以在移动这一帧后检测到退出 */
this._previousTriggerIntersections = new Set();
this._tempTriggerList = [];
this._entity = entity;
}
/**
* update应该在实体被移动后被调用,它将处理任何与Colllider重叠的ITriggerListeners。
* 它将处理任何与Collider重叠的ITriggerListeners。
*/
ColliderTriggerHelper.prototype.update = function () {
// 对所有实体.colliders进行重叠检查,这些实体.colliders是触发器,与所有宽相碰撞器,无论是否触发器。
// 任何重叠都会导致触发事件
var colliders = this._entity.getComponents(es.Collider);
for (var i = 0; i < colliders.length; i++) {
var collider = colliders[i];
var neighbors = es.Physics.boxcastBroadphase(collider.bounds, collider.collidesWithLayers);
for (var j = 0; j < neighbors.size; j++) {
var neighbor = neighbors[j];
// 我们至少需要一个碰撞器作为触发器
if (!collider.isTrigger && !neighbor.isTrigger)
continue;
if (collider.overlaps(neighbor)) {
var pair = new es.Pair(collider, neighbor);
// 如果我们的某一个集合中已经有了这个对子(前一个或当前的触发交叉点),就不要调用输入事件了
var shouldReportTriggerEvent = !this._activeTriggerIntersections.has(pair) &&
!this._previousTriggerIntersections.has(pair);
if (shouldReportTriggerEvent)
this.notifyTriggerListeners(pair, true);
this._activeTriggerIntersections.add(pair);
}
}
}
es.ListPool.free(colliders);
this.checkForExitedColliders();
};
ColliderTriggerHelper.prototype.checkForExitedColliders = function () {
// 删除所有与此帧交互的触发器,留下我们退出的触发器
this.excepthWith(this._previousTriggerIntersections, this._activeTriggerIntersections);
for (var i = 0; i < this._previousTriggerIntersections.size; i++) {
this.notifyTriggerListeners(this._previousTriggerIntersections[i], false);
}
this._previousTriggerIntersections.clear();
// 添加所有当前激活的触发器
this.unionWith(this._previousTriggerIntersections, this._activeTriggerIntersections);
// 清空活动集,为下一帧做准备
this._activeTriggerIntersections.clear();
};
ColliderTriggerHelper.prototype.excepthWith = function (previous, active) {
for (var i = 0; i < previous.size; i++) {
var previousDATA = previous[i];
for (var j = 0; j < active.size; j++) {
var activeDATA = active[j];
if (activeDATA.equals(previousDATA))
previous.delete(previousDATA);
}
}
};
ColliderTriggerHelper.prototype.unionWith = function (previous, active) {
for (var i = 0; i < this._activeTriggerIntersections.size; i++) {
if (!this._previousTriggerIntersections.has(this._activeTriggerIntersections[i]))
this._previousTriggerIntersections.add(this._activeTriggerIntersections[i]);
}
};
ColliderTriggerHelper.prototype.notifyTriggerListeners = function (collisionPair, isEntering) {
es.TriggerListenerHelper.getITriggerListener(collisionPair.first.entity, this._tempTriggerList);
for (var i = 0; i < this._tempTriggerList.length; i++) {
if (isEntering) {
this._tempTriggerList[i].onTriggerEnter(collisionPair.second, collisionPair.first);
}
else {
this._tempTriggerList[i].onTriggerExit(collisionPair.second, collisionPair.first);
}
this._tempTriggerList.length = 0;
if (collisionPair.second.entity) {
es.TriggerListenerHelper.getITriggerListener(collisionPair.second.entity, this._tempTriggerList);
for (var i_2 = 0; i_2 < this._tempTriggerList.length; i_2++) {
if (isEntering) {
this._tempTriggerList[i_2].onTriggerEnter(collisionPair.first, collisionPair.second);
}
else {
this._tempTriggerList[i_2].onTriggerExit(collisionPair.first, collisionPair.second);
}
}
this._tempTriggerList.length = 0;
}
}
};
return ColliderTriggerHelper;
}());
es.ColliderTriggerHelper = ColliderTriggerHelper;
})(es || (es = {}));
var es;
(function (es) {
var PointSectors;
(function (PointSectors) {
PointSectors[PointSectors["center"] = 0] = "center";
PointSectors[PointSectors["top"] = 1] = "top";
PointSectors[PointSectors["bottom"] = 2] = "bottom";
PointSectors[PointSectors["topLeft"] = 9] = "topLeft";
PointSectors[PointSectors["topRight"] = 5] = "topRight";
PointSectors[PointSectors["left"] = 8] = "left";
PointSectors[PointSectors["right"] = 4] = "right";
PointSectors[PointSectors["bottomLeft"] = 10] = "bottomLeft";
PointSectors[PointSectors["bottomRight"] = 6] = "bottomRight";
})(PointSectors = es.PointSectors || (es.PointSectors = {}));
var Collisions = /** @class */ (function () {
function Collisions() {
}
Collisions.isLineToLine = function (a1, a2, b1, b2) {
var b = es.Vector2.subtract(a2, a1);
var d = es.Vector2.subtract(b2, b1);
var bDotDPerp = b.x * d.y - b.y * d.x;
// 如果b*d = 0,表示这两条直线平行,因此有无穷个交点
if (bDotDPerp == 0)
return false;
var c = es.Vector2.subtract(b1, a1);
var t = (c.x * d.y - c.y * d.x) / bDotDPerp;
if (t < 0 || t > 1)
return false;
var u = (c.x * b.y - c.y * b.x) / bDotDPerp;
if (u < 0 || u > 1)
return false;
return true;
};
Collisions.lineToLineIntersection = function (a1, a2, b1, b2) {
var intersection = new es.Vector2(0, 0);
var b = es.Vector2.subtract(a2, a1);
var d = es.Vector2.subtract(b2, b1);
var bDotDPerp = b.x * d.y - b.y * d.x;
// 如果b*d = 0,表示这两条直线平行,因此有无穷个交点
if (bDotDPerp == 0)
return intersection;
var c = es.Vector2.subtract(b1, a1);
var t = (c.x * d.y - c.y * d.x) / bDotDPerp;
if (t < 0 || t > 1)
return intersection;
var u = (c.x * b.y - c.y * b.x) / bDotDPerp;
if (u < 0 || u > 1)
return intersection;
intersection = es.Vector2.add(a1, new es.Vector2(t * b.x, t * b.y));
return intersection;
};
Collisions.closestPointOnLine = function (lineA, lineB, closestTo) {
var v = es.Vector2.subtract(lineB, lineA);
var w = es.Vector2.subtract(closestTo, lineA);
var t = es.Vector2.dot(w, v) / es.Vector2.dot(v, v);
t = es.MathHelper.clamp(t, 0, 1);
return es.Vector2.add(lineA, new es.Vector2(v.x * t, v.y * t));
};
Collisions.circleToCircle = function (circleCenter1, circleRadius1, circleCenter2, circleRadius2) {
return es.Vector2.distanceSquared(circleCenter1, circleCenter2) < (circleRadius1 + circleRadius2) * (circleRadius1 + circleRadius2);
};
Collisions.circleToLine = function (circleCenter, radius, lineFrom, lineTo) {
return es.Vector2.distanceSquared(circleCenter, this.closestPointOnLine(lineFrom, lineTo, circleCenter)) < radius * radius;
};
Collisions.circleToPoint = function (circleCenter, radius, point) {
return es.Vector2.distanceSquared(circleCenter, point) < radius * radius;
};
Collisions.rectToCircle = function (rect, cPosition, cRadius) {
if (this.rectToPoint(rect.x, rect.y, rect.width, rect.height, cPosition))
return true;
var edgeFrom = es.Vector2.zero;
var edgeTo = es.Vector2.zero;
var sector = this.getSector(rect.x, rect.y, rect.width, rect.height, cPosition);
if ((sector & PointSectors.top) != 0) {
edgeFrom = new es.Vector2(rect.x, rect.y);
edgeTo = new es.Vector2(rect.x + rect.width, rect.y);
if (this.circleToLine(cPosition, cRadius, edgeFrom, edgeTo))
return true;
}
if ((sector & PointSectors.bottom) != 0) {
edgeFrom = new es.Vector2(rect.x, rect.y + rect.width);
edgeTo = new es.Vector2(rect.x + rect.width, rect.y + rect.height);
if (this.circleToLine(cPosition, cRadius, edgeFrom, edgeTo))
return true;
}
if ((sector & PointSectors.left) != 0) {
edgeFrom = new es.Vector2(rect.x + rect.width, rect.y);
edgeTo = new es.Vector2(rect.x + rect.width, rect.y + rect.height);
if (this.circleToLine(cPosition, cRadius, edgeFrom, edgeTo))
return true;
}
return false;
};
Collisions.rectToLine = function (rect, lineFrom, lineTo) {
var fromSector = this.getSector(rect.x, rect.y, rect.width, rect.height, lineFrom);
var toSector = this.getSector(rect.x, rect.y, rect.width, rect.height, lineTo);
if (fromSector == PointSectors.center || toSector == PointSectors.center) {
return true;
}
else if ((fromSector & toSector) != 0) {
return false;
}
else {
var both = fromSector | toSector;
// 线对边进行检查
var edgeFrom = void 0;
var edgeTo = void 0;
if ((both & PointSectors.top) != 0) {
edgeFrom = new es.Vector2(rect.x, rect.y);
edgeTo = new es.Vector2(rect.x + rect.width, rect.y);
if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo))
return true;
}
if ((both & PointSectors.bottom) != 0) {
edgeFrom = new es.Vector2(rect.x, rect.y + rect.height);
edgeTo = new es.Vector2(rect.x + rect.width, rect.y + rect.height);
if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo))
return true;
}
if ((both & PointSectors.left) != 0) {
edgeFrom = new es.Vector2(rect.x, rect.y);
edgeTo = new es.Vector2(rect.x, rect.y + rect.height);
if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo))
return true;
}
if ((both & PointSectors.right) != 0) {
edgeFrom = new es.Vector2(rect.x + rect.width, rect.y);
edgeTo = new es.Vector2(rect.x + rect.width, rect.y + rect.height);
if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo))
return true;
}
}
return false;
};
Collisions.rectToPoint = function (rX, rY, rW, rH, point) {
return point.x >= rX && point.y >= rY && point.x < rX + rW && point.y < rY + rH;
};
/**
* 位标志和帮助使用Cohen–Sutherland算法
*
* 位标志:
* 1001 1000 1010
* 0001 0000 0010
* 0101 0100 0110
* @param rX
* @param rY
* @param rW
* @param rH
* @param point
*/
Collisions.getSector = function (rX, rY, rW, rH, point) {
var sector = PointSectors.center;
if (point.x < rX)
sector |= PointSectors.left;
else if (point.x >= rX + rW)
sector |= PointSectors.right;
if (point.y < rY)
sector |= PointSectors.top;
else if (point.y >= rY + rH)
sector |= PointSectors.bottom;
return sector;
};
return Collisions;
}());
es.Collisions = Collisions;
})(es || (es = {}));
var es;
(function (es) {
var RaycastHit = /** @class */ (function () {
function RaycastHit(collider, fraction, distance, point, normal) {
/**
* 撞击发生时沿射线的距离。
*/
this.fraction = 0;
/**
* 从射线原点到碰撞点的距离
*/
this.distance = 0;
/**
* 世界空间中光线击中对撞机表面的点
*/
this.point = es.Vector2.zero;
/**
* 被射线击中的表面的法向量
*/
this.normal = es.Vector2.zero;
this.collider = collider;
this.fraction = fraction;
this.distance = distance;
this.point = point;
this.centroid = es.Vector2.zero;
}
RaycastHit.prototype.setValues = function (collider, fraction, distance, point) {
this.collider = collider;
this.fraction = fraction;
this.distance = distance;
this.point = point;
};
RaycastHit.prototype.setValuesNonCollider = function (fraction, distance, point, normal) {
this.fraction = fraction;
this.distance = distance;
this.point = point;
this.normal = normal;
};
RaycastHit.prototype.reset = function () {
this.collider = null;
this.fraction = this.distance = 0;
};
RaycastHit.prototype.toString = function () {
return "[RaycastHit] fraction: " + this.fraction + ", distance: " + this.distance + ", normal: " + this.normal + ", centroid: " + this.centroid + ", point: " + this.point;
};
return RaycastHit;
}());
es.RaycastHit = RaycastHit;
})(es || (es = {}));
///
* this.sample([1, 2, 3, 4, 5], 3) // Choose 3 elements
* [4, 1, 5]
*
* @param sequence
* @param num
* @return
*
*/
RandomUtils.sample = function (sequence, num) {
var len = sequence.length;
if (num <= 0 || len < num)
throw new Error("采样数量不够");
var selected = [];
var indices = [];
for (var i = 0; i < num; i++) {
var index = Math.floor(this.random() * len);
while (indices.indexOf(index) >= 0)
index = Math.floor(this.random() * len);
selected.push(sequence[index]);
indices.push(index);
}
return selected;
};
/**
* 返回 0.0 - 1.0 之间的随机数,等同于 Math.random()
* @return Math.random()
*
*/
RandomUtils.random = function () {
return Math.random();
};
/**
* 计算概率
* @param chance 概率
* @return
*/
RandomUtils.boolean = function (chance) {
if (chance === void 0) { chance = .5; }
return (this.random() < chance) ? true : false;
};
RandomUtils._randomCompare = function (a, b) {
return (this.random() > .5) ? 1 : -1;
};
return RandomUtils;
}());
var es;
(function (es) {
var RectangleExt = /** @class */ (function () {
function RectangleExt() {
}
/**
* 获取指定边的位置
* @param rect
* @param edge
*/
RectangleExt.getSide = function (rect, edge) {
switch (edge) {
case es.Edge.top:
return rect.top;
case es.Edge.bottom:
return rect.bottom;
case es.Edge.left:
return rect.left;
case es.Edge.right:
return rect.right;
}
};
/**
* 计算两个矩形的并集。结果将是一个包含其他两个的矩形。
* @param first
* @param point
*/
RectangleExt.union = function (first, point) {
var rect = new es.Rectangle(point.x, point.y, 0, 0);
var result = new es.Rectangle();
result.x = Math.min(first.x, rect.x);
result.y = Math.min(first.y, rect.y);
result.width = Math.max(first.right, rect.right) - result.x;
result.height = Math.max(first.bottom, result.bottom) - result.y;
return result;
};
RectangleExt.getHalfRect = function (rect, edge) {
switch (edge) {
case es.Edge.top:
return new es.Rectangle(rect.x, rect.y, rect.width, rect.height / 2);
case es.Edge.bottom:
return new es.Rectangle(rect.x, rect.y + rect.height / 2, rect.width, rect.height / 2);
case es.Edge.left:
return new es.Rectangle(rect.x, rect.y, rect.width / 2, rect.height);
case es.Edge.right:
return new es.Rectangle(rect.x + rect.width / 2, rect.y, rect.width / 2, rect.height);
}
};
/**
* 获取矩形的一部分,其宽度/高度的大小位于矩形的边缘,但仍然包含在其中。
* @param rect
* @param edge
* @param size
*/
RectangleExt.getRectEdgePortion = function (rect, edge, size) {
if (size === void 0) { size = 1; }
switch (edge) {
case es.Edge.top:
return new es.Rectangle(rect.x, rect.y, rect.width, size);
case es.Edge.bottom:
return new es.Rectangle(rect.x, rect.y + rect.height - size, rect.width, size);
case es.Edge.left:
return new es.Rectangle(rect.x, rect.y, size, rect.height);
case es.Edge.right:
return new es.Rectangle(rect.x + rect.width - size, rect.y, size, rect.height);
}
};
RectangleExt.expandSide = function (rect, edge, amount) {
amount = Math.abs(amount);
switch (edge) {
case es.Edge.top:
rect.y -= amount;
rect.height += amount;
break;
case es.Edge.bottom:
rect.height += amount;
break;
case es.Edge.left:
rect.x -= amount;
rect.width += amount;
break;
case es.Edge.right:
rect.width += amount;
break;
}
};
RectangleExt.contract = function (rect, horizontalAmount, verticalAmount) {
rect.x += horizontalAmount;
rect.y += verticalAmount;
rect.width -= horizontalAmount * 2;
rect.height -= verticalAmount * 2;
};
return RectangleExt;
}());
es.RectangleExt = RectangleExt;
})(es || (es = {}));
var es;
(function (es) {
/**
* 使得number/string/boolean类型作为对象引用来进行传递
*/
var Ref = /** @class */ (function () {
function Ref(value) {
this.value = value;
}
return Ref;
}());
es.Ref = Ref;
})(es || (es = {}));
var es;
(function (es) {
/**
* 管理数值的简单助手类。它存储值,直到累计的总数大于1。一旦超过1,该值将在调用update时添加到amount中。
*/
var SubpixelNumber = /** @class */ (function () {
function SubpixelNumber() {
}
/**
* 以amount递增余数,将值截断为int,存储新的余数并将amount设置为当前值。
* @param amount
*/
SubpixelNumber.prototype.update = function (amount) {
this.remainder += amount;
var motion = Math.trunc(this.remainder);
this.remainder -= motion;
return motion;
};
/**
* 将余数重置为0。当一个物体与一个不可移动的物体碰撞时有用。
* 在这种情况下,您将希望将亚像素余数归零,因为它是空的和无效的碰撞。
*/
SubpixelNumber.prototype.reset = function () {
this.remainder = 0;
};
return SubpixelNumber;
}());
es.SubpixelNumber = SubpixelNumber;
})(es || (es = {}));
var es;
(function (es) {
/**
* 三角剖分
*/
var Triangulator = /** @class */ (function () {
function Triangulator() {
/**
* 最后一次三角调用中使用的点列表的三角形列表项的索引
*/
this.triangleIndices = [];
this._triPrev = new Array(12);
this._triNext = new Array(12);
}
Triangulator.testPointTriangle = function (point, a, b, c) {
if (es.Vector2Ext.cross(es.Vector2.subtract(point, a), es.Vector2.subtract(b, a)) < 0)
return false;
if (es.Vector2Ext.cross(es.Vector2.subtract(point, b), es.Vector2.subtract(c, b)) < 0)
return false;
if (es.Vector2Ext.cross(es.Vector2.subtract(point, c), es.Vector2.subtract(a, c)) < 0)
return false;
return true;
};
/**
* 计算一个三角形列表,该列表完全覆盖给定点集所包含的区域。如果点不是CCW,则将arePointsCCW参数传递为false
* @param points 定义封闭路径的点列表
* @param arePointsCCW
*/
Triangulator.prototype.triangulate = function (points, arePointsCCW) {
if (arePointsCCW === void 0) { arePointsCCW = true; }
var count = points.length;
// 设置前一个链接和下一个链接
this.initialize(count);
// 非三角的多边形断路器
var iterations = 0;
// 从0开始
var index = 0;
// 继续移除所有的三角形,直到只剩下一个三角形
while (count > 3 && iterations < 500) {
iterations++;
var isEar = true;
var a = points[this._triPrev[index]];
var b = points[index];
var c = points[this._triNext[index]];
if (es.Vector2Ext.isTriangleCCW(a, b, c)) {
var k = this._triNext[this._triNext[index]];
do {
if (Triangulator.testPointTriangle(points[k], a, b, c)) {
isEar = false;
break;
}
k = this._triNext[k];
} while (k != this._triPrev[index]);
}
else {
isEar = false;
}
if (isEar) {
this.triangleIndices.push(this._triPrev[index]);
this.triangleIndices.push(index);
this.triangleIndices.push(this._triNext[index]);
// 删除vert通过重定向相邻vert的上一个和下一个链接,从而减少vertext计数
this._triNext[this._triPrev[index]] = this._triNext[index];
this._triPrev[this._triNext[index]] = this._triPrev[index];
count--;
// 接下来访问前一个vert
index = this._triPrev[index];
}
else {
index = this._triNext[index];
}
}
this.triangleIndices.push(this._triPrev[index]);
this.triangleIndices.push(index);
this.triangleIndices.push(this._triNext[index]);
if (!arePointsCCW)
this.triangleIndices.reverse();
};
Triangulator.prototype.initialize = function (count) {
this.triangleIndices.length = 0;
if (this._triNext.length < count) {
this._triNext.reverse();
this._triNext = new Array(Math.max(this._triNext.length * 2, count));
}
if (this._triPrev.length < count) {
this._triPrev.reverse();
this._triPrev = new Array(Math.max(this._triPrev.length * 2, count));
}
for (var i = 0; i < count; i++) {
this._triPrev[i] = i - 1;
this._triNext[i] = i + 1;
}
this._triPrev[0] = count - 1;
this._triNext[count - 1] = 0;
};
return Triangulator;
}());
es.Triangulator = Triangulator;
})(es || (es = {}));
var es;
(function (es) {
var TypeUtils = /** @class */ (function () {
function TypeUtils() {
}
TypeUtils.getType = function (obj) {
return obj["__proto__"]["constructor"];
};
return TypeUtils;
}());
es.TypeUtils = TypeUtils;
})(es || (es = {}));
var es;
(function (es) {
var Vector2Ext = /** @class */ (function () {
function Vector2Ext() {
}
/**
* 检查三角形是CCW还是CW
* @param a
* @param center
* @param c
*/
Vector2Ext.isTriangleCCW = function (a, center, c) {
return this.cross(es.Vector2.subtract(center, a), es.Vector2.subtract(c, center)) < 0;
};
Vector2Ext.halfVector = function () {
return new es.Vector2(0.5, 0.5);
};
/**
* 计算二维伪叉乘点(Perp(u), v)
* @param u
* @param v
*/
Vector2Ext.cross = function (u, v) {
return u.y * v.x - u.x * v.y;
};
/**
* 返回与传入向量垂直的向量
* @param first
* @param second
*/
Vector2Ext.perpendicular = function (first, second) {
return new es.Vector2(-1 * (second.y - first.y), second.x - first.x);
};
/**
* Vector2的临时解决方案
* 标准化把向量弄乱了
* @param vec
*/
Vector2Ext.normalize = function (vec) {
var magnitude = Math.sqrt((vec.x * vec.x) + (vec.y * vec.y));
if (magnitude > es.MathHelper.Epsilon) {
vec.divide(new es.Vector2(magnitude));
}
else {
vec.x = vec.y = 0;
}
};
/**
* 通过指定的矩阵对Vector2的数组中的向量应用变换,并将结果放置在另一个数组中。
* @param sourceArray
* @param sourceIndex
* @param matrix
* @param destinationArray
* @param destinationIndex
* @param length
*/
Vector2Ext.transformA = function (sourceArray, sourceIndex, matrix, destinationArray, destinationIndex, length) {
for (var i = 0; i < length; i++) {
var position = sourceArray[sourceIndex + i];
var destination = destinationArray[destinationIndex + i];
destination.x = (position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m31;
destination.y = (position.x * matrix.m12) + (position.y * matrix.m22) + matrix.m32;
destinationArray[destinationIndex + i] = destination;
}
};
Vector2Ext.transformR = function (position, matrix, result) {
var x = (position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m31;
var y = (position.x * matrix.m12) + (position.y * matrix.m22) + matrix.m32;
result.x = x;
result.y = y;
};
/**
* 通过指定的矩阵对Vector2的数组中的所有向量应用变换,并将结果放到另一个数组中。
* @param sourceArray
* @param matrix
* @param destinationArray
*/
Vector2Ext.transform = function (sourceArray, matrix, destinationArray) {
this.transformA(sourceArray, 0, matrix, destinationArray, 0, sourceArray.length);
};
Vector2Ext.round = function (vec) {
return new es.Vector2(Math.round(vec.x), Math.round(vec.y));
};
return Vector2Ext;
}());
es.Vector2Ext = Vector2Ext;
})(es || (es = {}));
var WebGLUtils = /** @class */ (function () {
function WebGLUtils() {
}
/**
* 获取webgl context
*/
WebGLUtils.getContext = function () {
var canvas = document.getElementsByTagName('canvas')[0];
return canvas.getContext('2d');
};
return WebGLUtils;
}());
var stopwatch;
(function (stopwatch) {
/**
* 记录时间的持续时间,一些设计灵感来自物理秒表。
*/
var Stopwatch = /** @class */ (function () {
function Stopwatch(getSystemTime) {
if (getSystemTime === void 0) { getSystemTime = _defaultSystemTimeGetter; }
this.getSystemTime = getSystemTime;
/** 自上次复位以来,秒表已停止的系统时间总数。 */
this._stopDuration = 0;
/**
* 记录自上次复位以来所有已完成切片的结果。
*/
this._completeSlices = [];
}
Stopwatch.prototype.getState = function () {
if (this._startSystemTime === undefined) {
return State.IDLE;
}
else if (this._stopSystemTime === undefined) {
return State.RUNNING;
}
else {
return State.STOPPED;
}
};
Stopwatch.prototype.isIdle = function () {
return this.getState() === State.IDLE;
};
Stopwatch.prototype.isRunning = function () {
return this.getState() === State.RUNNING;
};
Stopwatch.prototype.isStopped = function () {
return this.getState() === State.STOPPED;
};
/**
*
*/
Stopwatch.prototype.slice = function () {
return this.recordPendingSlice();
};
/**
* 获取自上次复位以来该秒表已完成/记录的所有片的列表。
*/
Stopwatch.prototype.getCompletedSlices = function () {
return Array.from(this._completeSlices);
};
/**
* 获取自上次重置以来该秒表已完成/记录的所有片的列表,以及当前挂起的片。
*/
Stopwatch.prototype.getCompletedAndPendingSlices = function () {
return this._completeSlices.concat([this.getPendingSlice()]);
};
/**
* 获取关于这个秒表当前挂起的切片的详细信息。
*/
Stopwatch.prototype.getPendingSlice = function () {
return this.calculatePendingSlice();
};
/**
* 获取当前秒表时间。这是这个秒表自上次复位以来运行的系统时间总数。
*/
Stopwatch.prototype.getTime = function () {
return this.caculateStopwatchTime();
};
/**
* 完全重置这个秒表到它的初始状态。清除所有记录的运行持续时间、切片等。
*/
Stopwatch.prototype.reset = function () {
this._startSystemTime = this._pendingSliceStartStopwatchTime = this._stopSystemTime = undefined;
this._stopDuration = 0;
this._completeSlices = [];
};
/**
* 开始(或继续)运行秒表。
* @param forceReset
*/
Stopwatch.prototype.start = function (forceReset) {
if (forceReset === void 0) { forceReset = false; }
if (forceReset) {
this.reset();
}
if (this._stopSystemTime !== undefined) {
var systemNow = this.getSystemTime();
var stopDuration = systemNow - this._stopSystemTime;
this._stopDuration += stopDuration;
this._stopSystemTime = undefined;
}
else if (this._startSystemTime === undefined) {
var systemNow = this.getSystemTime();
this._startSystemTime = systemNow;
this._pendingSliceStartStopwatchTime = 0;
}
};
/**
*
* @param recordPendingSlice
*/
Stopwatch.prototype.stop = function (recordPendingSlice) {
if (recordPendingSlice === void 0) { recordPendingSlice = false; }
if (this._startSystemTime === undefined) {
return 0;
}
var systemTimeOfStopwatchTime = this.getSystemTimeOfCurrentStopwatchTime();
if (recordPendingSlice) {
this.recordPendingSlice(this.caculateStopwatchTime(systemTimeOfStopwatchTime));
}
this._stopSystemTime = systemTimeOfStopwatchTime;
return this.getTime();
};
/**
* 计算指定秒表时间的当前挂起片。
* @param endStopwatchTime
*/
Stopwatch.prototype.calculatePendingSlice = function (endStopwatchTime) {
if (this._pendingSliceStartStopwatchTime === undefined) {
return Object.freeze({ startTime: 0, endTime: 0, duration: 0 });
}
if (endStopwatchTime === undefined) {
endStopwatchTime = this.getTime();
}
return Object.freeze({
startTime: this._pendingSliceStartStopwatchTime,
endTime: endStopwatchTime,
duration: endStopwatchTime - this._pendingSliceStartStopwatchTime
});
};
/**
* 计算指定系统时间的当前秒表时间。
* @param endSystemTime
*/
Stopwatch.prototype.caculateStopwatchTime = function (endSystemTime) {
if (this._startSystemTime === undefined)
return 0;
if (endSystemTime === undefined)
endSystemTime = this.getSystemTimeOfCurrentStopwatchTime();
return endSystemTime - this._startSystemTime - this._stopDuration;
};
/**
* 获取与当前秒表时间等效的系统时间。
* 如果该秒表当前停止,则返回该秒表停止时的系统时间。
*/
Stopwatch.prototype.getSystemTimeOfCurrentStopwatchTime = function () {
return this._stopSystemTime === undefined ? this.getSystemTime() : this._stopSystemTime;
};
/**
* 结束/记录当前挂起的片的私有实现。
* @param endStopwatchTime
*/
Stopwatch.prototype.recordPendingSlice = function (endStopwatchTime) {
if (this._pendingSliceStartStopwatchTime !== undefined) {
if (endStopwatchTime === undefined) {
endStopwatchTime = this.getTime();
}
var slice = this.calculatePendingSlice(endStopwatchTime);
this._pendingSliceStartStopwatchTime = slice.endTime;
this._completeSlices.push(slice);
return slice;
}
else {
return this.calculatePendingSlice();
}
};
return Stopwatch;
}());
stopwatch.Stopwatch = Stopwatch;
var State;
(function (State) {
/** 秒表尚未启动,或已复位。 */
State["IDLE"] = "IDLE";
/** 秒表正在运行。 */
State["RUNNING"] = "RUNNING";
/** 秒表以前还在跑,但现在已经停了。 */
State["STOPPED"] = "STOPPED";
})(State || (State = {}));
function setDefaultSystemTimeGetter(systemTimeGetter) {
if (systemTimeGetter === void 0) { systemTimeGetter = Date.now; }
_defaultSystemTimeGetter = systemTimeGetter;
}
stopwatch.setDefaultSystemTimeGetter = setDefaultSystemTimeGetter;
/** 所有新实例的默认“getSystemTime”实现 */
var _defaultSystemTimeGetter = Date.now;
})(stopwatch || (stopwatch = {}));
var es;
(function (es) {
var Timer = /** @class */ (function () {
function Timer() {
this._timeInSeconds = 0;
this._repeats = false;
this._isDone = false;
this._elapsedTime = 0;
}
Timer.prototype.getContext = function () {
return this.context;
};
Timer.prototype.reset = function () {
this._elapsedTime = 0;
};
Timer.prototype.stop = function () {
this._isDone = true;
};
Timer.prototype.tick = function () {
// 如果stop在tick之前被调用,那么isDone将为true,我们不应该再做任何事情
if (!this._isDone && this._elapsedTime > this._timeInSeconds) {
this._elapsedTime -= this._timeInSeconds;
this._onTime(this);
if (!this._isDone && !this._repeats)
this._isDone = true;
}
this._elapsedTime += es.Time.deltaTime;
return this._isDone;
};
Timer.prototype.initialize = function (timeInsSeconds, repeats, context, onTime) {
this._timeInSeconds = timeInsSeconds;
this._repeats = repeats;
this.context = context;
this._onTime = onTime;
};
/**
* 空出对象引用,以便在js需要时GC可以清理它们的引用
*/
Timer.prototype.unload = function () {
this.context = null;
this._onTime = null;
};
return Timer;
}());
es.Timer = Timer;
})(es || (es = {}));
var es;
(function (es) {
/**
* 允许动作的延迟和重复执行
*/
var TimerManager = /** @class */ (function (_super) {
__extends(TimerManager, _super);
function TimerManager() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this._timers = [];
return _this;
}
TimerManager.prototype.update = function () {
for (var i = this._timers.length - 1; i >= 0; i--) {
if (this._timers[i].tick()) {
this._timers[i].unload();
this._timers.removeAt(i);
}
}
};
/**
* 调度一个一次性或重复的计时器,该计时器将调用已传递的动作
* @param timeInSeconds
* @param repeats
* @param context
* @param onTime
*/
TimerManager.prototype.schedule = function (timeInSeconds, repeats, context, onTime) {
var timer = new es.Timer();
timer.initialize(timeInSeconds, repeats, context, onTime);
this._timers.push(timer);
return timer;
};
return TimerManager;
}(es.GlobalManager));
es.TimerManager = TimerManager;
})(es || (es = {}));