From 59c8d456cbe729abec03fef13ec13ecbbf2472e6 Mon Sep 17 00:00:00 2001 From: yhh <359807859@qq.com> Date: Thu, 10 Dec 2020 16:15:19 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=AD=90=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E4=B8=8E=E6=96=87=E4=BB=B6=E8=BF=81=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitmodules | 6 + demo/egret_demo | 1 + demo/laya_demo | 1 + source/bin/framework.d.ts | 1241 +++---- source/bin/framework.js | 2989 +++++++++-------- source/bin/framework.min.js | 2 +- source/gulpfile.js | 15 +- source/package-lock.json | 6 + source/package.json | 3 +- source/src/ECS/Core.ts | 2 +- source/src/ECS/Transform.ts | 2 +- .../Shapes/ShapeCollisions/ShapeCollisions.ts | 28 +- .../Utils => Utils/Collections}/FastList.ts | 0 .../Collections/FasterDictionary.ts} | 0 .../src/Utils/{ => Collections}/LinkList.ts | 0 .../src/Utils/{ => Collections}/ListPool.ts | 0 source/src/Utils/{ => Collections}/Pair.ts | 0 source/src/Utils/{ => Collections}/Pool.ts | 0 source/src/Utils/{ => Collections}/Set.ts | 0 .../src/Utils/{ => Extensions}/ArrayUtils.ts | 592 ++-- .../src/Utils/{ => Extensions}/Base64Utils.ts | 268 +- source/src/Utils/{ => Extensions}/EdgeExt.ts | 0 .../Utils/{ => Extensions}/NumberExtension.ts | 0 .../src/Utils/{ => Extensions}/RandomUtils.ts | 264 +- source/src/Utils/Extensions/RectangleExt.ts | 220 ++ .../src/Utils/{ => Extensions}/TypeUtils.ts | 0 .../src/Utils/{ => Extensions}/Vector2Ext.ts | 0 .../src/Utils/{ => Extensions}/WebGLUtils.ts | 16 +- .../Utils/PolygonLight/VisibilityComputer.ts | 2 +- source/src/Utils/RectangleExt.ts | 96 - 30 files changed, 3028 insertions(+), 2726 deletions(-) create mode 100644 .gitmodules create mode 160000 demo/egret_demo create mode 160000 demo/laya_demo rename source/src/{ECS/Utils => Utils/Collections}/FastList.ts (100%) rename source/src/{ECS/Utils/FastDirectory.ts => Utils/Collections/FasterDictionary.ts} (100%) rename source/src/Utils/{ => Collections}/LinkList.ts (100%) rename source/src/Utils/{ => Collections}/ListPool.ts (100%) rename source/src/Utils/{ => Collections}/Pair.ts (100%) rename source/src/Utils/{ => Collections}/Pool.ts (100%) rename source/src/Utils/{ => Collections}/Set.ts (100%) rename source/src/Utils/{ => Extensions}/ArrayUtils.ts (96%) rename source/src/Utils/{ => Extensions}/Base64Utils.ts (97%) rename source/src/Utils/{ => Extensions}/EdgeExt.ts (100%) rename source/src/Utils/{ => Extensions}/NumberExtension.ts (100%) rename source/src/Utils/{ => Extensions}/RandomUtils.ts (96%) create mode 100644 source/src/Utils/Extensions/RectangleExt.ts rename source/src/Utils/{ => Extensions}/TypeUtils.ts (100%) rename source/src/Utils/{ => Extensions}/Vector2Ext.ts (100%) rename source/src/Utils/{ => Extensions}/WebGLUtils.ts (96%) delete mode 100644 source/src/Utils/RectangleExt.ts diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..004a2057 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "demo/egret_demo"] + path = demo/egret_demo + url = https://github.com/esengine/ecs-egret-demo +[submodule "demo/laya_demo"] + path = demo/laya_demo + url = https://github.com/esengine/ecs-laya-demo.git diff --git a/demo/egret_demo b/demo/egret_demo new file mode 160000 index 00000000..b4789059 --- /dev/null +++ b/demo/egret_demo @@ -0,0 +1 @@ +Subproject commit b478905960dc0bc56f4d5dba96550900d4f9f133 diff --git a/demo/laya_demo b/demo/laya_demo new file mode 160000 index 00000000..ef025467 --- /dev/null +++ b/demo/laya_demo @@ -0,0 +1 @@ +Subproject commit ef025467dc33e38baa1177285de28e54bad2b613 diff --git a/source/bin/framework.d.ts b/source/bin/framework.d.ts index d721bf1a..ce4b4db1 100644 --- a/source/bin/framework.d.ts +++ b/source/bin/framework.d.ts @@ -1292,117 +1292,6 @@ declare module es { protected removeFromProcessors(entity: Entity): void; } } -declare module es { - /** - * 创建这个字典的原因只有一个: - * 我需要一个能让我直接以数组的形式对值进行迭代的字典,而不需要生成一个数组或使用迭代器。 - * 对于这个目标是比标准字典快N倍。 - * Faster dictionary在大部分操作上也比标准字典快,但差别可以忽略不计。 - * 唯一较慢的操作是在添加时调整内存大小,因为与标准数组相比,这个实现需要使用两个单独的数组。 - */ - class FasterDictionary { - _values: TValue[]; - _valuesInfo: FastNode[]; - _buckets: number[]; - _freeValueCellIndex: number; - _collisions: number; - constructor(size?: number); - getValuesArray(count: { - value: number; - }): TValue[]; - readonly valuesArray: TValue[]; - readonly count: number; - add(key: TKey, value: TValue): void; - addValue(key: TKey, value: TValue, indexSet: { - value: number; - }): boolean; - remove(key: TKey): boolean; - trim(): void; - clear(): void; - fastClear(): void; - containsKey(key: TKey): boolean; - tryGetValue(key: TKey): TValue; - tryFindIndex(key: TKey, findIndex: { - value: number; - }): boolean; - getDirectValue(index: number): TValue; - getIndex(key: TKey): number; - static updateLinkedList(index: number, valuesInfo: FastNode[]): void; - static hash(key: any): number; - static reduce(x: number, n: number): number; - } - class FastNode { - readonly key: any; - readonly hashcode: number; - previous: number; - next: number; - constructor(key: any, hash: number, previousNode?: number); - } -} -declare module es { - /** - * 围绕一个数组的非常基本的包装,当它达到容量时自动扩展。 - * 注意,在迭代时应该这样直接访问缓冲区,但使用FastList.length字段。 - * - * @tutorial - * for( var i = 0; i <= list.length; i++ ) - * var item = list.buffer[i]; - */ - class FastList { - /** - * 直接访问后备缓冲区。 - * 不要使用buffer.Length! 使用FastList.length - */ - buffer: T[]; - /** - * 直接访问缓冲区内填充项的长度。不要改变。 - */ - length: number; - constructor(size?: number); - /** - * 清空列表并清空缓冲区中的所有项目 - */ - clear(): void; - /** - * 和clear的工作原理一样,只是它不会将缓冲区中的所有项目清空。 - */ - reset(): void; - /** - * 将该项目添加到列表中 - * @param item - */ - add(item: T): void; - /** - * 从列表中删除该项目 - * @param item - */ - remove(item: T): void; - /** - * 从列表中删除给定索引的项目。 - * @param index - */ - removeAt(index: number): void; - /** - * 检查项目是否在FastList中 - * @param item - */ - contains(item: T): boolean; - /** - * 如果缓冲区达到最大,将分配更多的空间来容纳额外的ItemCount。 - * @param additionalItemCount - */ - ensureCapacity(additionalItemCount?: number): void; - /** - * 添加数组中的所有项目 - * @param array - */ - addRange(array: T[]): void; - /** - * 对缓冲区中的所有项目进行排序,长度不限。 - */ - sort(comparer: IComparer): void; - } -} declare module es { class HashHelpers { static readonly hashCollisionThreshold: number; @@ -2945,14 +2834,14 @@ declare module es { * @param polygon * @param result */ - static circleToPolygon(circle: Circle, polygon: Polygon, result: CollisionResult): boolean; + static circleToPolygon(circle: Circle, polygon: Polygon, result?: CollisionResult): boolean; /** - * 适用于圆心在方框内以及只与方框外圆心重叠的圆。 + * 适用于中心在框内的圆,也适用于与框外中心重合的圆。 * @param circle * @param box * @param result */ - static circleToBox(circle: Circle, box: Box, result: CollisionResult): boolean; + static circleToBox(circle: Circle, box: Box, result?: CollisionResult): boolean; /** * * @param point @@ -2981,7 +2870,7 @@ declare module es { * @param second * @param result */ - static circleToCircle(first: Circle, second: Circle, result: CollisionResult): boolean; + static circleToCircle(first: Circle, second: Circle, result?: CollisionResult): boolean; /** * * @param first @@ -2990,7 +2879,7 @@ declare module es { */ static boxToBox(first: Box, second: Box, result: CollisionResult): boolean; private static minkowskiDifference; - static lineToPoly(start: Vector2, end: Vector2, polygon: Polygon, hit: RaycastHit): boolean; + static lineToPoly(start: Vector2, end: Vector2, polygon: Polygon, hit?: RaycastHit): boolean; static lineToLine(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2, intersection: Vector2): boolean; static lineToCircle(start: Vector2, end: Vector2, s: Circle, hit: RaycastHit): boolean; /** @@ -3003,6 +2892,608 @@ declare module es { static boxToBoxCast(first: Box, second: Box, movement: Vector2, hit: RaycastHit): boolean; } } +declare module es { + /** + * 用于包装事件的一个小类 + */ + class FuncPack { + /** 函数 */ + func: Function; + /** 上下文 */ + context: any; + constructor(func: Function, context: any); + } + /** + * 用于事件管理 + */ + class Emitter { + private _messageTable; + constructor(); + /** + * 开始监听项 + * @param eventType 监听类型 + * @param handler 监听函数 + * @param context 监听上下文 + */ + addObserver(eventType: T, handler: Function, context: any): void; + /** + * 移除监听项 + * @param eventType 事件类型 + * @param handler 事件函数 + */ + removeObserver(eventType: T, handler: Function): void; + /** + * 触发该事件 + * @param eventType 事件类型 + * @param data 事件数据 + */ + emit(eventType: T, data?: any): void; + } +} +declare module es { + enum Edge { + top = 0, + bottom = 1, + left = 2, + right = 3 + } +} +declare module es { + class Enumerable { + /** + * 生成包含一个重复值的序列 + * @param element 要重复的值 + * @param count 在生成的序列中重复该值的次数 + */ + static repeat(element: T, count: number): any[]; + } +} +declare module es { + class EqualityComparer implements IEqualityComparer { + static default(): EqualityComparer; + protected constructor(); + equals(x: T, y: T): boolean; + getHashCode(o: T): number; + private _getHashCodeForNumber; + private _getHashCodeForString; + private forOwn; + } +} +declare module es { + class GlobalManager { + _enabled: boolean; + /** + * 如果true则启用了GlobalManager。 + * 状态的改变会导致调用OnEnabled/OnDisable + */ + /** + * 如果true则启用了GlobalManager。 + * 状态的改变会导致调用OnEnabled/OnDisable + * @param value + */ + enabled: boolean; + /** + * 启用/禁用这个GlobalManager + * @param isEnabled + */ + setEnabled(isEnabled: boolean): void; + /** + * 此GlobalManager启用时调用 + */ + onEnabled(): void; + /** + * 此GlobalManager禁用时调用 + */ + onDisabled(): void; + /** + * 在frame .update之前调用每一帧 + */ + update(): void; + } +} +declare module es { + interface IComparer { + compare(x: T, y: T): number; + } +} +declare module es { + /** + * 对象声明自己的平等方法和Hashcode的生成 + */ + interface IEqualityComparable { + /** + * 确定另一个对象是否等于这个实例 + * @param other + */ + equals(other: any): boolean; + /** + * 生成对象的哈希码 + */ + getHashCode(): number; + } +} +declare module es { + /** + * 为确定对象的哈希码和两个项目是否相等提供接口 + */ + interface IEqualityComparer { + /** + * 判断两个对象是否相等 + * @param x + * @param y + */ + equals(x: T, y: T): boolean; + /** + * 生成对象的哈希码 + * @param value + */ + getHashCode(value: T): number; + } +} +declare module es { + /** + * 实现该接口用于判定两个对象是否相等的快速接口 + */ + interface IEquatable { + equals(other: T): boolean; + } +} +declare module es { + /** + * 使得number/string/boolean类型作为对象引用来进行传递 + */ + class Ref { + value: T; + constructor(value: T); + } +} +declare module es { + /** + * 管理数值的简单助手类。它存储值,直到累计的总数大于1。一旦超过1,该值将在调用update时添加到amount中。 + */ + class SubpixelNumber { + remainder: number; + /** + * 以amount递增余数,将值截断为int,存储新的余数并将amount设置为当前值。 + * @param amount + */ + update(amount: number): number; + /** + * 将余数重置为0。当一个物体与一个不可移动的物体碰撞时有用。 + * 在这种情况下,您将希望将亚像素余数归零,因为它是空的和无效的碰撞。 + */ + reset(): void; + } +} +declare module es { + /** + * 简单的剪耳三角测量器,最终的三角形将出现在triangleIndices列表中。 + */ + class Triangulator { + /** + * 上次三角函数调用中使用的点列表的三角列表条目索引 + */ + triangleIndices: number[]; + private _triPrev; + private _triNext; + static testPointTriangle(point: Vector2, a: Vector2, b: Vector2, c: Vector2): boolean; + /** + * 计算一个三角形列表,该列表完全覆盖给定点集所包含的区域。如果点不是CCW,则将arePointsCCW参数传递为false + * @param points 定义封闭路径的点列表 + * @param arePointsCCW + */ + triangulate(points: Vector2[], arePointsCCW?: boolean): void; + private initialize; + } +} +declare namespace stopwatch { + /** + * 记录时间的持续时间,一些设计灵感来自物理秒表。 + */ + class Stopwatch { + private readonly getSystemTime; + /** + * 秒表启动的系统时间。 + * undefined,如果秒表尚未启动,或已复位。 + */ + private _startSystemTime; + /** + * 秒表停止的系统时间。 + * undefined,如果秒表目前没有停止,尚未开始,或已复位。 + */ + private _stopSystemTime; + /** 自上次复位以来,秒表已停止的系统时间总数。 */ + private _stopDuration; + /** + * 用秒表计时,当前等待的切片开始的时间。 + * undefined,如果秒表尚未启动,或已复位。 + */ + private _pendingSliceStartStopwatchTime; + /** + * 记录自上次复位以来所有已完成切片的结果。 + */ + private _completeSlices; + constructor(getSystemTime?: GetTimeFunc); + getState(): State; + isIdle(): boolean; + isRunning(): boolean; + isStopped(): boolean; + /** + * + */ + slice(): Slice; + /** + * 获取自上次复位以来该秒表已完成/记录的所有片的列表。 + */ + getCompletedSlices(): Slice[]; + /** + * 获取自上次重置以来该秒表已完成/记录的所有片的列表,以及当前挂起的片。 + */ + getCompletedAndPendingSlices(): Slice[]; + /** + * 获取关于这个秒表当前挂起的切片的详细信息。 + */ + getPendingSlice(): Slice; + /** + * 获取当前秒表时间。这是这个秒表自上次复位以来运行的系统时间总数。 + */ + getTime(): number; + /** + * 完全重置这个秒表到它的初始状态。清除所有记录的运行持续时间、切片等。 + */ + reset(): void; + /** + * 开始(或继续)运行秒表。 + * @param forceReset + */ + start(forceReset?: boolean): void; + /** + * + * @param recordPendingSlice + */ + stop(recordPendingSlice?: boolean): number; + /** + * 计算指定秒表时间的当前挂起片。 + * @param endStopwatchTime + */ + private calculatePendingSlice; + /** + * 计算指定系统时间的当前秒表时间。 + * @param endSystemTime + */ + private caculateStopwatchTime; + /** + * 获取与当前秒表时间等效的系统时间。 + * 如果该秒表当前停止,则返回该秒表停止时的系统时间。 + */ + private getSystemTimeOfCurrentStopwatchTime; + /** + * 结束/记录当前挂起的片的私有实现。 + * @param endStopwatchTime + */ + private recordPendingSlice; + } + /** + * 返回某个系统的“当前时间”的函数。 + * 惟一的要求是,对该函数的每次调用都必须返回一个大于或等于前一次对该函数的调用的数字。 + */ + type GetTimeFunc = () => number; + enum State { + /** 秒表尚未启动,或已复位。 */ + IDLE = "IDLE", + /** 秒表正在运行。 */ + RUNNING = "RUNNING", + /** 秒表以前还在跑,但现在已经停了。 */ + STOPPED = "STOPPED" + } + function setDefaultSystemTimeGetter(systemTimeGetter?: GetTimeFunc): void; + /** + * 由秒表记录的单个“薄片”的测量值 + */ + interface Slice { + /** 秒表显示的时间在这一片开始的时候。 */ + readonly startTime: number; + /** 秒表在这片片尾的时间。 */ + readonly endTime: number; + /** 该切片的运行时间 */ + readonly duration: number; + } +} +declare module es { + /** + * 围绕一个数组的非常基本的包装,当它达到容量时自动扩展。 + * 注意,在迭代时应该这样直接访问缓冲区,但使用FastList.length字段。 + * + * @tutorial + * for( var i = 0; i <= list.length; i++ ) + * var item = list.buffer[i]; + */ + class FastList { + /** + * 直接访问后备缓冲区。 + * 不要使用buffer.Length! 使用FastList.length + */ + buffer: T[]; + /** + * 直接访问缓冲区内填充项的长度。不要改变。 + */ + length: number; + constructor(size?: number); + /** + * 清空列表并清空缓冲区中的所有项目 + */ + clear(): void; + /** + * 和clear的工作原理一样,只是它不会将缓冲区中的所有项目清空。 + */ + reset(): void; + /** + * 将该项目添加到列表中 + * @param item + */ + add(item: T): void; + /** + * 从列表中删除该项目 + * @param item + */ + remove(item: T): void; + /** + * 从列表中删除给定索引的项目。 + * @param index + */ + removeAt(index: number): void; + /** + * 检查项目是否在FastList中 + * @param item + */ + contains(item: T): boolean; + /** + * 如果缓冲区达到最大,将分配更多的空间来容纳额外的ItemCount。 + * @param additionalItemCount + */ + ensureCapacity(additionalItemCount?: number): void; + /** + * 添加数组中的所有项目 + * @param array + */ + addRange(array: T[]): void; + /** + * 对缓冲区中的所有项目进行排序,长度不限。 + */ + sort(comparer: IComparer): void; + } +} +declare module es { + /** + * 创建这个字典的原因只有一个: + * 我需要一个能让我直接以数组的形式对值进行迭代的字典,而不需要生成一个数组或使用迭代器。 + * 对于这个目标是比标准字典快N倍。 + * Faster dictionary在大部分操作上也比标准字典快,但差别可以忽略不计。 + * 唯一较慢的操作是在添加时调整内存大小,因为与标准数组相比,这个实现需要使用两个单独的数组。 + */ + class FasterDictionary { + _values: TValue[]; + _valuesInfo: FastNode[]; + _buckets: number[]; + _freeValueCellIndex: number; + _collisions: number; + constructor(size?: number); + getValuesArray(count: { + value: number; + }): TValue[]; + readonly valuesArray: TValue[]; + readonly count: number; + add(key: TKey, value: TValue): void; + addValue(key: TKey, value: TValue, indexSet: { + value: number; + }): boolean; + remove(key: TKey): boolean; + trim(): void; + clear(): void; + fastClear(): void; + containsKey(key: TKey): boolean; + tryGetValue(key: TKey): TValue; + tryFindIndex(key: TKey, findIndex: { + value: number; + }): boolean; + getDirectValue(index: number): TValue; + getIndex(key: TKey): number; + static updateLinkedList(index: number, valuesInfo: FastNode[]): void; + static hash(key: any): number; + static reduce(x: number, n: number): number; + } + class FastNode { + readonly key: any; + readonly hashcode: number; + previous: number; + next: number; + constructor(key: any, hash: number, previousNode?: number); + } +} +declare module es { + class Node { + element: T; + next: Node; + constructor(element: T, next?: Node); + } + interface equalsFnType { + (a: T, b: T): boolean; + } + function defaultEquals(a: T, b: T): boolean; + class LinkedList { + protected count: number; + protected next: any; + protected equalsFn: equalsFnType; + protected head: Node; + constructor(equalsFn?: typeof defaultEquals); + push(element: T): void; + removeAt(index: number): T; + getElementAt(index: number): Node; + insert(element: T, index: number): boolean; + indexOf(element: T): number; + remove(element: T): void; + clear(): void; + size(): number; + isEmpty(): boolean; + getHead(): Node; + toString(): string; + } +} +declare module es { + /** + * 可以用于列表池的简单类 + */ + class ListPool { + private static readonly _objectQueue; + /** + * 预热缓存,使用最大的cacheCount对象填充缓存 + * @param cacheCount + */ + static warmCache(cacheCount: number): void; + /** + * 将缓存修剪为cacheCount项目 + * @param cacheCount + */ + static trimCache(cacheCount: any): void; + /** + * 清除缓存 + */ + static clearCache(): void; + /** + * 如果可以的话,从堆栈中弹出一个项 + */ + static obtain(): T[]; + /** + * 将项推回堆栈 + * @param obj + */ + static free(obj: Array): void; + } +} +declare module es { + /** + * 用于管理一对对象的简单DTO + */ + class Pair implements IEqualityComparable { + first: T; + second: T; + constructor(first: T, second: T); + clear(): void; + equals(other: Pair): boolean; + getHashCode(): number; + } +} +declare module es { + /** + * 用于池任何对象 + */ + class Pool { + private static _objectQueue; + /** + * 预热缓存,使用最大的cacheCount对象填充缓存 + * @param type + * @param cacheCount + */ + static warmCache(type: any, cacheCount: number): void; + /** + * 将缓存修剪为cacheCount项目 + * @param cacheCount + */ + static trimCache(cacheCount: number): void; + /** + * 清除缓存 + */ + static clearCache(): void; + /** + * 如果可以的话,从堆栈中弹出一个项 + */ + static obtain(type: any): T; + /** + * 将项推回堆栈 + * @param obj + */ + static free(obj: T): void; + } + interface IPoolable { + /** + * 重置对象以供重用。对象引用应该为空,字段可以设置为默认值 + */ + reset(): any; + } + var isIPoolable: (props: any) => props is IPoolable; +} +declare module es { + interface ISet { + add(item: T): boolean; + remove(item: T): boolean; + contains(item: T): boolean; + getCount(): number; + clear(): void; + toArray(): Array; + /** + * 从当前集合中删除指定集合中的所有元素 + * @param other + */ + exceptWith(other: Array): void; + /** + * 修改当前Set对象,使其只包含该对象和指定数组中的元素 + * @param other + */ + intersectWith(other: Array): void; + /** + * 修改当前的集合对象,使其包含所有存在于自身、指定集合中的元素,或者两者都包含 + * @param other + */ + unionWith(other: Array): void; + isSubsetOf(other: Array): boolean; + isSupersetOf(other: Array): boolean; + overlaps(other: Array): boolean; + setEquals(other: Array): boolean; + } + abstract class Set implements ISet { + protected buckets: T[][]; + protected count: number; + constructor(source?: Array); + abstract getHashCode(item: T): number; + abstract areEqual(value1: T, value2: T): boolean; + add(item: T): boolean; + remove(item: T): boolean; + contains(item: T): boolean; + getCount(): number; + clear(): void; + toArray(): T[]; + /** + * 从当前集合中删除指定集合中的所有元素 + * @param other + */ + exceptWith(other: Array): void; + /** + * 修改当前Set对象,使其只包含该对象和指定数组中的元素 + * @param other + */ + intersectWith(other: Array): void; + unionWith(other: Array): void; + /** + * 确定当前集合是否为指定集合或数组的子集 + * @param other + */ + isSubsetOf(other: Array): boolean; + /** + * 确定当前不可变排序集是否为指定集合的超集 + * @param other + */ + isSupersetOf(other: Array): boolean; + overlaps(other: Array): boolean; + setEquals(other: Array): boolean; + private buildInternalBuckets; + private bucketsContains; + } + class HashSet extends Set { + constructor(source?: Array); + getHashCode(item: T): number; + areEqual(value1: T, value2: T): boolean; + } +} declare class ArrayUtils { /** * 执行冒泡排序 @@ -3170,269 +3661,11 @@ declare module es { static isVertical(self: Edge): boolean; } } -declare module es { - /** - * 用于包装事件的一个小类 - */ - class FuncPack { - /** 函数 */ - func: Function; - /** 上下文 */ - context: any; - constructor(func: Function, context: any); - } - /** - * 用于事件管理 - */ - class Emitter { - private _messageTable; - constructor(); - /** - * 开始监听项 - * @param eventType 监听类型 - * @param handler 监听函数 - * @param context 监听上下文 - */ - addObserver(eventType: T, handler: Function, context: any): void; - /** - * 移除监听项 - * @param eventType 事件类型 - * @param handler 事件函数 - */ - removeObserver(eventType: T, handler: Function): void; - /** - * 触发该事件 - * @param eventType 事件类型 - * @param data 事件数据 - */ - emit(eventType: T, data?: any): void; - } -} -declare module es { - enum Edge { - top = 0, - bottom = 1, - left = 2, - right = 3 - } -} -declare module es { - class Enumerable { - /** - * 生成包含一个重复值的序列 - * @param element 要重复的值 - * @param count 在生成的序列中重复该值的次数 - */ - static repeat(element: T, count: number): any[]; - } -} -declare module es { - class EqualityComparer implements IEqualityComparer { - static default(): EqualityComparer; - protected constructor(); - equals(x: T, y: T): boolean; - getHashCode(o: T): number; - private _getHashCodeForNumber; - private _getHashCodeForString; - private forOwn; - } -} -declare module es { - class GlobalManager { - _enabled: boolean; - /** - * 如果true则启用了GlobalManager。 - * 状态的改变会导致调用OnEnabled/OnDisable - */ - /** - * 如果true则启用了GlobalManager。 - * 状态的改变会导致调用OnEnabled/OnDisable - * @param value - */ - enabled: boolean; - /** - * 启用/禁用这个GlobalManager - * @param isEnabled - */ - setEnabled(isEnabled: boolean): void; - /** - * 此GlobalManager启用时调用 - */ - onEnabled(): void; - /** - * 此GlobalManager禁用时调用 - */ - onDisabled(): void; - /** - * 在frame .update之前调用每一帧 - */ - update(): void; - } -} -declare module es { - interface IComparer { - compare(x: T, y: T): number; - } -} -declare module es { - /** - * 对象声明自己的平等方法和Hashcode的生成 - */ - interface IEqualityComparable { - /** - * 确定另一个对象是否等于这个实例 - * @param other - */ - equals(other: any): boolean; - /** - * 生成对象的哈希码 - */ - getHashCode(): number; - } -} -declare module es { - /** - * 为确定对象的哈希码和两个项目是否相等提供接口 - */ - interface IEqualityComparer { - /** - * 判断两个对象是否相等 - * @param x - * @param y - */ - equals(x: T, y: T): boolean; - /** - * 生成对象的哈希码 - * @param value - */ - getHashCode(value: T): number; - } -} -declare module es { - /** - * 实现该接口用于判定两个对象是否相等的快速接口 - */ - interface IEquatable { - equals(other: T): boolean; - } -} -declare module es { - class Node { - element: T; - next: Node; - constructor(element: T, next?: Node); - } - interface equalsFnType { - (a: T, b: T): boolean; - } - function defaultEquals(a: T, b: T): boolean; - class LinkedList { - protected count: number; - protected next: any; - protected equalsFn: equalsFnType; - protected head: Node; - constructor(equalsFn?: typeof defaultEquals); - push(element: T): void; - removeAt(index: number): T; - getElementAt(index: number): Node; - insert(element: T, index: number): boolean; - indexOf(element: T): number; - remove(element: T): void; - clear(): void; - size(): number; - isEmpty(): boolean; - getHead(): Node; - toString(): string; - } -} -declare module es { - /** - * 可以用于列表池的简单类 - */ - class ListPool { - private static readonly _objectQueue; - /** - * 预热缓存,使用最大的cacheCount对象填充缓存 - * @param cacheCount - */ - static warmCache(cacheCount: number): void; - /** - * 将缓存修剪为cacheCount项目 - * @param cacheCount - */ - static trimCache(cacheCount: any): void; - /** - * 清除缓存 - */ - static clearCache(): void; - /** - * 如果可以的话,从堆栈中弹出一个项 - */ - static obtain(): T[]; - /** - * 将项推回堆栈 - * @param obj - */ - static free(obj: Array): void; - } -} declare module es { class NumberExtension { static toNumber(value: any): number; } } -declare module es { - /** - * 用于管理一对对象的简单DTO - */ - class Pair implements IEqualityComparable { - first: T; - second: T; - constructor(first: T, second: T); - clear(): void; - equals(other: Pair): boolean; - getHashCode(): number; - } -} -declare module es { - /** - * 用于池任何对象 - */ - class Pool { - private static _objectQueue; - /** - * 预热缓存,使用最大的cacheCount对象填充缓存 - * @param type - * @param cacheCount - */ - static warmCache(type: any, cacheCount: number): void; - /** - * 将缓存修剪为cacheCount项目 - * @param cacheCount - */ - static trimCache(cacheCount: number): void; - /** - * 清除缓存 - */ - static clearCache(): void; - /** - * 如果可以的话,从堆栈中弹出一个项 - */ - static obtain(type: any): T; - /** - * 将项推回堆栈 - * @param obj - */ - static free(obj: T): void; - } - interface IPoolable { - /** - * 重置对象以供重用。对象引用应该为空,字段可以设置为默认值 - */ - reset(): any; - } - var isIPoolable: (props: any) => props is IPoolable; -} declare class RandomUtils { /** * 在 start 与 stop之间取一个随机整数,可以用step指定间隔, 但不包括较大的端点(start与stop较大的一个) @@ -3526,126 +3759,43 @@ declare module es { static getRectEdgePortion(rect: Rectangle, edge: Edge, size?: number): Rectangle; static expandSide(rect: Rectangle, edge: Edge, amount: number): void; static contract(rect: Rectangle, horizontalAmount: any, verticalAmount: any): void; - } -} -declare module es { - /** - * 使得number/string/boolean类型作为对象引用来进行传递 - */ - class Ref { - value: T; - constructor(value: T); - } -} -declare module es { - interface ISet { - add(item: T): boolean; - remove(item: T): boolean; - contains(item: T): boolean; - getCount(): number; - clear(): void; - toArray(): Array; /** - * 从当前集合中删除指定集合中的所有元素 + * 给定多边形的点,计算其边界 + * @param points + */ + static boundsFromPolygonVector(points: Vector2[]): Rectangle; + /** + * 创建一个给定最小/最大点(左上角,右下角)的矩形 + * @param min + * @param max + */ + static fromMinMaxVector(min: Vector2, max: Vector2): Rectangle; + /** + * 返回一个跨越当前边界和提供的delta位置的Bounds + * @param rect + * @param deltaX + * @param deltaY + */ + static getSweptBroadphaseBounds(rect: Rectangle, deltaX: number, deltaY: number): Rectangle; + /** + * 如果矩形发生碰撞,返回true + * moveX和moveY将返回b1为避免碰撞而必须移动的移动量 + * @param rect * @param other + * @param moveX + * @param moveY */ - exceptWith(other: Array): void; + collisionCheck(rect: Rectangle, other: Rectangle, moveX: Ref, moveY: Ref): boolean; /** - * 修改当前Set对象,使其只包含该对象和指定数组中的元素 - * @param other + * 计算两个矩形之间有符号的交点深度 + * @param rectA + * @param rectB + * @returns 两个相交的矩形之间的重叠量。 + * 这些深度值可以是负值,取决于矩形相交的边。 + * 这允许调用者确定正确的推送对象的方向,以解决碰撞问题。 + * 如果矩形不相交,则返回Vector2.zero。 */ - intersectWith(other: Array): void; - /** - * 修改当前的集合对象,使其包含所有存在于自身、指定集合中的元素,或者两者都包含 - * @param other - */ - unionWith(other: Array): void; - isSubsetOf(other: Array): boolean; - isSupersetOf(other: Array): boolean; - overlaps(other: Array): boolean; - setEquals(other: Array): boolean; - } - abstract class Set implements ISet { - protected buckets: T[][]; - protected count: number; - constructor(source?: Array); - abstract getHashCode(item: T): number; - abstract areEqual(value1: T, value2: T): boolean; - add(item: T): boolean; - remove(item: T): boolean; - contains(item: T): boolean; - getCount(): number; - clear(): void; - toArray(): T[]; - /** - * 从当前集合中删除指定集合中的所有元素 - * @param other - */ - exceptWith(other: Array): void; - /** - * 修改当前Set对象,使其只包含该对象和指定数组中的元素 - * @param other - */ - intersectWith(other: Array): void; - unionWith(other: Array): void; - /** - * 确定当前集合是否为指定集合或数组的子集 - * @param other - */ - isSubsetOf(other: Array): boolean; - /** - * 确定当前不可变排序集是否为指定集合的超集 - * @param other - */ - isSupersetOf(other: Array): boolean; - overlaps(other: Array): boolean; - setEquals(other: Array): boolean; - private buildInternalBuckets; - private bucketsContains; - } - class HashSet extends Set { - constructor(source?: Array); - getHashCode(item: T): number; - areEqual(value1: T, value2: T): boolean; - } -} -declare module es { - /** - * 管理数值的简单助手类。它存储值,直到累计的总数大于1。一旦超过1,该值将在调用update时添加到amount中。 - */ - class SubpixelNumber { - remainder: number; - /** - * 以amount递增余数,将值截断为int,存储新的余数并将amount设置为当前值。 - * @param amount - */ - update(amount: number): number; - /** - * 将余数重置为0。当一个物体与一个不可移动的物体碰撞时有用。 - * 在这种情况下,您将希望将亚像素余数归零,因为它是空的和无效的碰撞。 - */ - reset(): void; - } -} -declare module es { - /** - * 简单的剪耳三角测量器,最终的三角形将出现在triangleIndices列表中。 - */ - class Triangulator { - /** - * 上次三角函数调用中使用的点列表的三角列表条目索引 - */ - triangleIndices: number[]; - private _triPrev; - private _triNext; - static testPointTriangle(point: Vector2, a: Vector2, b: Vector2, c: Vector2): boolean; - /** - * 计算一个三角形列表,该列表完全覆盖给定点集所包含的区域。如果点不是CCW,则将arePointsCCW参数传递为false - * @param points 定义封闭路径的点列表 - * @param arePointsCCW - */ - triangulate(points: Vector2[], arePointsCCW?: boolean): void; - private initialize; + static getIntersectionDepth(rectA: Rectangle, rectB: Rectangle): Vector2; } } declare module es { @@ -3729,119 +3879,6 @@ declare class WebGLUtils { */ static getContext(): CanvasRenderingContext2D; } -declare namespace stopwatch { - /** - * 记录时间的持续时间,一些设计灵感来自物理秒表。 - */ - class Stopwatch { - private readonly getSystemTime; - /** - * 秒表启动的系统时间。 - * undefined,如果秒表尚未启动,或已复位。 - */ - private _startSystemTime; - /** - * 秒表停止的系统时间。 - * undefined,如果秒表目前没有停止,尚未开始,或已复位。 - */ - private _stopSystemTime; - /** 自上次复位以来,秒表已停止的系统时间总数。 */ - private _stopDuration; - /** - * 用秒表计时,当前等待的切片开始的时间。 - * undefined,如果秒表尚未启动,或已复位。 - */ - private _pendingSliceStartStopwatchTime; - /** - * 记录自上次复位以来所有已完成切片的结果。 - */ - private _completeSlices; - constructor(getSystemTime?: GetTimeFunc); - getState(): State; - isIdle(): boolean; - isRunning(): boolean; - isStopped(): boolean; - /** - * - */ - slice(): Slice; - /** - * 获取自上次复位以来该秒表已完成/记录的所有片的列表。 - */ - getCompletedSlices(): Slice[]; - /** - * 获取自上次重置以来该秒表已完成/记录的所有片的列表,以及当前挂起的片。 - */ - getCompletedAndPendingSlices(): Slice[]; - /** - * 获取关于这个秒表当前挂起的切片的详细信息。 - */ - getPendingSlice(): Slice; - /** - * 获取当前秒表时间。这是这个秒表自上次复位以来运行的系统时间总数。 - */ - getTime(): number; - /** - * 完全重置这个秒表到它的初始状态。清除所有记录的运行持续时间、切片等。 - */ - reset(): void; - /** - * 开始(或继续)运行秒表。 - * @param forceReset - */ - start(forceReset?: boolean): void; - /** - * - * @param recordPendingSlice - */ - stop(recordPendingSlice?: boolean): number; - /** - * 计算指定秒表时间的当前挂起片。 - * @param endStopwatchTime - */ - private calculatePendingSlice; - /** - * 计算指定系统时间的当前秒表时间。 - * @param endSystemTime - */ - private caculateStopwatchTime; - /** - * 获取与当前秒表时间等效的系统时间。 - * 如果该秒表当前停止,则返回该秒表停止时的系统时间。 - */ - private getSystemTimeOfCurrentStopwatchTime; - /** - * 结束/记录当前挂起的片的私有实现。 - * @param endStopwatchTime - */ - private recordPendingSlice; - } - /** - * 返回某个系统的“当前时间”的函数。 - * 惟一的要求是,对该函数的每次调用都必须返回一个大于或等于前一次对该函数的调用的数字。 - */ - type GetTimeFunc = () => number; - enum State { - /** 秒表尚未启动,或已复位。 */ - IDLE = "IDLE", - /** 秒表正在运行。 */ - RUNNING = "RUNNING", - /** 秒表以前还在跑,但现在已经停了。 */ - STOPPED = "STOPPED" - } - function setDefaultSystemTimeGetter(systemTimeGetter?: GetTimeFunc): void; - /** - * 由秒表记录的单个“薄片”的测量值 - */ - interface Slice { - /** 秒表显示的时间在这一片开始的时候。 */ - readonly startTime: number; - /** 秒表在这片片尾的时间。 */ - readonly endTime: number; - /** 该切片的运行时间 */ - readonly duration: number; - } -} declare module linq { class Enumerable { /** diff --git a/source/bin/framework.js b/source/bin/framework.js index c4edb201..41b7727b 100644 --- a/source/bin/framework.js +++ b/source/bin/framework.js @@ -241,8 +241,8 @@ var es; } if (this._instance._scene == null) { this._instance._scene = value; + this._instance.onSceneChanged(); this._instance._scene.begin(); - Core.Instance.onSceneChanged(); } else { this._instance._nextScene = value; @@ -1377,7 +1377,7 @@ var es; * 对精灵坐标进行四舍五入 */ Transform.prototype.roundPosition = function () { - this.position = this._position.round(); + this.position = es.Vector2Ext.round(this._position); }; Transform.prototype.updateTransform = function () { if (this.hierarchyDirty != DirtyType.clean) { @@ -3194,391 +3194,6 @@ var es; es.EntityProcessorList = EntityProcessorList; })(es || (es = {})); var es; -(function (es) { - /** - * 创建这个字典的原因只有一个: - * 我需要一个能让我直接以数组的形式对值进行迭代的字典,而不需要生成一个数组或使用迭代器。 - * 对于这个目标是比标准字典快N倍。 - * Faster dictionary在大部分操作上也比标准字典快,但差别可以忽略不计。 - * 唯一较慢的操作是在添加时调整内存大小,因为与标准数组相比,这个实现需要使用两个单独的数组。 - */ - var FasterDictionary = /** @class */ (function () { - function FasterDictionary(size) { - if (size === void 0) { size = 1; } - this._freeValueCellIndex = 0; - this._collisions = 0; - this._valuesInfo = new Array(size); - this._values = new Array(size); - this._buckets = new Array(es.HashHelpers.getPrime(size)); - } - FasterDictionary.prototype.getValuesArray = function (count) { - count.value = this._freeValueCellIndex; - return this._values; - }; - Object.defineProperty(FasterDictionary.prototype, "valuesArray", { - get: function () { - return this._values; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(FasterDictionary.prototype, "count", { - get: function () { - return this._freeValueCellIndex; - }, - enumerable: true, - configurable: true - }); - FasterDictionary.prototype.add = function (key, value) { - if (!this.addValue(key, value, { value: 0 })) - throw new Error("key 已经存在"); - }; - FasterDictionary.prototype.addValue = function (key, value, indexSet) { - var hash = es.HashHelpers.getHashCode(key); - var bucketIndex = FasterDictionary.reduce(hash, this._buckets.length); - if (this._freeValueCellIndex == this._values.length) { - var expandPrime = es.HashHelpers.expandPrime(this._freeValueCellIndex); - this._values.length = expandPrime; - this._valuesInfo.length = expandPrime; - } - // buckets值-1表示它是空的 - var valueIndex = es.NumberExtension.toNumber(this._buckets[bucketIndex]) - 1; - if (valueIndex == -1) { - // 在最后一个位置创建信息节点,并填入相关信息 - this._valuesInfo[this._freeValueCellIndex] = new FastNode(key, hash); - } - else { - { - var currentValueIndex = valueIndex; - do { - // 必须检查键是否已经存在于字典中 - if (this._valuesInfo[currentValueIndex].hashcode == hash && - this._valuesInfo[currentValueIndex].key == key) { - // 键已经存在,只需将其值替换掉即可 - this._values[currentValueIndex] = value; - indexSet.value = currentValueIndex; - return false; - } - currentValueIndex = this._valuesInfo[currentValueIndex].previous; - } while (currentValueIndex != -1); // -1表示没有更多的值与相同的哈希值的键 - } - this._collisions++; - // 创建一个新的节点,该节点之前的索引指向当前指向桶的节点 - this._valuesInfo[this._freeValueCellIndex] = new FastNode(key, hash, valueIndex); - // 更新现有单元格的下一个单元格指向新的单元格,旧的单元格 -> 新的单元格 -> 旧的单元格 <- 下一个单元格 - this._valuesInfo[valueIndex].next = this._freeValueCellIndex; - } - // 重要的是:新的节点总是被桶单元格指向的那个节点,所以我可以假设被桶指向的那个节点总是最后添加的值(next = -1) - // item与这个bucketIndex将指向最后创建的值 - // TODO: 如果相反,我假设原来的那个是bucket中的那个,我就不需要在这里更新bucket了 - this._buckets[bucketIndex] = (this._freeValueCellIndex + 1); - this._values[this._freeValueCellIndex] = value; - indexSet.value = this._freeValueCellIndex; - this._freeValueCellIndex++; - if (this._collisions > this._buckets.length) { - // 我们需要更多的空间和更少的碰撞 - this._buckets = new Array(es.HashHelpers.expandPrime(this._collisions)); - this._collisions = 0; - // 我们需要得到目前存储的所有值的哈希码,并将它们分布在新的桶长上 - for (var newValueIndex = 0; newValueIndex < this._freeValueCellIndex; newValueIndex++) { - // 获取原始哈希码,并根据新的长度找到新的bucketIndex - bucketIndex = FasterDictionary.reduce(this._valuesInfo[newValueIndex].hashcode, this._buckets.length); - // bucketsIndex可以是-1或下一个值。 - // 如果是-1意味着没有碰撞。 - // 如果有碰撞,我们创建一个新节点,它的上一个指向旧节点。 - // 旧节点指向新节点,新节点指向旧节点,旧节点指向新节点,现在bucket指向新节点,这样我们就可以重建linkedlist. - // 获取当前值Index,如果没有碰撞,则为-1。 - var existingValueIndex = es.NumberExtension.toNumber(this._buckets[bucketIndex]) - 1; - // 将bucket索引更新为共享bucketIndex的当前项目的索引(最后找到的总是bucket中的那个) - this._buckets[bucketIndex] = newValueIndex + 1; - if (existingValueIndex != -1) { - // 这个单元格已经指向了新的bucket list中的一个值,这意味着有一个碰撞,出了问题 - this._collisions++; - // bucket将指向这个值,所以新的值将使用以前的索引 - this._valuesInfo[newValueIndex].previous = existingValueIndex; - this._valuesInfo[newValueIndex].next = -1; - // 并将之前的下一个索引更新为新的索引 - this._valuesInfo[existingValueIndex].next = newValueIndex; - } - else { - // 什么都没有被索引,桶是空的。我们需要更新之前的 next 和 previous 的值。 - this._valuesInfo[newValueIndex].next = -1; - this._valuesInfo[newValueIndex].previous = -1; - } - } - } - return true; - }; - FasterDictionary.prototype.remove = function (key) { - var hash = FasterDictionary.hash(key); - var bucketIndex = FasterDictionary.reduce(hash, this._buckets.length); - // 找桶 - var indexToValueToRemove = es.NumberExtension.toNumber(this._buckets[bucketIndex]) - 1; - // 第一部分:在bucket list中寻找实际的键,如果找到了,我就更新bucket list,使它不再指向要删除的单元格。 - while (indexToValueToRemove != -1) { - if (this._valuesInfo[indexToValueToRemove].hashcode == hash && - this._valuesInfo[indexToValueToRemove].key == key) { - // 如果找到了密钥,并且桶直接指向了要删除的节点 - if (this._buckets[bucketIndex] - 1 == indexToValueToRemove) { - if (this._valuesInfo[indexToValueToRemove].next != -1) - throw new Error("如果 bucket 指向单元格,那么 next 必须不存在。"); - // 如果前一个单元格存在,它的下一个指针必须被更新! - //<---迭代顺序 - // B(ucket总是指向最后一个) - // ------- ------- ------- - // 1 | | | | 2 | | | 3 | //bucket不能有下一个,只能有上一个。 - // ------- ------- ------- - //--> 插入 - var value = this._valuesInfo[indexToValueToRemove].previous; - this._buckets[bucketIndex] = value + 1; - } - else { - if (this._valuesInfo[indexToValueToRemove].next == -1) - throw new Error("如果 bucket 指向另一个单元格,则 NEXT 必须存在"); - } - FasterDictionary.updateLinkedList(indexToValueToRemove, this._valuesInfo); - break; - } - indexToValueToRemove = this._valuesInfo[indexToValueToRemove].previous; - } - if (indexToValueToRemove == -1) - return false; // 未找到 - this._freeValueCellIndex--; // 少了一个需要反复计算的值 - // 第二部分 - // 这时节点指针和水桶会被更新,但_values数组会被更新仍然有要删除的值 - // 这个字典的目标是能够做到像数组一样对数值进行迭代,所以数值数组必须始终是最新的 - // 如果要删除的单元格是列表中的最后一个,我们可以执行较少的操作(不需要交换),否则我们要将最后一个值的单元格移到要删除的值上。 - if (indexToValueToRemove != this._freeValueCellIndex) { - // 我们可以将两个数组的最后一个值移到要删除的数组中。 - // 为了做到这一点,我们需要确保 bucket 指针已经更新了 - // 首先我们在桶列表中找到指向要移动的单元格的指针的索引 - var movingBucketIndex = FasterDictionary.reduce(this._valuesInfo[this._freeValueCellIndex].hashcode, this._buckets.length); - // 如果找到了键,并且桶直接指向要删除的节点,现在必须指向要移动的单元格。 - if (this._buckets[movingBucketIndex] - 1 == this._freeValueCellIndex) - this._buckets[movingBucketIndex] = (indexToValueToRemove + 1); - // 否则意味着有多个键具有相同的哈希值(碰撞),所以我们需要更新链接列表和它的指针 - var next = this._valuesInfo[this._freeValueCellIndex].next; - var previous = this._valuesInfo[this._freeValueCellIndex].previous; - // 现在它们指向最后一个值被移入的单元格 - if (next != -1) - this._valuesInfo[next].previous = indexToValueToRemove; - if (previous != -1) - this._valuesInfo[previous].next = indexToValueToRemove; - // 最后,实际上是移动值 - this._valuesInfo[indexToValueToRemove] = this._valuesInfo[this._freeValueCellIndex]; - this._values[indexToValueToRemove] = this._values[this._freeValueCellIndex]; - } - return true; - }; - FasterDictionary.prototype.trim = function () { - var expandPrime = es.HashHelpers.expandPrime(this._freeValueCellIndex); - if (expandPrime < this._valuesInfo.length) { - this._values.length = expandPrime; - this._valuesInfo.length = expandPrime; - } - }; - FasterDictionary.prototype.clear = function () { - if (this._freeValueCellIndex == 0) - return; - this._freeValueCellIndex = 0; - this._buckets.length = 0; - this._values.length = 0; - this._valuesInfo.length = 0; - }; - FasterDictionary.prototype.fastClear = function () { - if (this._freeValueCellIndex == 0) - return; - this._freeValueCellIndex = 0; - this._buckets.length = 0; - this._valuesInfo.length = 0; - }; - FasterDictionary.prototype.containsKey = function (key) { - if (this.tryFindIndex(key, { value: 0 })) { - return true; - } - return false; - }; - FasterDictionary.prototype.tryGetValue = function (key) { - var findIndex = { value: 0 }; - if (this.tryFindIndex(key, findIndex)) { - return this._values[findIndex.value]; - } - return null; - }; - FasterDictionary.prototype.tryFindIndex = function (key, findIndex) { - // 我把所有的索引都用偏移量+1来存储,这样在bucket list中0就意味着实际上不存在 - // 当读取时,偏移量必须再偏移-1才是真实的 - // 这样我就避免了将数组初始化为-1 - var hash = FasterDictionary.hash(key); - var bucketIndex = FasterDictionary.reduce(hash, this._buckets.length); - var valueIndex = es.NumberExtension.toNumber(this._buckets[bucketIndex]) - 1; - // 即使我们找到了一个现有的值,我们也需要确定它是我们所要求的值 - while (valueIndex != -1) { - if (this._valuesInfo[valueIndex].hashcode == hash && this._valuesInfo[valueIndex].key == key) { - findIndex.value = valueIndex; - return true; - } - valueIndex = this._valuesInfo[valueIndex].previous; - } - findIndex.value = 0; - return false; - }; - FasterDictionary.prototype.getDirectValue = function (index) { - return this._values[index]; - }; - FasterDictionary.prototype.getIndex = function (key) { - var findIndex = { value: 0 }; - if (this.tryFindIndex(key, findIndex)) - return findIndex.value; - throw new Error("未找到key"); - }; - FasterDictionary.updateLinkedList = function (index, valuesInfo) { - var next = valuesInfo[index].next; - var previous = valuesInfo[index].previous; - if (next != -1) - valuesInfo[next].previous = previous; - if (previous != -1) - valuesInfo[previous].next = next; - }; - FasterDictionary.hash = function (key) { - return es.HashHelpers.getHashCode(key); - }; - FasterDictionary.reduce = function (x, n) { - if (x >= n) - return x % n; - return x; - }; - return FasterDictionary; - }()); - es.FasterDictionary = FasterDictionary; - var FastNode = /** @class */ (function () { - function FastNode(key, hash, previousNode) { - if (previousNode === void 0) { previousNode = -1; } - this.key = key; - this.hashcode = hash; - this.previous = previousNode; - this.next = -1; - } - return FastNode; - }()); - es.FastNode = FastNode; -})(es || (es = {})); -var es; -(function (es) { - /** - * 围绕一个数组的非常基本的包装,当它达到容量时自动扩展。 - * 注意,在迭代时应该这样直接访问缓冲区,但使用FastList.length字段。 - * - * @tutorial - * for( var i = 0; i <= list.length; i++ ) - * var item = list.buffer[i]; - */ - var FastList = /** @class */ (function () { - function FastList(size) { - if (size === void 0) { size = 5; } - /** - * 直接访问缓冲区内填充项的长度。不要改变。 - */ - this.length = 0; - this.buffer = new Array(size); - } - /** - * 清空列表并清空缓冲区中的所有项目 - */ - FastList.prototype.clear = function () { - this.buffer.length = 0; - this.length = 0; - }; - /** - * 和clear的工作原理一样,只是它不会将缓冲区中的所有项目清空。 - */ - FastList.prototype.reset = function () { - this.length = 0; - }; - /** - * 将该项目添加到列表中 - * @param item - */ - FastList.prototype.add = function (item) { - if (this.length == this.buffer.length) - this.buffer.length = Math.max(this.buffer.length << 1, 10); - this.buffer[this.length++] = item; - }; - /** - * 从列表中删除该项目 - * @param item - */ - FastList.prototype.remove = function (item) { - var comp = es.EqualityComparer.default(); - for (var i = 0; i < this.length; ++i) { - if (comp.equals(this.buffer[i], item)) { - this.removeAt(i); - return; - } - } - }; - /** - * 从列表中删除给定索引的项目。 - * @param index - */ - FastList.prototype.removeAt = function (index) { - if (index >= this.length) - throw new Error("index超出范围!"); - this.length--; - new linq.List(this.buffer).removeAt(index); - }; - /** - * 检查项目是否在FastList中 - * @param item - */ - FastList.prototype.contains = function (item) { - var comp = es.EqualityComparer.default(); - for (var i = 0; i < this.length; ++i) { - if (comp.equals(this.buffer[i], item)) - return true; - } - return false; - }; - /** - * 如果缓冲区达到最大,将分配更多的空间来容纳额外的ItemCount。 - * @param additionalItemCount - */ - FastList.prototype.ensureCapacity = function (additionalItemCount) { - if (additionalItemCount === void 0) { additionalItemCount = 1; } - if (this.length + additionalItemCount >= this.buffer.length) - this.buffer.length = Math.max(this.buffer.length << 1, this.length + additionalItemCount); - }; - /** - * 添加数组中的所有项目 - * @param array - */ - FastList.prototype.addRange = function (array) { - var e_3, _a; - try { - for (var array_1 = __values(array), array_1_1 = array_1.next(); !array_1_1.done; array_1_1 = array_1.next()) { - var item = array_1_1.value; - this.add(item); - } - } - catch (e_3_1) { e_3 = { error: e_3_1 }; } - finally { - try { - if (array_1_1 && !array_1_1.done && (_a = array_1.return)) _a.call(array_1); - } - finally { if (e_3) throw e_3.error; } - } - }; - /** - * 对缓冲区中的所有项目进行排序,长度不限。 - */ - FastList.prototype.sort = function (comparer) { - this.buffer.sort(comparer.compare); - }; - return FastList; - }()); - es.FastList = FastList; -})(es || (es = {})); -var es; (function (es) { var HashHelpers = /** @class */ (function () { function HashHelpers() { @@ -6527,7 +6142,7 @@ var es; * @param layerMask */ SpatialHash.prototype.overlapCircle = function (circleCenter, radius, results, layerMask) { - var e_4, _a; + var e_3, _a; var bounds = new es.Rectangle(circleCenter.x - radius, circleCenter.y - radius, radius * 2, radius * 2); this._overlapTestCircle.radius = radius; this._overlapTestCircle.position = circleCenter; @@ -6560,12 +6175,12 @@ var es; return resultCounter; } } - catch (e_4_1) { e_4 = { error: e_4_1 }; } + catch (e_3_1) { e_3 = { error: e_3_1 }; } finally { try { if (potentials_1_1 && !potentials_1_1.done && (_a = potentials_1.return)) _a.call(potentials_1); } - finally { if (e_4) throw e_4.error; } + finally { if (e_3) throw e_3.error; } } return resultCounter; }; @@ -7351,6 +6966,7 @@ var es; * @param result */ ShapeCollisions.circleToPolygon = function (circle, polygon, result) { + if (result === void 0) { result = new es.CollisionResult(); } // 圆圈在多边形中的位置坐标 var poly2Circle = es.Vector2.subtract(circle.position, polygon.position); // 首先,我们需要找到从圆到多边形的最近距离 @@ -7374,7 +6990,7 @@ var es; } else { var distance = Math.sqrt(distanceSquared.value); - mtv = new es.Vector2(-poly2Circle.x + closestPoint.x, -poly2Circle.y + closestPoint.y) + mtv = es.Vector2.subtract(new es.Vector2(-1), es.Vector2.subtract(poly2Circle, closestPoint)) .multiply(new es.Vector2((circle.radius - distance) / distance)); } } @@ -7383,23 +6999,24 @@ var es; return true; }; /** - * 适用于圆心在方框内以及只与方框外圆心重叠的圆。 + * 适用于中心在框内的圆,也适用于与框外中心重合的圆。 * @param circle * @param box * @param result */ ShapeCollisions.circleToBox = function (circle, box, result) { + if (result === void 0) { result = new es.CollisionResult(); } var closestPointOnBounds = box.bounds.getClosestPointOnRectangleBorderToPoint(circle.position, result.normal); - // 处理那些中心在盒子里的圆,因为比较好操作, + // 先处理中心在盒子里的圆,如果我们是包含的, 它的成本更低, if (box.containsPoint(circle.position)) { - result.point = closestPointOnBounds; - // 计算mtv。找到安全的,没有碰撞的位置,然后从那里得到mtv + result.point = closestPointOnBounds.clone(); + // 计算MTV。找出安全的、非碰撞的位置,并从中得到MTV var safePlace = es.Vector2.add(closestPointOnBounds, es.Vector2.multiply(result.normal, new es.Vector2(circle.radius))); result.minimumTranslationVector = es.Vector2.subtract(circle.position, safePlace); return true; } var sqrDistance = es.Vector2.distanceSquared(closestPointOnBounds, circle.position); - // 看盒子上的点与圆的距离是否小于半径 + // 看框上的点距圆的半径是否小于圆的半径 if (sqrDistance == 0) { result.minimumTranslationVector = es.Vector2.multiply(result.normal, new es.Vector2(circle.radius)); } @@ -7452,7 +7069,7 @@ var es; 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, es.Vector2.multiply(v, new es.Vector2(t, t))); + return es.Vector2.add(lineA, es.Vector2.multiply(v, new es.Vector2(t))); }; /** * @@ -7477,6 +7094,7 @@ var es; * @param result */ ShapeCollisions.circleToCircle = function (first, second, result) { + if (result === void 0) { result = new es.CollisionResult(); } var distanceSquared = es.Vector2.distanceSquared(first.position, second.position); var sumOfRadii = first.radius + second.radius; var collided = distanceSquared < sumOfRadii * sumOfRadii; @@ -7485,6 +7103,10 @@ var es; var depth = sumOfRadii - Math.sqrt(distanceSquared); result.minimumTranslationVector = es.Vector2.multiply(new es.Vector2(-depth), result.normal); result.point = es.Vector2.add(second.position, es.Vector2.multiply(result.normal, new es.Vector2(second.radius))); + // 这可以得到实际的碰撞点,可能有用也可能没用,所以我们暂时把它留在这里 + // let collisionPointX = ((first.position.x * second.radius) + (second.position.x * first.radius)) / sumOfRadii; + // let collisionPointY = ((first.position.y * second.radius) + (second.position.y * first.radius)) / sumOfRadii; + // result.point = new Vector2(collisionPointX, collisionPointY); return true; } return false; @@ -7517,6 +7139,7 @@ var es; return new es.Rectangle(topLeft.x, topLeft.y, fullSize.x, fullSize.y); }; ShapeCollisions.lineToPoly = function (start, end, polygon, hit) { + if (hit === void 0) { hit = new es.RaycastHit(); } var normal = es.Vector2.zero; var intersectionPoint = es.Vector2.zero; var fraction = Number.MAX_VALUE; @@ -7630,6 +7253,1431 @@ var es; }()); es.ShapeCollisions = ShapeCollisions; })(es || (es = {})); +var es; +(function (es) { + /** + * 用于包装事件的一个小类 + */ + var FuncPack = /** @class */ (function () { + function FuncPack(func, context) { + this.func = func; + this.context = context; + } + return FuncPack; + }()); + es.FuncPack = FuncPack; + /** + * 用于事件管理 + */ + var Emitter = /** @class */ (function () { + function Emitter() { + this._messageTable = new Map(); + } + /** + * 开始监听项 + * @param eventType 监听类型 + * @param handler 监听函数 + * @param context 监听上下文 + */ + Emitter.prototype.addObserver = function (eventType, handler, context) { + var list = this._messageTable.get(eventType); + if (!list) { + list = []; + this._messageTable.set(eventType, list); + } + if (list.findIndex(function (funcPack) { return funcPack.func == handler; }) != -1) + console.warn("您试图添加相同的观察者两次"); + list.push(new FuncPack(handler, context)); + }; + /** + * 移除监听项 + * @param eventType 事件类型 + * @param handler 事件函数 + */ + Emitter.prototype.removeObserver = function (eventType, handler) { + var messageData = this._messageTable.get(eventType); + var index = messageData.findIndex(function (data) { return data.func == handler; }); + if (index != -1) + new linq.List(messageData).removeAt(index); + }; + /** + * 触发该事件 + * @param eventType 事件类型 + * @param data 事件数据 + */ + Emitter.prototype.emit = function (eventType, data) { + var list = this._messageTable.get(eventType); + if (list) { + for (var i = list.length - 1; i >= 0; i--) + list[i].func.call(list[i].context, data); + } + }; + return Emitter; + }()); + es.Emitter = Emitter; +})(es || (es = {})); +var es; +(function (es) { + var Edge; + (function (Edge) { + Edge[Edge["top"] = 0] = "top"; + Edge[Edge["bottom"] = 1] = "bottom"; + Edge[Edge["left"] = 2] = "left"; + Edge[Edge["right"] = 3] = "right"; + })(Edge = es.Edge || (es.Edge = {})); +})(es || (es = {})); +var es; +(function (es) { + var Enumerable = /** @class */ (function () { + function Enumerable() { + } + /** + * 生成包含一个重复值的序列 + * @param element 要重复的值 + * @param count 在生成的序列中重复该值的次数 + */ + Enumerable.repeat = function (element, count) { + var result = []; + while (count--) { + result.push(element); + } + return result; + }; + return Enumerable; + }()); + es.Enumerable = Enumerable; +})(es || (es = {})); +var es; +(function (es) { + var EqualityComparer = /** @class */ (function () { + function EqualityComparer() { + } + EqualityComparer.default = function () { + return new EqualityComparer(); + }; + EqualityComparer.prototype.equals = function (x, y) { + if (typeof x["equals"] == 'function') { + return x["equals"](y); + } + else { + return x === y; + } + }; + EqualityComparer.prototype.getHashCode = function (o) { + var _this = this; + if (typeof o == 'number') { + return this._getHashCodeForNumber(o); + } + if (typeof o == 'string') { + return this._getHashCodeForString(o); + } + var hashCode = 385229220; + this.forOwn(o, function (value) { + if (typeof value == 'number') { + hashCode += _this._getHashCodeForNumber(value); + } + else if (typeof value == 'string') { + hashCode += _this._getHashCodeForString(value); + } + else if (typeof value == 'object') { + _this.forOwn(value, function () { + hashCode += _this.getHashCode(value); + }); + } + }); + return hashCode; + }; + EqualityComparer.prototype._getHashCodeForNumber = function (n) { + return n; + }; + EqualityComparer.prototype._getHashCodeForString = function (s) { + var hashCode = 385229220; + for (var i = 0; i < s.length; i++) { + hashCode = (hashCode * -1521134295) ^ s.charCodeAt(i); + } + return hashCode; + }; + EqualityComparer.prototype.forOwn = function (object, iteratee) { + object = Object(object); + Object.keys(object).forEach(function (key) { return iteratee(object[key], key, object); }); + }; + return EqualityComparer; + }()); + es.EqualityComparer = EqualityComparer; +})(es || (es = {})); +var es; +(function (es) { + var GlobalManager = /** @class */ (function () { + function GlobalManager() { + } + Object.defineProperty(GlobalManager.prototype, "enabled", { + /** + * 如果true则启用了GlobalManager。 + * 状态的改变会导致调用OnEnabled/OnDisable + */ + get: function () { + return this._enabled; + }, + /** + * 如果true则启用了GlobalManager。 + * 状态的改变会导致调用OnEnabled/OnDisable + * @param value + */ + set: function (value) { + this.setEnabled(value); + }, + enumerable: true, + configurable: true + }); + /** + * 启用/禁用这个GlobalManager + * @param isEnabled + */ + GlobalManager.prototype.setEnabled = function (isEnabled) { + if (this._enabled != isEnabled) { + this._enabled = isEnabled; + if (this._enabled) { + this.onEnabled(); + } + else { + this.onDisabled(); + } + } + }; + /** + * 此GlobalManager启用时调用 + */ + GlobalManager.prototype.onEnabled = function () { + }; + /** + * 此GlobalManager禁用时调用 + */ + GlobalManager.prototype.onDisabled = function () { + }; + /** + * 在frame .update之前调用每一帧 + */ + GlobalManager.prototype.update = function () { + }; + return GlobalManager; + }()); + es.GlobalManager = GlobalManager; +})(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) { + /** + * 简单的剪耳三角测量器,最终的三角形将出现在triangleIndices列表中。 + */ + 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) { + // 如果点在AB的右边,那么外边的三角形是 + if (es.Vector2Ext.cross(es.Vector2.subtract(point, a), es.Vector2.subtract(b, a)) < 0) + return false; + // 如果点在BC的右边,则在三角形的外侧 + if (es.Vector2Ext.cross(es.Vector2.subtract(point, b), es.Vector2.subtract(c, b)) < 0) + return false; + // 如果点在ca的右边,则在三角形的外面 + 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.length = Math.max(this._triNext.length * 2, count); + } + if (this._triPrev.length < count) { + this._triPrev.reverse(); + this._triPrev.length = 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 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 __spread(this._completeSlices, [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) { + /** + * 围绕一个数组的非常基本的包装,当它达到容量时自动扩展。 + * 注意,在迭代时应该这样直接访问缓冲区,但使用FastList.length字段。 + * + * @tutorial + * for( var i = 0; i <= list.length; i++ ) + * var item = list.buffer[i]; + */ + var FastList = /** @class */ (function () { + function FastList(size) { + if (size === void 0) { size = 5; } + /** + * 直接访问缓冲区内填充项的长度。不要改变。 + */ + this.length = 0; + this.buffer = new Array(size); + } + /** + * 清空列表并清空缓冲区中的所有项目 + */ + FastList.prototype.clear = function () { + this.buffer.length = 0; + this.length = 0; + }; + /** + * 和clear的工作原理一样,只是它不会将缓冲区中的所有项目清空。 + */ + FastList.prototype.reset = function () { + this.length = 0; + }; + /** + * 将该项目添加到列表中 + * @param item + */ + FastList.prototype.add = function (item) { + if (this.length == this.buffer.length) + this.buffer.length = Math.max(this.buffer.length << 1, 10); + this.buffer[this.length++] = item; + }; + /** + * 从列表中删除该项目 + * @param item + */ + FastList.prototype.remove = function (item) { + var comp = es.EqualityComparer.default(); + for (var i = 0; i < this.length; ++i) { + if (comp.equals(this.buffer[i], item)) { + this.removeAt(i); + return; + } + } + }; + /** + * 从列表中删除给定索引的项目。 + * @param index + */ + FastList.prototype.removeAt = function (index) { + if (index >= this.length) + throw new Error("index超出范围!"); + this.length--; + new linq.List(this.buffer).removeAt(index); + }; + /** + * 检查项目是否在FastList中 + * @param item + */ + FastList.prototype.contains = function (item) { + var comp = es.EqualityComparer.default(); + for (var i = 0; i < this.length; ++i) { + if (comp.equals(this.buffer[i], item)) + return true; + } + return false; + }; + /** + * 如果缓冲区达到最大,将分配更多的空间来容纳额外的ItemCount。 + * @param additionalItemCount + */ + FastList.prototype.ensureCapacity = function (additionalItemCount) { + if (additionalItemCount === void 0) { additionalItemCount = 1; } + if (this.length + additionalItemCount >= this.buffer.length) + this.buffer.length = Math.max(this.buffer.length << 1, this.length + additionalItemCount); + }; + /** + * 添加数组中的所有项目 + * @param array + */ + FastList.prototype.addRange = function (array) { + var e_4, _a; + try { + for (var array_1 = __values(array), array_1_1 = array_1.next(); !array_1_1.done; array_1_1 = array_1.next()) { + var item = array_1_1.value; + this.add(item); + } + } + catch (e_4_1) { e_4 = { error: e_4_1 }; } + finally { + try { + if (array_1_1 && !array_1_1.done && (_a = array_1.return)) _a.call(array_1); + } + finally { if (e_4) throw e_4.error; } + } + }; + /** + * 对缓冲区中的所有项目进行排序,长度不限。 + */ + FastList.prototype.sort = function (comparer) { + this.buffer.sort(comparer.compare); + }; + return FastList; + }()); + es.FastList = FastList; +})(es || (es = {})); +var es; +(function (es) { + /** + * 创建这个字典的原因只有一个: + * 我需要一个能让我直接以数组的形式对值进行迭代的字典,而不需要生成一个数组或使用迭代器。 + * 对于这个目标是比标准字典快N倍。 + * Faster dictionary在大部分操作上也比标准字典快,但差别可以忽略不计。 + * 唯一较慢的操作是在添加时调整内存大小,因为与标准数组相比,这个实现需要使用两个单独的数组。 + */ + var FasterDictionary = /** @class */ (function () { + function FasterDictionary(size) { + if (size === void 0) { size = 1; } + this._freeValueCellIndex = 0; + this._collisions = 0; + this._valuesInfo = new Array(size); + this._values = new Array(size); + this._buckets = new Array(es.HashHelpers.getPrime(size)); + } + FasterDictionary.prototype.getValuesArray = function (count) { + count.value = this._freeValueCellIndex; + return this._values; + }; + Object.defineProperty(FasterDictionary.prototype, "valuesArray", { + get: function () { + return this._values; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(FasterDictionary.prototype, "count", { + get: function () { + return this._freeValueCellIndex; + }, + enumerable: true, + configurable: true + }); + FasterDictionary.prototype.add = function (key, value) { + if (!this.addValue(key, value, { value: 0 })) + throw new Error("key 已经存在"); + }; + FasterDictionary.prototype.addValue = function (key, value, indexSet) { + var hash = es.HashHelpers.getHashCode(key); + var bucketIndex = FasterDictionary.reduce(hash, this._buckets.length); + if (this._freeValueCellIndex == this._values.length) { + var expandPrime = es.HashHelpers.expandPrime(this._freeValueCellIndex); + this._values.length = expandPrime; + this._valuesInfo.length = expandPrime; + } + // buckets值-1表示它是空的 + var valueIndex = es.NumberExtension.toNumber(this._buckets[bucketIndex]) - 1; + if (valueIndex == -1) { + // 在最后一个位置创建信息节点,并填入相关信息 + this._valuesInfo[this._freeValueCellIndex] = new FastNode(key, hash); + } + else { + { + var currentValueIndex = valueIndex; + do { + // 必须检查键是否已经存在于字典中 + if (this._valuesInfo[currentValueIndex].hashcode == hash && + this._valuesInfo[currentValueIndex].key == key) { + // 键已经存在,只需将其值替换掉即可 + this._values[currentValueIndex] = value; + indexSet.value = currentValueIndex; + return false; + } + currentValueIndex = this._valuesInfo[currentValueIndex].previous; + } while (currentValueIndex != -1); // -1表示没有更多的值与相同的哈希值的键 + } + this._collisions++; + // 创建一个新的节点,该节点之前的索引指向当前指向桶的节点 + this._valuesInfo[this._freeValueCellIndex] = new FastNode(key, hash, valueIndex); + // 更新现有单元格的下一个单元格指向新的单元格,旧的单元格 -> 新的单元格 -> 旧的单元格 <- 下一个单元格 + this._valuesInfo[valueIndex].next = this._freeValueCellIndex; + } + // 重要的是:新的节点总是被桶单元格指向的那个节点,所以我可以假设被桶指向的那个节点总是最后添加的值(next = -1) + // item与这个bucketIndex将指向最后创建的值 + // TODO: 如果相反,我假设原来的那个是bucket中的那个,我就不需要在这里更新bucket了 + this._buckets[bucketIndex] = (this._freeValueCellIndex + 1); + this._values[this._freeValueCellIndex] = value; + indexSet.value = this._freeValueCellIndex; + this._freeValueCellIndex++; + if (this._collisions > this._buckets.length) { + // 我们需要更多的空间和更少的碰撞 + this._buckets = new Array(es.HashHelpers.expandPrime(this._collisions)); + this._collisions = 0; + // 我们需要得到目前存储的所有值的哈希码,并将它们分布在新的桶长上 + for (var newValueIndex = 0; newValueIndex < this._freeValueCellIndex; newValueIndex++) { + // 获取原始哈希码,并根据新的长度找到新的bucketIndex + bucketIndex = FasterDictionary.reduce(this._valuesInfo[newValueIndex].hashcode, this._buckets.length); + // bucketsIndex可以是-1或下一个值。 + // 如果是-1意味着没有碰撞。 + // 如果有碰撞,我们创建一个新节点,它的上一个指向旧节点。 + // 旧节点指向新节点,新节点指向旧节点,旧节点指向新节点,现在bucket指向新节点,这样我们就可以重建linkedlist. + // 获取当前值Index,如果没有碰撞,则为-1。 + var existingValueIndex = es.NumberExtension.toNumber(this._buckets[bucketIndex]) - 1; + // 将bucket索引更新为共享bucketIndex的当前项目的索引(最后找到的总是bucket中的那个) + this._buckets[bucketIndex] = newValueIndex + 1; + if (existingValueIndex != -1) { + // 这个单元格已经指向了新的bucket list中的一个值,这意味着有一个碰撞,出了问题 + this._collisions++; + // bucket将指向这个值,所以新的值将使用以前的索引 + this._valuesInfo[newValueIndex].previous = existingValueIndex; + this._valuesInfo[newValueIndex].next = -1; + // 并将之前的下一个索引更新为新的索引 + this._valuesInfo[existingValueIndex].next = newValueIndex; + } + else { + // 什么都没有被索引,桶是空的。我们需要更新之前的 next 和 previous 的值。 + this._valuesInfo[newValueIndex].next = -1; + this._valuesInfo[newValueIndex].previous = -1; + } + } + } + return true; + }; + FasterDictionary.prototype.remove = function (key) { + var hash = FasterDictionary.hash(key); + var bucketIndex = FasterDictionary.reduce(hash, this._buckets.length); + // 找桶 + var indexToValueToRemove = es.NumberExtension.toNumber(this._buckets[bucketIndex]) - 1; + // 第一部分:在bucket list中寻找实际的键,如果找到了,我就更新bucket list,使它不再指向要删除的单元格。 + while (indexToValueToRemove != -1) { + if (this._valuesInfo[indexToValueToRemove].hashcode == hash && + this._valuesInfo[indexToValueToRemove].key == key) { + // 如果找到了密钥,并且桶直接指向了要删除的节点 + if (this._buckets[bucketIndex] - 1 == indexToValueToRemove) { + if (this._valuesInfo[indexToValueToRemove].next != -1) + throw new Error("如果 bucket 指向单元格,那么 next 必须不存在。"); + // 如果前一个单元格存在,它的下一个指针必须被更新! + //<---迭代顺序 + // B(ucket总是指向最后一个) + // ------- ------- ------- + // 1 | | | | 2 | | | 3 | //bucket不能有下一个,只能有上一个。 + // ------- ------- ------- + //--> 插入 + var value = this._valuesInfo[indexToValueToRemove].previous; + this._buckets[bucketIndex] = value + 1; + } + else { + if (this._valuesInfo[indexToValueToRemove].next == -1) + throw new Error("如果 bucket 指向另一个单元格,则 NEXT 必须存在"); + } + FasterDictionary.updateLinkedList(indexToValueToRemove, this._valuesInfo); + break; + } + indexToValueToRemove = this._valuesInfo[indexToValueToRemove].previous; + } + if (indexToValueToRemove == -1) + return false; // 未找到 + this._freeValueCellIndex--; // 少了一个需要反复计算的值 + // 第二部分 + // 这时节点指针和水桶会被更新,但_values数组会被更新仍然有要删除的值 + // 这个字典的目标是能够做到像数组一样对数值进行迭代,所以数值数组必须始终是最新的 + // 如果要删除的单元格是列表中的最后一个,我们可以执行较少的操作(不需要交换),否则我们要将最后一个值的单元格移到要删除的值上。 + if (indexToValueToRemove != this._freeValueCellIndex) { + // 我们可以将两个数组的最后一个值移到要删除的数组中。 + // 为了做到这一点,我们需要确保 bucket 指针已经更新了 + // 首先我们在桶列表中找到指向要移动的单元格的指针的索引 + var movingBucketIndex = FasterDictionary.reduce(this._valuesInfo[this._freeValueCellIndex].hashcode, this._buckets.length); + // 如果找到了键,并且桶直接指向要删除的节点,现在必须指向要移动的单元格。 + if (this._buckets[movingBucketIndex] - 1 == this._freeValueCellIndex) + this._buckets[movingBucketIndex] = (indexToValueToRemove + 1); + // 否则意味着有多个键具有相同的哈希值(碰撞),所以我们需要更新链接列表和它的指针 + var next = this._valuesInfo[this._freeValueCellIndex].next; + var previous = this._valuesInfo[this._freeValueCellIndex].previous; + // 现在它们指向最后一个值被移入的单元格 + if (next != -1) + this._valuesInfo[next].previous = indexToValueToRemove; + if (previous != -1) + this._valuesInfo[previous].next = indexToValueToRemove; + // 最后,实际上是移动值 + this._valuesInfo[indexToValueToRemove] = this._valuesInfo[this._freeValueCellIndex]; + this._values[indexToValueToRemove] = this._values[this._freeValueCellIndex]; + } + return true; + }; + FasterDictionary.prototype.trim = function () { + var expandPrime = es.HashHelpers.expandPrime(this._freeValueCellIndex); + if (expandPrime < this._valuesInfo.length) { + this._values.length = expandPrime; + this._valuesInfo.length = expandPrime; + } + }; + FasterDictionary.prototype.clear = function () { + if (this._freeValueCellIndex == 0) + return; + this._freeValueCellIndex = 0; + this._buckets.length = 0; + this._values.length = 0; + this._valuesInfo.length = 0; + }; + FasterDictionary.prototype.fastClear = function () { + if (this._freeValueCellIndex == 0) + return; + this._freeValueCellIndex = 0; + this._buckets.length = 0; + this._valuesInfo.length = 0; + }; + FasterDictionary.prototype.containsKey = function (key) { + if (this.tryFindIndex(key, { value: 0 })) { + return true; + } + return false; + }; + FasterDictionary.prototype.tryGetValue = function (key) { + var findIndex = { value: 0 }; + if (this.tryFindIndex(key, findIndex)) { + return this._values[findIndex.value]; + } + return null; + }; + FasterDictionary.prototype.tryFindIndex = function (key, findIndex) { + // 我把所有的索引都用偏移量+1来存储,这样在bucket list中0就意味着实际上不存在 + // 当读取时,偏移量必须再偏移-1才是真实的 + // 这样我就避免了将数组初始化为-1 + var hash = FasterDictionary.hash(key); + var bucketIndex = FasterDictionary.reduce(hash, this._buckets.length); + var valueIndex = es.NumberExtension.toNumber(this._buckets[bucketIndex]) - 1; + // 即使我们找到了一个现有的值,我们也需要确定它是我们所要求的值 + while (valueIndex != -1) { + if (this._valuesInfo[valueIndex].hashcode == hash && this._valuesInfo[valueIndex].key == key) { + findIndex.value = valueIndex; + return true; + } + valueIndex = this._valuesInfo[valueIndex].previous; + } + findIndex.value = 0; + return false; + }; + FasterDictionary.prototype.getDirectValue = function (index) { + return this._values[index]; + }; + FasterDictionary.prototype.getIndex = function (key) { + var findIndex = { value: 0 }; + if (this.tryFindIndex(key, findIndex)) + return findIndex.value; + throw new Error("未找到key"); + }; + FasterDictionary.updateLinkedList = function (index, valuesInfo) { + var next = valuesInfo[index].next; + var previous = valuesInfo[index].previous; + if (next != -1) + valuesInfo[next].previous = previous; + if (previous != -1) + valuesInfo[previous].next = next; + }; + FasterDictionary.hash = function (key) { + return es.HashHelpers.getHashCode(key); + }; + FasterDictionary.reduce = function (x, n) { + if (x >= n) + return x % n; + return x; + }; + return FasterDictionary; + }()); + es.FasterDictionary = FasterDictionary; + var FastNode = /** @class */ (function () { + function FastNode(key, hash, previousNode) { + if (previousNode === void 0) { previousNode = -1; } + this.key = key; + this.hashcode = hash; + this.previous = previousNode; + this.next = -1; + } + return FastNode; + }()); + es.FastNode = FastNode; +})(es || (es = {})); +var es; +(function (es) { + var Node = /** @class */ (function () { + // next为可选参数,如果不传则为undefined + function Node(element, next) { + this.element = element; + this.next = next; + } + return Node; + }()); + es.Node = Node; + function defaultEquals(a, b) { + return a === b; + } + es.defaultEquals = defaultEquals; + var LinkedList = /** @class */ (function () { + function LinkedList(equalsFn) { + if (equalsFn === void 0) { equalsFn = defaultEquals; } + // 初始化链表内部变量 + this.count = 0; + this.next = undefined; + this.equalsFn = equalsFn; + this.head = null; + } + // 链表尾部添加元素 + LinkedList.prototype.push = function (element) { + // 声明结点变量,将元素当作参数传入生成结点 + var node = new Node(element); + // 存储遍历到的链表元素 + var current; + if (this.head == null) { + // 链表为空,直接将链表头部赋值为结点变量 + this.head = node; + } + else { + // 链表不为空,我们只能拿到链表中第一个元素的引用 + current = this.head; + // 循环访问链表 + while (current.next != null) { + // 赋值遍历到的元素 + current = current.next; + } + // 此时已经得到了链表的最后一个元素(null),将链表的下一个元素赋值为结点变量。 + current.next = node; + } + // 链表长度自增 + this.count++; + }; + // 移除链表指定位置的元素 + LinkedList.prototype.removeAt = function (index) { + // 边界判断: 参数是否有效 + if (index >= 0 && index < this.count) { + // 获取当前链表头部元素 + var current = this.head; + // 移除第一项 + if (index === 0) { + this.head = current.next; + } + else { + // 获取目标参数上一个结点 + var previous = this.getElementAt(index - 1); + // 当前结点指向目标结点 + current = previous.next; + /** + * 目标结点元素已找到 + * previous.next指向目标结点 + * current.next指向undefined + * previous.next指向current.next即删除目标结点的元素 + */ + previous.next = current.next; + } + // 链表长度自减 + this.count--; + // 返回当前删除的目标结点 + return current.element; + } + return undefined; + }; + // 获取链表指定位置的结点 + LinkedList.prototype.getElementAt = function (index) { + // 参数校验 + if (index >= 0 && index <= this.count) { + // 获取链表头部元素 + var current = this.head; + // 从链表头部遍历至目标结点位置 + for (var i = 0; i < index && current != null; i++) { + // 当前结点指向下一个目标结点 + current = current.next; + } + // 返回目标结点数据 + return current; + } + return undefined; + }; + // 向链表中插入元素 + LinkedList.prototype.insert = function (element, index) { + // 参数有效性判断 + if (index >= 0 && index <= this.count) { + // 声明节点变量,将当前要插入的元素作为参数生成结点 + var node = new Node(element); + // 第一个位置添加元素 + if (index === 0) { + // 将节点变量(node)的下一个元素指向链表的头部元素 + node.next = this.head; + // 链表头部元素赋值为节点变量 + this.head = node; + } + else { + // 获取目标结点的上一个结点 + var previous = this.getElementAt(index - 1); + // 将节点变量的下一个元素指向目标节点 + node.next = previous.next; + /** + * 此时node中当前结点为要插入的值 + * next为原位置处的结点 + * 因此将当前结点赋值为node,就完成了结点插入操作 + */ + previous.next = node; + } + // 链表长度自增 + this.count++; + return true; + } + return false; + }; + // 根据元素获取其在链表中的索引 + LinkedList.prototype.indexOf = function (element) { + // 获取链表顶部元素 + var current = this.head; + // 遍历链表内的元素 + for (var i = 0; i < this.count && current != null; i++) { + // 判断当前链表中的结点与目标结点是否相等 + if (this.equalsFn(element, current.element)) { + // 返回索引 + return i; + } + // 当前结点指向下一个结点 + current = current.next; + } + // 目标元素不存在 + return -1; + }; + // 移除链表中的指定元素 + LinkedList.prototype.remove = function (element) { + // 获取element的索引,移除索引位置的元素 + this.removeAt(this.indexOf(element)); + }; + LinkedList.prototype.clear = function () { + this.head = undefined; + this.count = 0; + }; + // 获取链表长度 + LinkedList.prototype.size = function () { + return this.count; + }; + // 判断链表是否为空 + LinkedList.prototype.isEmpty = function () { + return this.size() === 0; + }; + // 获取链表头部元素 + LinkedList.prototype.getHead = function () { + return this.head; + }; + // 获取链表中的所有元素 + LinkedList.prototype.toString = function () { + if (this.head == null) { + return ""; + } + var objString = "" + this.head.element; + // 获取链表顶点的下一个结点 + var current = this.head.next; + // 遍历链表中的所有结点 + for (var i = 1; i < this.size() && current != null; i++) { + // 将当前结点的元素拼接到最终要生成的字符串对象中 + objString = objString + ", " + current.element; + // 当前结点指向链表的下一个元素 + current = current.next; + } + return objString; + }; + return LinkedList; + }()); + es.LinkedList = LinkedList; +})(es || (es = {})); +var es; +(function (es) { + /** + * 可以用于列表池的简单类 + */ + var ListPool = /** @class */ (function () { + function ListPool() { + } + /** + * 预热缓存,使用最大的cacheCount对象填充缓存 + * @param cacheCount + */ + ListPool.warmCache = function (cacheCount) { + cacheCount -= this._objectQueue.length; + if (cacheCount > 0) { + for (var i = 0; i < cacheCount; i++) { + this._objectQueue.unshift([]); + } + } + }; + /** + * 将缓存修剪为cacheCount项目 + * @param cacheCount + */ + ListPool.trimCache = function (cacheCount) { + while (cacheCount > this._objectQueue.length) + this._objectQueue.shift(); + }; + /** + * 清除缓存 + */ + ListPool.clearCache = function () { + this._objectQueue.length = 0; + }; + /** + * 如果可以的话,从堆栈中弹出一个项 + */ + ListPool.obtain = function () { + if (this._objectQueue.length > 0) + return this._objectQueue.shift(); + return []; + }; + /** + * 将项推回堆栈 + * @param obj + */ + ListPool.free = function (obj) { + this._objectQueue.unshift(obj); + obj.length = 0; + }; + ListPool._objectQueue = []; + return ListPool; + }()); + es.ListPool = ListPool; +})(es || (es = {})); +var es; +(function (es) { + /** + * 用于管理一对对象的简单DTO + */ + var Pair = /** @class */ (function () { + function Pair(first, second) { + this.first = first; + this.second = second; + } + Pair.prototype.clear = function () { + this.first = this.second = null; + }; + Pair.prototype.equals = function (other) { + // 这两种方法在功能上应该是等价的 + return this.first == other.first && this.second == other.second; + }; + Pair.prototype.getHashCode = function () { + return es.EqualityComparer.default().getHashCode(this.first) * 37 + + es.EqualityComparer.default().getHashCode(this.second); + }; + return Pair; + }()); + es.Pair = Pair; +})(es || (es = {})); +var es; +(function (es) { + /** + * 用于池任何对象 + */ + var Pool = /** @class */ (function () { + function Pool() { + } + /** + * 预热缓存,使用最大的cacheCount对象填充缓存 + * @param type + * @param cacheCount + */ + Pool.warmCache = function (type, cacheCount) { + cacheCount -= this._objectQueue.length; + if (cacheCount > 0) { + for (var i = 0; i < cacheCount; i++) { + this._objectQueue.unshift(new type()); + } + } + }; + /** + * 将缓存修剪为cacheCount项目 + * @param cacheCount + */ + Pool.trimCache = function (cacheCount) { + while (cacheCount > this._objectQueue.length) + this._objectQueue.shift(); + }; + /** + * 清除缓存 + */ + Pool.clearCache = function () { + this._objectQueue.length = 0; + }; + /** + * 如果可以的话,从堆栈中弹出一个项 + */ + Pool.obtain = function (type) { + if (this._objectQueue.length > 0) + return this._objectQueue.shift(); + return new type(); + }; + /** + * 将项推回堆栈 + * @param obj + */ + Pool.free = function (obj) { + this._objectQueue.unshift(obj); + if (es.isIPoolable(obj)) { + obj["reset"](); + } + }; + Pool._objectQueue = []; + return Pool; + }()); + es.Pool = Pool; + es.isIPoolable = function (props) { return typeof props['reset'] !== 'undefined'; }; +})(es || (es = {})); +var es; +(function (es) { + var Set = /** @class */ (function () { + function Set(source) { + var _this = this; + this.clear(); + if (source) + source.forEach(function (value) { + _this.add(value); + }); + } + Set.prototype.add = function (item) { + var _this = this; + var hashCode = this.getHashCode(item); + var bucket = this.buckets[hashCode]; + if (bucket === undefined) { + var newBucket = new Array(); + newBucket.push(item); + this.buckets[hashCode] = newBucket; + this.count = this.count + 1; + return true; + } + if (bucket.some(function (value) { return _this.areEqual(value, item); })) + return false; + bucket.push(item); + this.count = this.count + 1; + return true; + }; + ; + Set.prototype.remove = function (item) { + var _this = this; + var hashCode = this.getHashCode(item); + var bucket = this.buckets[hashCode]; + if (bucket === undefined) { + return false; + } + var result = false; + var newBucket = new Array(); + bucket.forEach(function (value) { + if (!_this.areEqual(value, item)) + newBucket.push(item); + else + result = true; + }); + this.buckets[hashCode] = newBucket; + if (result) + this.count = this.count - 1; + return result; + }; + Set.prototype.contains = function (item) { + return this.bucketsContains(this.buckets, item); + }; + ; + Set.prototype.getCount = function () { + return this.count; + }; + Set.prototype.clear = function () { + this.buckets = new Array(); + this.count = 0; + }; + Set.prototype.toArray = function () { + var result = new Array(); + this.buckets.forEach(function (value) { + value.forEach(function (inner) { + result.push(inner); + }); + }); + return result; + }; + /** + * 从当前集合中删除指定集合中的所有元素 + * @param other + */ + Set.prototype.exceptWith = function (other) { + var _this = this; + if (other) { + other.forEach(function (value) { + _this.remove(value); + }); + } + }; + /** + * 修改当前Set对象,使其只包含该对象和指定数组中的元素 + * @param other + */ + Set.prototype.intersectWith = function (other) { + var _this = this; + if (other) { + var otherBuckets_1 = this.buildInternalBuckets(other); + this.toArray().forEach(function (value) { + if (!_this.bucketsContains(otherBuckets_1.Buckets, value)) + _this.remove(value); + }); + } + else { + this.clear(); + } + }; + Set.prototype.unionWith = function (other) { + var _this = this; + other.forEach(function (value) { + _this.add(value); + }); + }; + /** + * 确定当前集合是否为指定集合或数组的子集 + * @param other + */ + Set.prototype.isSubsetOf = function (other) { + var _this = this; + var otherBuckets = this.buildInternalBuckets(other); + return this.toArray().every(function (value) { return _this.bucketsContains(otherBuckets.Buckets, value); }); + }; + /** + * 确定当前不可变排序集是否为指定集合的超集 + * @param other + */ + Set.prototype.isSupersetOf = function (other) { + var _this = this; + return other.every(function (value) { return _this.contains(value); }); + }; + Set.prototype.overlaps = function (other) { + var _this = this; + return other.some(function (value) { return _this.contains(value); }); + }; + Set.prototype.setEquals = function (other) { + var _this = this; + var otherBuckets = this.buildInternalBuckets(other); + if (otherBuckets.Count !== this.count) + return false; + return other.every(function (value) { return _this.contains(value); }); + }; + Set.prototype.buildInternalBuckets = function (source) { + var _this = this; + var internalBuckets = new Array(); + var internalCount = 0; + source.forEach(function (item) { + var hashCode = _this.getHashCode(item); + var bucket = internalBuckets[hashCode]; + if (bucket === undefined) { + var newBucket = new Array(); + newBucket.push(item); + internalBuckets[hashCode] = newBucket; + internalCount = internalCount + 1; + } + else if (!bucket.some(function (value) { return _this.areEqual(value, item); })) { + bucket.push(item); + internalCount = internalCount + 1; + } + }); + return { Buckets: internalBuckets, Count: internalCount }; + }; + Set.prototype.bucketsContains = function (internalBuckets, item) { + var _this = this; + var hashCode = this.getHashCode(item); + var bucket = internalBuckets[hashCode]; + if (bucket === undefined) { + return false; + } + return bucket.some(function (value) { return _this.areEqual(value, item); }); + }; + return Set; + }()); + var HashSet = /** @class */ (function (_super) { + __extends(HashSet, _super); + function HashSet(source) { + return _super.call(this, source) || this; + } + HashSet.prototype.getHashCode = function (item) { + return item.getHashCode(); + }; + HashSet.prototype.areEqual = function (value1, value2) { + return value1.equals(value2); + }; + return HashSet; + }(Set)); + es.HashSet = HashSet; +})(es || (es = {})); var ArrayUtils = /** @class */ (function () { function ArrayUtils() { } @@ -8081,455 +9129,6 @@ var es; es.EdgeExt = EdgeExt; })(es || (es = {})); var es; -(function (es) { - /** - * 用于包装事件的一个小类 - */ - var FuncPack = /** @class */ (function () { - function FuncPack(func, context) { - this.func = func; - this.context = context; - } - return FuncPack; - }()); - es.FuncPack = FuncPack; - /** - * 用于事件管理 - */ - var Emitter = /** @class */ (function () { - function Emitter() { - this._messageTable = new Map(); - } - /** - * 开始监听项 - * @param eventType 监听类型 - * @param handler 监听函数 - * @param context 监听上下文 - */ - Emitter.prototype.addObserver = function (eventType, handler, context) { - var list = this._messageTable.get(eventType); - if (!list) { - list = []; - this._messageTable.set(eventType, list); - } - if (list.findIndex(function (funcPack) { return funcPack.func == handler; }) != -1) - console.warn("您试图添加相同的观察者两次"); - list.push(new FuncPack(handler, context)); - }; - /** - * 移除监听项 - * @param eventType 事件类型 - * @param handler 事件函数 - */ - Emitter.prototype.removeObserver = function (eventType, handler) { - var messageData = this._messageTable.get(eventType); - var index = messageData.findIndex(function (data) { return data.func == handler; }); - if (index != -1) - new linq.List(messageData).removeAt(index); - }; - /** - * 触发该事件 - * @param eventType 事件类型 - * @param data 事件数据 - */ - Emitter.prototype.emit = function (eventType, data) { - var list = this._messageTable.get(eventType); - if (list) { - for (var i = list.length - 1; i >= 0; i--) - list[i].func.call(list[i].context, data); - } - }; - return Emitter; - }()); - es.Emitter = Emitter; -})(es || (es = {})); -var es; -(function (es) { - var Edge; - (function (Edge) { - Edge[Edge["top"] = 0] = "top"; - Edge[Edge["bottom"] = 1] = "bottom"; - Edge[Edge["left"] = 2] = "left"; - Edge[Edge["right"] = 3] = "right"; - })(Edge = es.Edge || (es.Edge = {})); -})(es || (es = {})); -var es; -(function (es) { - var Enumerable = /** @class */ (function () { - function Enumerable() { - } - /** - * 生成包含一个重复值的序列 - * @param element 要重复的值 - * @param count 在生成的序列中重复该值的次数 - */ - Enumerable.repeat = function (element, count) { - var result = []; - while (count--) { - result.push(element); - } - return result; - }; - return Enumerable; - }()); - es.Enumerable = Enumerable; -})(es || (es = {})); -var es; -(function (es) { - var EqualityComparer = /** @class */ (function () { - function EqualityComparer() { - } - EqualityComparer.default = function () { - return new EqualityComparer(); - }; - EqualityComparer.prototype.equals = function (x, y) { - if (typeof x["equals"] == 'function') { - return x["equals"](y); - } - else { - return x === y; - } - }; - EqualityComparer.prototype.getHashCode = function (o) { - var _this = this; - if (typeof o == 'number') { - return this._getHashCodeForNumber(o); - } - if (typeof o == 'string') { - return this._getHashCodeForString(o); - } - var hashCode = 385229220; - this.forOwn(o, function (value) { - if (typeof value == 'number') { - hashCode += _this._getHashCodeForNumber(value); - } - else if (typeof value == 'string') { - hashCode += _this._getHashCodeForString(value); - } - else if (typeof value == 'object') { - _this.forOwn(value, function () { - hashCode += _this.getHashCode(value); - }); - } - }); - return hashCode; - }; - EqualityComparer.prototype._getHashCodeForNumber = function (n) { - return n; - }; - EqualityComparer.prototype._getHashCodeForString = function (s) { - var hashCode = 385229220; - for (var i = 0; i < s.length; i++) { - hashCode = (hashCode * -1521134295) ^ s.charCodeAt(i); - } - return hashCode; - }; - EqualityComparer.prototype.forOwn = function (object, iteratee) { - object = Object(object); - Object.keys(object).forEach(function (key) { return iteratee(object[key], key, object); }); - }; - return EqualityComparer; - }()); - es.EqualityComparer = EqualityComparer; -})(es || (es = {})); -var es; -(function (es) { - var GlobalManager = /** @class */ (function () { - function GlobalManager() { - } - Object.defineProperty(GlobalManager.prototype, "enabled", { - /** - * 如果true则启用了GlobalManager。 - * 状态的改变会导致调用OnEnabled/OnDisable - */ - get: function () { - return this._enabled; - }, - /** - * 如果true则启用了GlobalManager。 - * 状态的改变会导致调用OnEnabled/OnDisable - * @param value - */ - set: function (value) { - this.setEnabled(value); - }, - enumerable: true, - configurable: true - }); - /** - * 启用/禁用这个GlobalManager - * @param isEnabled - */ - GlobalManager.prototype.setEnabled = function (isEnabled) { - if (this._enabled != isEnabled) { - this._enabled = isEnabled; - if (this._enabled) { - this.onEnabled(); - } - else { - this.onDisabled(); - } - } - }; - /** - * 此GlobalManager启用时调用 - */ - GlobalManager.prototype.onEnabled = function () { - }; - /** - * 此GlobalManager禁用时调用 - */ - GlobalManager.prototype.onDisabled = function () { - }; - /** - * 在frame .update之前调用每一帧 - */ - GlobalManager.prototype.update = function () { - }; - return GlobalManager; - }()); - es.GlobalManager = GlobalManager; -})(es || (es = {})); -var es; -(function (es) { - var Node = /** @class */ (function () { - // next为可选参数,如果不传则为undefined - function Node(element, next) { - this.element = element; - this.next = next; - } - return Node; - }()); - es.Node = Node; - function defaultEquals(a, b) { - return a === b; - } - es.defaultEquals = defaultEquals; - var LinkedList = /** @class */ (function () { - function LinkedList(equalsFn) { - if (equalsFn === void 0) { equalsFn = defaultEquals; } - // 初始化链表内部变量 - this.count = 0; - this.next = undefined; - this.equalsFn = equalsFn; - this.head = null; - } - // 链表尾部添加元素 - LinkedList.prototype.push = function (element) { - // 声明结点变量,将元素当作参数传入生成结点 - var node = new Node(element); - // 存储遍历到的链表元素 - var current; - if (this.head == null) { - // 链表为空,直接将链表头部赋值为结点变量 - this.head = node; - } - else { - // 链表不为空,我们只能拿到链表中第一个元素的引用 - current = this.head; - // 循环访问链表 - while (current.next != null) { - // 赋值遍历到的元素 - current = current.next; - } - // 此时已经得到了链表的最后一个元素(null),将链表的下一个元素赋值为结点变量。 - current.next = node; - } - // 链表长度自增 - this.count++; - }; - // 移除链表指定位置的元素 - LinkedList.prototype.removeAt = function (index) { - // 边界判断: 参数是否有效 - if (index >= 0 && index < this.count) { - // 获取当前链表头部元素 - var current = this.head; - // 移除第一项 - if (index === 0) { - this.head = current.next; - } - else { - // 获取目标参数上一个结点 - var previous = this.getElementAt(index - 1); - // 当前结点指向目标结点 - current = previous.next; - /** - * 目标结点元素已找到 - * previous.next指向目标结点 - * current.next指向undefined - * previous.next指向current.next即删除目标结点的元素 - */ - previous.next = current.next; - } - // 链表长度自减 - this.count--; - // 返回当前删除的目标结点 - return current.element; - } - return undefined; - }; - // 获取链表指定位置的结点 - LinkedList.prototype.getElementAt = function (index) { - // 参数校验 - if (index >= 0 && index <= this.count) { - // 获取链表头部元素 - var current = this.head; - // 从链表头部遍历至目标结点位置 - for (var i = 0; i < index && current != null; i++) { - // 当前结点指向下一个目标结点 - current = current.next; - } - // 返回目标结点数据 - return current; - } - return undefined; - }; - // 向链表中插入元素 - LinkedList.prototype.insert = function (element, index) { - // 参数有效性判断 - if (index >= 0 && index <= this.count) { - // 声明节点变量,将当前要插入的元素作为参数生成结点 - var node = new Node(element); - // 第一个位置添加元素 - if (index === 0) { - // 将节点变量(node)的下一个元素指向链表的头部元素 - node.next = this.head; - // 链表头部元素赋值为节点变量 - this.head = node; - } - else { - // 获取目标结点的上一个结点 - var previous = this.getElementAt(index - 1); - // 将节点变量的下一个元素指向目标节点 - node.next = previous.next; - /** - * 此时node中当前结点为要插入的值 - * next为原位置处的结点 - * 因此将当前结点赋值为node,就完成了结点插入操作 - */ - previous.next = node; - } - // 链表长度自增 - this.count++; - return true; - } - return false; - }; - // 根据元素获取其在链表中的索引 - LinkedList.prototype.indexOf = function (element) { - // 获取链表顶部元素 - var current = this.head; - // 遍历链表内的元素 - for (var i = 0; i < this.count && current != null; i++) { - // 判断当前链表中的结点与目标结点是否相等 - if (this.equalsFn(element, current.element)) { - // 返回索引 - return i; - } - // 当前结点指向下一个结点 - current = current.next; - } - // 目标元素不存在 - return -1; - }; - // 移除链表中的指定元素 - LinkedList.prototype.remove = function (element) { - // 获取element的索引,移除索引位置的元素 - this.removeAt(this.indexOf(element)); - }; - LinkedList.prototype.clear = function () { - this.head = undefined; - this.count = 0; - }; - // 获取链表长度 - LinkedList.prototype.size = function () { - return this.count; - }; - // 判断链表是否为空 - LinkedList.prototype.isEmpty = function () { - return this.size() === 0; - }; - // 获取链表头部元素 - LinkedList.prototype.getHead = function () { - return this.head; - }; - // 获取链表中的所有元素 - LinkedList.prototype.toString = function () { - if (this.head == null) { - return ""; - } - var objString = "" + this.head.element; - // 获取链表顶点的下一个结点 - var current = this.head.next; - // 遍历链表中的所有结点 - for (var i = 1; i < this.size() && current != null; i++) { - // 将当前结点的元素拼接到最终要生成的字符串对象中 - objString = objString + ", " + current.element; - // 当前结点指向链表的下一个元素 - current = current.next; - } - return objString; - }; - return LinkedList; - }()); - es.LinkedList = LinkedList; -})(es || (es = {})); -var es; -(function (es) { - /** - * 可以用于列表池的简单类 - */ - var ListPool = /** @class */ (function () { - function ListPool() { - } - /** - * 预热缓存,使用最大的cacheCount对象填充缓存 - * @param cacheCount - */ - ListPool.warmCache = function (cacheCount) { - cacheCount -= this._objectQueue.length; - if (cacheCount > 0) { - for (var i = 0; i < cacheCount; i++) { - this._objectQueue.unshift([]); - } - } - }; - /** - * 将缓存修剪为cacheCount项目 - * @param cacheCount - */ - ListPool.trimCache = function (cacheCount) { - while (cacheCount > this._objectQueue.length) - this._objectQueue.shift(); - }; - /** - * 清除缓存 - */ - ListPool.clearCache = function () { - this._objectQueue.length = 0; - }; - /** - * 如果可以的话,从堆栈中弹出一个项 - */ - ListPool.obtain = function () { - if (this._objectQueue.length > 0) - return this._objectQueue.shift(); - return []; - }; - /** - * 将项推回堆栈 - * @param obj - */ - ListPool.free = function (obj) { - this._objectQueue.unshift(obj); - obj.length = 0; - }; - ListPool._objectQueue = []; - return ListPool; - }()); - es.ListPool = ListPool; -})(es || (es = {})); -var es; (function (es) { var NumberExtension = /** @class */ (function () { function NumberExtension() { @@ -8543,90 +9142,6 @@ var es; }()); es.NumberExtension = NumberExtension; })(es || (es = {})); -var es; -(function (es) { - /** - * 用于管理一对对象的简单DTO - */ - var Pair = /** @class */ (function () { - function Pair(first, second) { - this.first = first; - this.second = second; - } - Pair.prototype.clear = function () { - this.first = this.second = null; - }; - Pair.prototype.equals = function (other) { - // 这两种方法在功能上应该是等价的 - return this.first == other.first && this.second == other.second; - }; - Pair.prototype.getHashCode = function () { - return es.EqualityComparer.default().getHashCode(this.first) * 37 + - es.EqualityComparer.default().getHashCode(this.second); - }; - return Pair; - }()); - es.Pair = Pair; -})(es || (es = {})); -var es; -(function (es) { - /** - * 用于池任何对象 - */ - var Pool = /** @class */ (function () { - function Pool() { - } - /** - * 预热缓存,使用最大的cacheCount对象填充缓存 - * @param type - * @param cacheCount - */ - Pool.warmCache = function (type, cacheCount) { - cacheCount -= this._objectQueue.length; - if (cacheCount > 0) { - for (var i = 0; i < cacheCount; i++) { - this._objectQueue.unshift(new type()); - } - } - }; - /** - * 将缓存修剪为cacheCount项目 - * @param cacheCount - */ - Pool.trimCache = function (cacheCount) { - while (cacheCount > this._objectQueue.length) - this._objectQueue.shift(); - }; - /** - * 清除缓存 - */ - Pool.clearCache = function () { - this._objectQueue.length = 0; - }; - /** - * 如果可以的话,从堆栈中弹出一个项 - */ - Pool.obtain = function (type) { - if (this._objectQueue.length > 0) - return this._objectQueue.shift(); - return new type(); - }; - /** - * 将项推回堆栈 - * @param obj - */ - Pool.free = function (obj) { - this._objectQueue.unshift(obj); - if (es.isIPoolable(obj)) { - obj["reset"](); - } - }; - Pool._objectQueue = []; - return Pool; - }()); - es.Pool = Pool; - es.isIPoolable = function (props) { return typeof props['reset'] !== 'undefined'; }; -})(es || (es = {})); var RandomUtils = /** @class */ (function () { function RandomUtils() { } @@ -8844,334 +9359,114 @@ var es; rect.width -= horizontalAmount * 2; rect.height -= verticalAmount * 2; }; + /** + * 给定多边形的点,计算其边界 + * @param points + */ + RectangleExt.boundsFromPolygonVector = 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.fromMinMaxVector(new es.Vector2(minX, minY), new es.Vector2(maxX, maxY)); + }; + /** + * 创建一个给定最小/最大点(左上角,右下角)的矩形 + * @param min + * @param max + */ + RectangleExt.fromMinMaxVector = function (min, max) { + return new es.Rectangle(min.x, min.y, max.x - min.x, max.y - min.y); + }; + /** + * 返回一个跨越当前边界和提供的delta位置的Bounds + * @param rect + * @param deltaX + * @param deltaY + */ + RectangleExt.getSweptBroadphaseBounds = function (rect, deltaX, deltaY) { + var broadphasebox = es.Rectangle.empty; + broadphasebox.x = deltaX > 0 ? rect.x : rect.x + deltaX; + broadphasebox.y = deltaY > 0 ? rect.y : rect.y + deltaY; + broadphasebox.width = deltaX > 0 ? deltaX + rect.width : rect.width - deltaX; + broadphasebox.height = deltaY > 0 ? deltaY + rect.height : rect.height - deltaY; + return broadphasebox; + }; + /** + * 如果矩形发生碰撞,返回true + * moveX和moveY将返回b1为避免碰撞而必须移动的移动量 + * @param rect + * @param other + * @param moveX + * @param moveY + */ + RectangleExt.prototype.collisionCheck = function (rect, other, moveX, moveY) { + moveX.value = moveY.value = 0; + var l = other.x - (rect.x + rect.width); + var r = (other.x + other.width) - rect.x; + var t = other.y - (rect.y + rect.height); + var b = (other.y + other.height) - rect.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。 + */ + RectangleExt.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); + }; 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) { - var Set = /** @class */ (function () { - function Set(source) { - var _this = this; - this.clear(); - if (source) - source.forEach(function (value) { - _this.add(value); - }); - } - Set.prototype.add = function (item) { - var _this = this; - var hashCode = this.getHashCode(item); - var bucket = this.buckets[hashCode]; - if (bucket === undefined) { - var newBucket = new Array(); - newBucket.push(item); - this.buckets[hashCode] = newBucket; - this.count = this.count + 1; - return true; - } - if (bucket.some(function (value) { return _this.areEqual(value, item); })) - return false; - bucket.push(item); - this.count = this.count + 1; - return true; - }; - ; - Set.prototype.remove = function (item) { - var _this = this; - var hashCode = this.getHashCode(item); - var bucket = this.buckets[hashCode]; - if (bucket === undefined) { - return false; - } - var result = false; - var newBucket = new Array(); - bucket.forEach(function (value) { - if (!_this.areEqual(value, item)) - newBucket.push(item); - else - result = true; - }); - this.buckets[hashCode] = newBucket; - if (result) - this.count = this.count - 1; - return result; - }; - Set.prototype.contains = function (item) { - return this.bucketsContains(this.buckets, item); - }; - ; - Set.prototype.getCount = function () { - return this.count; - }; - Set.prototype.clear = function () { - this.buckets = new Array(); - this.count = 0; - }; - Set.prototype.toArray = function () { - var result = new Array(); - this.buckets.forEach(function (value) { - value.forEach(function (inner) { - result.push(inner); - }); - }); - return result; - }; - /** - * 从当前集合中删除指定集合中的所有元素 - * @param other - */ - Set.prototype.exceptWith = function (other) { - var _this = this; - if (other) { - other.forEach(function (value) { - _this.remove(value); - }); - } - }; - /** - * 修改当前Set对象,使其只包含该对象和指定数组中的元素 - * @param other - */ - Set.prototype.intersectWith = function (other) { - var _this = this; - if (other) { - var otherBuckets_1 = this.buildInternalBuckets(other); - this.toArray().forEach(function (value) { - if (!_this.bucketsContains(otherBuckets_1.Buckets, value)) - _this.remove(value); - }); - } - else { - this.clear(); - } - }; - Set.prototype.unionWith = function (other) { - var _this = this; - other.forEach(function (value) { - _this.add(value); - }); - }; - /** - * 确定当前集合是否为指定集合或数组的子集 - * @param other - */ - Set.prototype.isSubsetOf = function (other) { - var _this = this; - var otherBuckets = this.buildInternalBuckets(other); - return this.toArray().every(function (value) { return _this.bucketsContains(otherBuckets.Buckets, value); }); - }; - /** - * 确定当前不可变排序集是否为指定集合的超集 - * @param other - */ - Set.prototype.isSupersetOf = function (other) { - var _this = this; - return other.every(function (value) { return _this.contains(value); }); - }; - Set.prototype.overlaps = function (other) { - var _this = this; - return other.some(function (value) { return _this.contains(value); }); - }; - Set.prototype.setEquals = function (other) { - var _this = this; - var otherBuckets = this.buildInternalBuckets(other); - if (otherBuckets.Count !== this.count) - return false; - return other.every(function (value) { return _this.contains(value); }); - }; - Set.prototype.buildInternalBuckets = function (source) { - var _this = this; - var internalBuckets = new Array(); - var internalCount = 0; - source.forEach(function (item) { - var hashCode = _this.getHashCode(item); - var bucket = internalBuckets[hashCode]; - if (bucket === undefined) { - var newBucket = new Array(); - newBucket.push(item); - internalBuckets[hashCode] = newBucket; - internalCount = internalCount + 1; - } - else if (!bucket.some(function (value) { return _this.areEqual(value, item); })) { - bucket.push(item); - internalCount = internalCount + 1; - } - }); - return { Buckets: internalBuckets, Count: internalCount }; - }; - Set.prototype.bucketsContains = function (internalBuckets, item) { - var _this = this; - var hashCode = this.getHashCode(item); - var bucket = internalBuckets[hashCode]; - if (bucket === undefined) { - return false; - } - return bucket.some(function (value) { return _this.areEqual(value, item); }); - }; - return Set; - }()); - var HashSet = /** @class */ (function (_super) { - __extends(HashSet, _super); - function HashSet(source) { - return _super.call(this, source) || this; - } - HashSet.prototype.getHashCode = function (item) { - return item.getHashCode(); - }; - HashSet.prototype.areEqual = function (value1, value2) { - return value1.equals(value2); - }; - return HashSet; - }(Set)); - es.HashSet = HashSet; -})(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) { - /** - * 简单的剪耳三角测量器,最终的三角形将出现在triangleIndices列表中。 - */ - 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) { - // 如果点在AB的右边,那么外边的三角形是 - if (es.Vector2Ext.cross(es.Vector2.subtract(point, a), es.Vector2.subtract(b, a)) < 0) - return false; - // 如果点在BC的右边,则在三角形的外侧 - if (es.Vector2Ext.cross(es.Vector2.subtract(point, b), es.Vector2.subtract(c, b)) < 0) - return false; - // 如果点在ca的右边,则在三角形的外面 - 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.length = Math.max(this._triNext.length * 2, count); - } - if (this._triPrev.length < count) { - this._triPrev.reverse(); - this._triPrev.length = 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() { @@ -9324,190 +9619,6 @@ var WebGLUtils = /** @class */ (function () { }; 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 __spread(this._completeSlices, [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 linq; (function (linq) { var Enumerable = /** @class */ (function () { @@ -10104,9 +10215,9 @@ var es; }()); es.Segment = Segment; })(es || (es = {})); -/// +/// var es; -/// +/// (function (es) { /** * 类,它可以计算出一个网格,表示从给定的一组遮挡物的原点可以看到哪些区域。使用方法如下。 diff --git a/source/bin/framework.min.js b/source/bin/framework.min.js index fbd982af..f3456227 100644 --- a/source/bin/framework.min.js +++ b/source/bin/framework.min.js @@ -1 +1 @@ -window.es={};var __awaiter=this&&this.__awaiter||function(t,e,n,i){return new(n||(n=Promise))(function(r,o){function s(t){try{c(i.next(t))}catch(t){o(t)}}function a(t){try{c(i.throw(t))}catch(t){o(t)}}function c(t){t.done?r(t.value):new n(function(e){e(t.value)}).then(s,a)}c((i=i.apply(t,e||[])).next())})},__generator=this&&this.__generator||function(t,e){var n,i,r,o,s={label:0,sent:function(){if(1&r[0])throw r[1];return r[1]},trys:[],ops:[]};return o={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function a(o){return function(a){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,i&&(r=2&o[0]?i.return:o[0]?i.throw||((r=i.return)&&r.call(i),0):i.next)&&!(r=r.call(i,o[1])).done)return r;switch(i=0,r&&(o=[2&o[0],r.value]),o[0]){case 0:case 1:r=o;break;case 4:return s.label++,{value:o[1],done:!1};case 5:s.label++,i=o[1],o=[0];continue;case 7:o=s.ops.pop(),s.trys.pop();continue;default:if(!(r=(r=s.trys).length>0&&r[r.length-1])&&(6===o[0]||2===o[0])){s=0;continue}if(3===o[0]&&(!r||o[1]>r[0]&&o[1]=t.length&&(t=void 0),{value:t&&t[n++],done:!t}}}},__read=this&&this.__read||function(t,e){var n="function"==typeof Symbol&&t[Symbol.iterator];if(!n)return t;var i,r,o=n.call(t),s=[];try{for(;(void 0===e||e-- >0)&&!(i=o.next()).done;)s.push(i.value)}catch(t){r={error:t}}finally{try{i&&!i.done&&(n=o.return)&&n.call(o)}finally{if(r)throw r.error}}return s},__spread=this&&this.__spread||function(){for(var t=[],e=0;e=1){var e=window.performance.memory;null!=e&&(this._totalMemory=Number((e.totalJSHeapSize/1048576).toFixed(2))),this._titleMemory&&this._titleMemory(this._totalMemory,this._frameCounter),this._frameCounter=0,this._frameCounterElapsedTime-=1}},e.prototype.onSceneChanged=function(){e.emitter.emit(t.CoreEvents.SceneChanged),t.Time.sceneChanged()},e.prototype.onGraphicsDeviceReset=function(){null!=this._graphicsDeviceChangeTimer?this._graphicsDeviceChangeTimer.reset():this._graphicsDeviceChangeTimer=e.schedule(.05,!1,this,function(n){n.context._graphicsDeviceChangeTimer=null,e.emitter.emit(t.CoreEvents.GraphicsDeviceReset)})},e.prototype.initialize=function(){},e.prototype.update=function(e){return __awaiter(this,void 0,void 0,function(){var n;return __generator(this,function(i){if(null!=e&&t.Time.update(e),null!=this._scene){for(n=this._globalManagers.length-1;n>=0;n--)this._globalManagers.buffer[n].enabled&&this._globalManagers.buffer[n].update();this._scene.update(),null!=this._nextScene&&(this._scene.end(),this._scene=this._nextScene,this._nextScene=null,this.onSceneChanged(),this._scene.begin())}return this.startDebugDraw(),[2]})})},e.pauseOnFocusLost=!0,e.debugRenderEndabled=!1,e}();t.Core=e}(es||(es={})),function(t){!function(t){t[t.GraphicsDeviceReset=0]="GraphicsDeviceReset",t[t.SceneChanged=1]="SceneChanged",t[t.OrientationChanged=2]="OrientationChanged",t[t.FrameUpdated=3]="FrameUpdated"}(t.CoreEvents||(t.CoreEvents={}))}(es||(es={})),function(t){var e=function(){function t(){}return t.prototype.compare=function(t,e){var n=t.updateOrder-e.updateOrder;return 0==n&&(n=t.id-e.id),n},t}();t.EntityComparer=e;var n=function(){function n(e){this.updateInterval=1,this._tag=0,this._enabled=!0,this._updateOrder=0,this.components=new t.ComponentList(this),this.transform=new t.Transform(this),this.name=e,this.id=n._idGenerator++,t.Core.entitySystemsEnabled&&(this.componentBits=new t.BitSet)}return Object.defineProperty(n.prototype,"isDestroyed",{get:function(){return this._isDestroyed},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"tag",{get:function(){return this._tag},set:function(t){this.setTag(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"enabled",{get:function(){return this._enabled},set:function(t){this.setEnabled(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"updateOrder",{get:function(){return this._updateOrder},set:function(t){this.setUpdateOrder(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"parent",{get:function(){return this.transform.parent},set:function(t){this.transform.setParent(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"childCount",{get:function(){return this.transform.childCount},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"position",{get:function(){return this.transform.position},set:function(t){this.transform.setPosition(t.x,t.y)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"localPosition",{get:function(){return this.transform.localPosition},set:function(t){this.transform.setLocalPosition(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"rotation",{get:function(){return this.transform.rotation},set:function(t){this.transform.setRotation(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"rotationDegrees",{get:function(){return this.transform.rotationDegrees},set:function(t){this.transform.setRotationDegrees(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"localRotation",{get:function(){return this.transform.localRotation},set:function(t){this.transform.setLocalRotation(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"localRotationDegrees",{get:function(){return this.transform.localRotationDegrees},set:function(t){this.transform.setLocalRotationDegrees(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"scale",{get:function(){return this.transform.scale},set:function(t){this.transform.setScale(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"localScale",{get:function(){return this.transform.localScale},set:function(t){this.transform.setLocalScale(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"worldInverseTransform",{get:function(){return this.transform.worldInverseTransform},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"localToWorldTransform",{get:function(){return this.transform.localToWorldTransform},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"worldToLocalTransform",{get:function(){return this.transform.worldToLocalTransform},enumerable:!0,configurable:!0}),n.prototype.onTransformChanged=function(t){this.components.onEntityTransformChanged(t)},n.prototype.setTag=function(t){return this._tag!=t&&(this.scene&&this.scene.entities.removeFromTagList(this),this._tag=t,this.scene&&this.scene.entities.addToTagList(this)),this},n.prototype.setEnabled=function(t){return this._enabled!=t&&(this._enabled=t,this._enabled?this.components.onEntityEnabled():this.components.onEntityDisabled()),this},n.prototype.setUpdateOrder=function(t){if(this._updateOrder!=t)return this._updateOrder=t,this.scene&&(this.scene.entities.markEntityListUnsorted(),this.scene.entities.markTagUnsorted(this.tag)),this},n.prototype.destroy=function(){this._isDestroyed=!0,this.scene.entities.remove(this),this.transform.parent=null;for(var t=this.transform.childCount-1;t>=0;t--){this.transform.getChild(t).entity.destroy()}},n.prototype.detachFromScene=function(){this.scene.entities.remove(this),this.components.deregisterAllComponents();for(var t=0;t=0;t--)this._sceneComponents.buffer[t].enabled&&this._sceneComponents.buffer[t].update();null!=this.entityProcessors&&this.entityProcessors.update(),this.entities.update(),null!=this.entityProcessors&&this.entityProcessors.lateUpdate()},e.prototype.addSceneComponent=function(t){return t.scene=this,t.onEnabled(),this._sceneComponents.add(t),this._sceneComponents.sort(t),t},e.prototype.getSceneComponent=function(t){for(var e=0;ee.x?-1:1,i=t.Vector2.normalize(t.Vector2.subtract(this.position,e));this.rotation=n*Math.acos(t.Vector2.dot(i,t.Vector2.unitY))},n.prototype.setLocalRotation=function(t){return this._localRotation=t,this._localDirty=this._positionDirty=this._localPositionDirty=this._localRotationDirty=this._localScaleDirty=!0,this.setDirty(e.rotationDirty),this},n.prototype.setLocalRotationDegrees=function(e){return this.setLocalRotation(t.MathHelper.toRadians(e))},n.prototype.setScale=function(e){return this._scale=e,this.parent?this.localScale=t.Vector2.divide(e,this.parent._scale):this.localScale=e,this},n.prototype.setLocalScale=function(t){return this._localScale=t,this._localDirty=this._positionDirty=this._localScaleDirty=!0,this.setDirty(e.scaleDirty),this},n.prototype.roundPosition=function(){this.position=this._position.round()},n.prototype.updateTransform=function(){this.hierarchyDirty!=e.clean&&(null!=this.parent&&this.parent.updateTransform(),this._localDirty&&(this._localPositionDirty&&(this._translationMatrix=t.Matrix2D.createTranslation(this._localPosition.x,this._localPosition.y),this._localPositionDirty=!1),this._localRotationDirty&&(this._rotationMatrix=t.Matrix2D.createRotation(this._localRotation),this._localRotationDirty=!1),this._localScaleDirty&&(this._scaleMatrix=t.Matrix2D.createScale(this._localScale.x,this._localScale.y),this._localScaleDirty=!1),this._localTransform=this._scaleMatrix.multiply(this._rotationMatrix),this._localTransform=this._localTransform.multiply(this._translationMatrix),null==this.parent&&(this._worldTransform=this._localTransform,this._rotation=this._localRotation,this._scale=this._localScale,this._worldInverseDirty=!0),this._localDirty=!1),null!=this.parent&&(this._worldTransform=this._localTransform.multiply(this.parent._worldTransform),this._rotation=this._localRotation+this.parent._rotation,this._scale=t.Vector2.multiply(this.parent._scale,this._localScale),this._worldInverseDirty=!0),this._worldToLocalDirty=!0,this._positionDirty=!0,this.hierarchyDirty=e.clean)},n.prototype.setDirty=function(e){if(0==(this.hierarchyDirty&e)){switch(this.hierarchyDirty|=e,e){case t.DirtyType.positionDirty:this.entity.onTransformChanged(transform.Component.position);break;case t.DirtyType.rotationDirty:this.entity.onTransformChanged(transform.Component.rotation);break;case t.DirtyType.scaleDirty:this.entity.onTransformChanged(transform.Component.scale)}for(var n=0;n0?this._cache.shift():new this._type}catch(t){throw new Error(this._type+t)}},t.prototype.free=function(t){t.reset(),this._cache.push(t)},t}();t.ComponentPool=e}(es||(es={})),function(t){var e=function(){function t(){}return t.prototype.compare=function(t,e){return t.updateOrder-e.updateOrder},t}();t.IUpdatableComparer=e,t.isIUpdatable=function(t){return void 0!==t.update}}(es||(es={})),function(t){var e=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return __extends(e,t),e}(t.Component);t.PooledComponent=e}(es||(es={})),function(t){var e=function(){function e(){this.updateOrder=0,this._enabled=!0}return Object.defineProperty(e.prototype,"enabled",{get:function(){return this._enabled},set:function(t){this.setEnabled(t)},enumerable:!0,configurable:!0}),e.prototype.onEnabled=function(){},e.prototype.onDisabled=function(){},e.prototype.onRemovedFromScene=function(){},e.prototype.update=function(){},e.prototype.setEnabled=function(t){return this._enabled!=t&&(this._enabled=t,this._enabled?this.onEnabled():this.onDisabled()),this},e.prototype.setUpdateOrder=function(e){return this.updateOrder!=e&&(this.updateOrder=e,t.Core.scene._sceneComponents.sort(this)),this},e.prototype.compare=function(t){return this.updateOrder-t.updateOrder},e}();t.SceneComponent=e}(es||(es={})),function(t){var e=function(e){function n(){var n=e.call(this)||this;return n.shouldUseGravity=!0,n.velocity=new t.Vector2,n._mass=10,n._elasticity=.5,n._friction=.5,n._glue=.01,n._inverseMass=0,n._inverseMass=1/n._mass,n}return __extends(n,e),Object.defineProperty(n.prototype,"mass",{get:function(){return this._mass},set:function(t){this.setMass(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"elasticity",{get:function(){return this._elasticity},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"elasticiy",{set:function(t){this.setElasticity(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"friction",{get:function(){return this._friction},set:function(t){this.setFriction(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"glue",{get:function(){return this._glue},set:function(t){this.setGlue(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"isImmovable",{get:function(){return this._mass<1e-4},enumerable:!0,configurable:!0}),n.prototype.setMass=function(e){return this._mass=t.MathHelper.clamp(e,0,Number.MAX_VALUE),this._mass>1e-4?this._inverseMass=1/this._mass:this._inverseMass=0,this},n.prototype.setElasticity=function(e){return this._elasticity=t.MathHelper.clamp01(e),this},n.prototype.setFriction=function(e){return this._friction=t.MathHelper.clamp01(e),this},n.prototype.setGlue=function(e){return this._glue=t.MathHelper.clamp(e,0,10),this},n.prototype.addImpulse=function(e){this.isImmovable||(this.velocity=t.Vector2.add(this.velocity,t.Vector2.multiply(e,new t.Vector2(1e5)).multiply(new t.Vector2(this._inverseMass*t.Time.deltaTime))))},n.prototype.onAddedToEntity=function(){this._collider=this.entity.getComponent(t.Collider),null==this._collider&&console.warn("ArcadeRigidbody 没有 Collider。ArcadeRigidbody需要一个Collider!")},n.prototype.update=function(){var e,i;if(this.isImmovable||null==this._collider)this.velocity=t.Vector2.zero;else{this.shouldUseGravity&&(this.velocity=t.Vector2.add(this.velocity,t.Vector2.multiply(t.Physics.gravity,new t.Vector2(t.Time.deltaTime)))),this.entity.transform.position=t.Vector2.add(this.entity.transform.position,t.Vector2.multiply(this.velocity,new t.Vector2(t.Time.deltaTime)));var r=new t.CollisionResult,o=t.Physics.boxcastBroadphaseExcludingSelfNonRect(this._collider,this._collider.collidesWithLayers.value);try{for(var s=__values(o),a=s.next();!a.done;a=s.next()){var c=a.value;if(!c.entity.equals(this.entity)&&this._collider.collidesWithNonMotion(c,r)){var h=c.entity.getComponent(n);if(null!=h)this.processOverlap(h,r.minimumTranslationVector),this.processCollision(h,r.minimumTranslationVector);else{this.entity.transform.position=t.Vector2.subtract(this.entity.transform.position,r.minimumTranslationVector);var u=this.velocity.clone();this.calculateResponseVelocity(u,r.minimumTranslationVector,u),this.velocity=t.Vector2.add(this.velocity,u)}}}}catch(t){e={error:t}}finally{try{a&&!a.done&&(i=s.return)&&i.call(s)}finally{if(e)throw e.error}}}},n.prototype.processOverlap=function(e,n){this.isImmovable?e.entity.transform.position=t.Vector2.add(e.entity.transform.position,n):e.isImmovable?this.entity.transform.position=t.Vector2.subtract(this.entity.transform.position,n):(this.entity.transform.position=t.Vector2.subtract(this.entity.transform.position,t.Vector2.multiply(n,t.Vector2Ext.halfVector())),e.entity.transform.position=t.Vector2.add(e.entity.transform.position,t.Vector2.multiply(n,t.Vector2Ext.halfVector())))},n.prototype.processCollision=function(e,n){var i=t.Vector2.subtract(this.velocity,e.velocity);this.calculateResponseVelocity(i,n,i);var r=this._inverseMass+e._inverseMass,o=this._inverseMass/r,s=e._inverseMass/r;this.velocity=t.Vector2.add(this.velocity,new t.Vector2(i.x*o,i.y*o)),e.velocity=t.Vector2.subtract(e.velocity,new t.Vector2(i.x*s,i.y*s))},n.prototype.calculateResponseVelocity=function(e,n,i){void 0===i&&(i=new t.Vector2);var r=t.Vector2.multiply(n,new t.Vector2(-1)),o=t.Vector2.normalize(r),s=t.Vector2.dot(e,o),a=new t.Vector2(o.x*s,o.y*s),c=t.Vector2.subtract(e,a);s>0&&(a=t.Vector2.zero);var h=this._friction;c.lengthSquared()>6;0!=(e&t.LONG_MASK)&&n++,this._bits=new Array(n),this._bits.fill(0)}return t.prototype.and=function(t){for(var e,n=Math.min(this._bits.length,t._bits.length),i=0;i=0;)this._bits[e]&=~t._bits[e]},t.prototype.cardinality=function(){for(var t=0,e=this._bits.length-1;e>=0;e--){var n=this._bits[e];if(0!=n)if(-1!=n){var i=((n=((n=(n>>1&0x5555555555555400)+(0x5555555555555400&n))>>2&0x3333333333333400)+(0x3333333333333400&n))>>32)+n>>>0;t+=((i=((i=(i>>4&252645135)+(252645135&i))>>8&16711935)+(16711935&i))>>16&65535)+(65535&i)}else t+=64}return t},t.prototype.clear=function(t){if(null!=t){var e=t>>6;this.ensure(e),this._bits[e]&=~(1<>6;return!(e>=this._bits.length)&&0!=(this._bits[e]&1<=0;)if(0!=(this._bits[e]&t._bits[e]))return!0;return!1},t.prototype.isEmpty=function(){for(var t=this._bits.length-1;t>=0;t--)if(this._bits[t])return!1;return!0},t.prototype.nextSetBit=function(t){for(var e=t>>6,n=1<>6;this.ensure(n),this._bits[n]|=1<=this._bits.length){var e=this._bits.length;this._bits.length=t+1,this._bits.fill(0,e,t+1)}},t.LONG_MASK=63,t}();t.BitSet=e}(es||(es={})),function(t){var e=function(){function e(e){this._components=new t.FastList,this._updatableComponents=new t.FastList,this._componentsToAdd=[],this._componentsToRemove=[],this._tempBufferList=[],this._entity=e}return Object.defineProperty(e.prototype,"count",{get:function(){return this._components.length},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"buffer",{get:function(){return this._components.buffer},enumerable:!0,configurable:!0}),e.prototype.markEntityListUnsorted=function(){this._isComponentListUnsorted=!0},e.prototype.add=function(t){this._componentsToAdd.push(t)},e.prototype.remove=function(t){var e=new linq.List(this._componentsToRemove),n=new linq.List(this._componentsToAdd);e.contains(t)&&console.warn("您正在尝试删除一个您已经删除的组件("+t+")"),n.contains(t)?n.remove(t):e.add(t)},e.prototype.removeAllComponents=function(){for(var t=0;t0){for(var n=0;n0){n=0;for(var i=this._componentsToAdd.length;n0&&(this._entitiesToRemove.toArray().forEach(function(n){e.removeFromTagList(n),e._entities.remove(n),n.onRemovedFromScene(),n.scene=null,t.Core.entitySystemsEnabled&&e.scene.entityProcessors.onEntityRemoved(n)}),this._entitiesToRemove.clear()),this._entitiesToAdded.getCount()>0&&(this._entitiesToAdded.toArray().forEach(function(n){e._entities.add(n),n.scene=e.scene,e.addToTagList(n),t.Core.entitySystemsEnabled&&e.scene.entityProcessors.onEntityAdded(n)}),this._entitiesToAdded.toArray().forEach(function(t){t.onAddedToScene()}),this._entitiesToAdded.clear(),this._isEntityListUnsorted=!0),this._isEntityListUnsorted&&(this._entities.sort(t.Entity.entityComparer),this._isEntityListUnsorted=!1),this._unsortedTags.size>0&&(this._unsortedTags.forEach(function(t){return e._entityDict.get(t).sort(function(t,e){return t.compareTo(e)})}),this._unsortedTags.clear())},e.prototype.findEntity=function(t){for(var e=0;ethis._buckets.length){this._buckets=new Array(t.HashHelpers.expandPrime(this._collisions)),this._collisions=0;for(var l=0;l=e?t%e:t},e}();t.FasterDictionary=e;var n=function(){return function(t,e,n){void 0===n&&(n=-1),this.key=t,this.hashcode=e,this.previous=n,this.next=-1}}();t.FastNode=n}(es||(es={})),function(t){var e=function(){function e(t){void 0===t&&(t=5),this.length=0,this.buffer=new Array(t)}return e.prototype.clear=function(){this.buffer.length=0,this.length=0},e.prototype.reset=function(){this.length=0},e.prototype.add=function(t){this.length==this.buffer.length&&(this.buffer.length=Math.max(this.buffer.length<<1,10)),this.buffer[this.length++]=t},e.prototype.remove=function(e){for(var n=t.EqualityComparer.default(),i=0;i=this.length)throw new Error("index超出范围!");this.length--,new linq.List(this.buffer).removeAt(t)},e.prototype.contains=function(e){for(var n=t.EqualityComparer.default(),i=0;i=this.buffer.length&&(this.buffer.length=Math.max(this.buffer.length<<1,this.length+t))},e.prototype.addRange=function(t){var e,n;try{for(var i=__values(t),r=i.next();!r.done;r=i.next()){var o=r.value;this.add(o)}}catch(t){e={error:t}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(e)throw e.error}}},e.prototype.sort=function(t){this.buffer.sort(t.compare)},e}();t.FastList=e}(es||(es={})),function(t){var e=function(){function t(){}return t.isPrime=function(t){if(0!=(1&t)){for(var e=Math.sqrt(t),n=3;n<=e;n+=2)if(0==(t&n))return!1;return!0}return 2==t},t.getPrime=function(t){if(t<0)throw new Error("参数错误 min不能小于0");for(var e=0;e=t)return n}for(e=1|t;ethis.maxPrimeArrayLength&&this.maxPrimeArrayLength>t?this.maxPrimeArrayLength:this.getPrime(e)},t.getHashCode=function(t){var e,n=0;if(0==(e="object"==typeof t?JSON.stringify(t):t.toString()).length)return n;for(var i=0;i=0;e=this.allSet.nextSetBit(e+1))if(!t.get(e))return!1;return!(!this.exclusionSet.isEmpty()&&this.exclusionSet.intersects(t))&&!(!this.oneSet.isEmpty()&&!this.oneSet.intersects(t))},e.prototype.all=function(){for(var e=this,n=[],i=0;i=e)return t;var i=!1;"-"==t.substr(0,1)&&(i=!0,t=t.substr(1));for(var r=e-n,o=0;o1?this.reverse(t.substring(1))+t.substring(0,1):t},t.cutOff=function(t,e,n,i){void 0===i&&(i=!0),e=Math.floor(e),n=Math.floor(n);var r=t.length;e>r&&(e=r);var o,s=e,a=e+n;return i?o=t.substring(0,s)+t.substr(a,r):(a=(s=r-1-e-n)+n,o=t.substring(0,s+1)+t.substr(a+1,r)),o},t.strReplace=function(t,e){for(var n=0,i=e.length;n",">",'"',""","'","'","®","®","©","©","™","™"],t}();!function(t){var e=function(){function t(){}return t.update=function(t){var e=(t-this._lastTime)/1e3;this.totalTime+=e,this.deltaTime=e*this.timeScale,this.unscaledDeltaTime=e,this.timeSinceSceneLoad+=e,this.frameCount++,this._lastTime=t},t.sceneChanged=function(){this.timeSinceSceneLoad=0},t.checkEvery=function(t){return this.timeSinceSceneLoad/t>(this.timeSinceSceneLoad-this.deltaTime)/t},t.deltaTime=0,t.timeScale=1,t.frameCount=0,t._lastTime=0,t}();t.Time=e}(es||(es={}));var TimeUtils=function(){function t(){}return t.monthId=function(t){void 0===t&&(t=null);var e=(t=t||new Date).getFullYear(),n=t.getMonth()+1;return parseInt(e+(n<10?"0":"")+n)},t.dateId=function(t){void 0===t&&(t=null);var e=(t=t||new Date).getMonth()+1,n=e<10?"0":"",i=t.getDate(),r=i<10?"0":"";return parseInt(t.getFullYear()+n+e+r+i)},t.weekId=function(t,e){void 0===t&&(t=null),void 0===e&&(e=!0),t=t||new Date;var n=new Date;n.setTime(t.getTime()),n.setDate(1),n.setMonth(0);var i=n.getFullYear(),r=n.getDay();0==r&&(r=7);var o=!1;r<=4?(o=r>1,n.setDate(n.getDate()-(r-1))):n.setDate(n.getDate()+7-r+1);var s=this.diffDay(t,n,!1);if(s<0)return n.setDate(1),n.setMonth(0),n.setDate(n.getDate()-1),this.weekId(n,!1);var a=s/7,c=Math.floor(a)+1;if(53==c){n.setTime(t.getTime()),n.setDate(n.getDate()-1);var h=n.getDay();if(0==h&&(h=7),e&&(!o||h<4))return n.setFullYear(n.getFullYear()+1),n.setDate(1),n.setMonth(0),this.weekId(n,!1)}return parseInt(i+"00"+(c>9?"":"0")+c)},t.diffDay=function(t,e,n){void 0===n&&(n=!1);var i=(t.getTime()-e.getTime())/864e5;return n?Math.ceil(i):Math.floor(i)},t.getFirstDayOfWeek=function(t){var e=(t=t||new Date).getDay()||7;return new Date(t.getFullYear(),t.getMonth(),t.getDate()+1-e,0,0,0,0)},t.getFirstOfDay=function(t){return(t=t||new Date).setHours(0,0,0,0),t},t.getNextFirstOfDay=function(t){return new Date(this.getFirstOfDay(t).getTime()+864e5)},t.formatDate=function(t){var e=t.getFullYear(),n=t.getMonth()+1;n=n<10?"0"+n:n;var i=t.getDate();return e+"-"+n+"-"+(i=i<10?"0"+i:i)},t.formatDateTime=function(t){var e=t.getFullYear(),n=t.getMonth()+1;n=n<10?"0"+n:n;var i=t.getDate();i=i<10?"0"+i:i;var r=t.getHours(),o=t.getMinutes();o=o<10?"0"+o:o;var s=t.getSeconds();return e+"-"+n+"-"+i+" "+r+":"+o+":"+(s=s<10?"0"+s:s)},t.parseDate=function(t){var e=Date.parse(t);return isNaN(e)?new Date:new Date(Date.parse(t.replace(/-/g,"/")))},t.secondToTime=function(t,e,n){void 0===t&&(t=0),void 0===e&&(e=":"),void 0===n&&(n=!0);var i=Math.floor(t/3600),r=Math.floor(t%3600/60),o=Math.floor(t%3600%60),s=i.toString(),a=r.toString(),c=o.toString();return i<10&&(s="0"+s),r<10&&(a="0"+a),o<10&&(c="0"+c),n?s+e+a+e+c:a+e+c},t.timeToMillisecond=function(t,e){void 0===e&&(e=":");for(var n=t.split(e),i=0,r=n.length,o=0;o=1?(e.value=1,n=this._points.length-4):(e.value=t.MathHelper.clamp01(e.value)*this._curveCount,n=~~e,e.value-=n,n*=3),n},e.prototype.setControlPoint=function(e,n){if(e%3==0){var i=t.Vector2.subtract(n,this._points.buffer[e]);e>0&&this._points.buffer[e-1].add(i),e+1n?n:t},e.pointOnCirlce=function(n,i,r){var o=e.toRadians(r);return new t.Vector2(Math.cos(o)*o+n.x,Math.sin(o)*o+n.y)},e.isEven=function(t){return t%2==0},e.clamp01=function(t){return t<0?0:t>1?1:t},e.angleBetweenVectors=function(t,e){return Math.atan2(e.y-t.y,e.x-t.x)},e.angleToVector=function(e,n){return new t.Vector2(Math.cos(e)*n,Math.sin(e)*n)},e.incrementWithWrap=function(t,e){return++t==e?0:t},e.approach=function(t,e,n){return ti&&(i=s.x),s.yr&&(r=s.y)}return this.fromMinMax(e,n,i,r)},e.prototype.getSide=function(e){switch(e){case t.Edge.top:return this.top;case t.Edge.bottom:return this.bottom;case t.Edge.left:return this.left;case t.Edge.right:return this.right;default:throw new Error("Argument Out Of Range")}},e.prototype.contains=function(t,e){return this.x<=t&&tthis.x+this.width)return!1}else{var i=1/t.direction.x,r=(this.x-t.start.x)*i,o=(this.x+this.width-t.start.x)*i;if(r>o){var s=r;r=o,o=s}if(e.value=Math.max(r,e.value),n=Math.min(o,n),e.value>n)return!1}if(Math.abs(t.direction.y)<1e-6){if(t.start.ythis.y+this.height)return!1}else{var a=1/t.direction.y,c=(this.y-t.start.y)*a,h=(this.y+this.height-t.start.y)*a;if(c>h){var u=c;c=h,h=u}if(e.value=Math.max(c,e.value),n=Math.max(h,n),e.value>n)return!1}return!0},e.prototype.containsRect=function(t){return this.x<=t.x&&t.x0?this.x:this.x+t,i.y=n>0?this.y:this.y+n,i.width=t>0?t+this.width:this.width-t,i.height=n>0?n+this.height:this.height-n,i},e.prototype.collisionCheck=function(t,e,n){e.value=n.value=0;var i=t.x-(this.x+this.width),r=t.x+t.width-this.x,o=t.y-(this.y+this.height),s=t.y+t.height-this.y;return!(i>0||r<0||o>0||s<0)&&(e.value=Math.abs(i)=l||Math.abs(u)>=p)return t.Vector2.zero;var f=h>0?l-h:-l-h,d=u>0?p-u:-p-u;return new t.Vector2(f,d)},e.prototype.equals=function(t){return this===t},e.prototype.getHashCode=function(){return this.x^this.y^this.width^this.height},e.prototype.clone=function(){return new e(this.x,this.y,this.width,this.height)},e}();t.Rectangle=e}(es||(es={})),function(t){var e=function(){function t(){this.remainder=0}return t.prototype.update=function(t){this.remainder+=t;var e=Math.floor(Math.trunc(this.remainder));return this.remainder-=e,t=e},t.prototype.reset=function(){this.remainder=0},t}();t.SubpixelFloat=e}(es||(es={})),function(t){var e=function(){function e(){this._x=new t.SubpixelFloat,this._y=new t.SubpixelFloat}return e.prototype.update=function(t){t.x=this._x.update(t.x),t.y=this._y.update(t.y)},e.prototype.reset=function(){this._x.reset(),this._y.reset()},e}();t.SubpixelVector2=e}(es||(es={})),function(t){var e=function(){function e(t,e){this.x=0,this.y=0,this.x=t||0,this.y=null!=e?e:this.x}return Object.defineProperty(e,"zero",{get:function(){return new e(0,0)},enumerable:!0,configurable:!0}),Object.defineProperty(e,"one",{get:function(){return new e(1,1)},enumerable:!0,configurable:!0}),Object.defineProperty(e,"unitX",{get:function(){return new e(1,0)},enumerable:!0,configurable:!0}),Object.defineProperty(e,"unitY",{get:function(){return new e(0,1)},enumerable:!0,configurable:!0}),e.add=function(t,n){var i=e.zero;return i.x=t.x+n.x,i.y=t.y+n.y,i},e.divide=function(t,n){var i=e.zero;return i.x=t.x/n.x,i.y=t.y/n.y,i},e.multiply=function(t,n){var i=new e(0,0);return i.x=t.x*n.x,i.y=t.y*n.y,i},e.subtract=function(t,n){var i=new e(0,0);return i.x=t.x-n.x,i.y=t.y-n.y,i},e.normalize=function(t){var n=new e(t.x,t.y),i=1/Math.sqrt(n.x*n.x+n.y*n.y);return n.x*=i,n.y*=i,n},e.dot=function(t,e){return t.x*e.x+t.y*e.y},e.distanceSquared=function(t,e){var n=t.x-e.x,i=t.y-e.y;return n*n+i*i},e.clamp=function(n,i,r){return new e(t.MathHelper.clamp(n.x,i.x,r.x),t.MathHelper.clamp(n.y,i.y,r.y))},e.lerp=function(n,i,r){return new e(t.MathHelper.lerp(n.x,i.x,r),t.MathHelper.lerp(n.y,i.y,r))},e.transform=function(t,n){return new e(t.x*n.m11+t.y*n.m21+n.m31,t.x*n.m12+t.y*n.m22+n.m32)},e.distance=function(t,e){var n=t.x-e.x,i=t.y-e.y;return Math.sqrt(n*n+i*i)},e.angle=function(n,i){return n=e.normalize(n),i=e.normalize(i),Math.acos(t.MathHelper.clamp(e.dot(n,i),-1,1))*t.MathHelper.Rad2Deg},e.negate=function(t){return t.x=-t.x,t.y=-t.y,t},e.prototype.add=function(t){return this.x+=t.x,this.y+=t.y,this},e.prototype.divide=function(t){return this.x/=t.x,this.y/=t.y,this},e.prototype.multiply=function(t){return this.x*=t.x,this.y*=t.y,this},e.prototype.subtract=function(t){return this.x-=t.x,this.y-=t.y,this},e.prototype.normalize=function(){var t=1/Math.sqrt(this.x*this.x+this.y*this.y);this.x*=t,this.y*=t},e.prototype.length=function(){return Math.sqrt(this.x*this.x+this.y*this.y)},e.prototype.lengthSquared=function(){return this.x*this.x+this.y*this.y},e.prototype.round=function(){return new e(Math.round(this.x),Math.round(this.y))},e.prototype.angleBetween=function(n,i){var r=e.subtract(n,this),o=e.subtract(i,this);return t.Vector2Ext.angle(r,o)},e.prototype.equals=function(t){return t instanceof e&&(t.x==this.x&&t.y==this.y)},e.prototype.clone=function(){return new e(this.x,this.y)},e}();t.Vector2=e}(es||(es={})),function(t){var e=function(){function e(e){this._activeTriggerIntersections=new t.HashSet,this._previousTriggerIntersections=new t.HashSet,this._tempTriggerList=[],this._entity=e}return e.prototype.update=function(){for(var e=this._entity.getComponents(t.Collider),n=0;n1)return!1;var u=(c.x*o.y-c.y*o.x)/a;return!(u<0||u>1)},n.lineToLineIntersection=function(e,n,i,r,o){void 0===o&&(o=new t.Vector2),o.x=0,o.y=0;var s=t.Vector2.subtract(n,e),a=t.Vector2.subtract(r,i),c=s.x*a.y-s.y*a.x;if(0==c)return!1;var h=t.Vector2.subtract(i,e),u=(h.x*a.y-h.y*a.x)/c;if(u<0||u>1)return!1;var l=(h.x*s.y-h.y*s.x)/c;if(l<0||l>1)return!1;var p=t.Vector2.add(e,new t.Vector2(u*s.x,u*s.y));return o.x=p.x,o.y=p.y,!0},n.closestPointOnLine=function(e,n,i){var r=t.Vector2.subtract(n,e),o=t.Vector2.subtract(i,e),s=t.Vector2.dot(o,r)/t.Vector2.dot(r,r);return s=t.MathHelper.clamp(s,0,1),t.Vector2.add(e,new t.Vector2(r.x*s,r.y*s))},n.circleToCircle=function(e,n,i,r){return t.Vector2.distanceSquared(e,i)<(n+r)*(n+r)},n.circleToLine=function(e,n,i,r){return t.Vector2.distanceSquared(e,this.closestPointOnLine(i,r,e))=t&&r.y>=e&&r.x=t+i&&(s|=e.right),o.y=n+r&&(s|=e.bottom),s},n}();t.Collisions=n}(es||(es={})),function(t){var e=function(){function e(e,n,i,r,o){this.fraction=0,this.distance=0,this.point=t.Vector2.zero,this.normal=t.Vector2.zero,this.collider=e,this.fraction=n,this.distance=i,this.point=r,this.centroid=t.Vector2.zero}return e.prototype.setValues=function(t,e,n,i){this.collider=t,this.fraction=e,this.distance=n,this.point=i},e.prototype.setValuesNonCollider=function(t,e,n,i){this.fraction=t,this.distance=e,this.point=n,this.normal=i},e.prototype.reset=function(){this.collider=null,this.fraction=this.distance=0},e.prototype.toString=function(){return"[RaycastHit] fraction: "+this.fraction+", distance: "+this.distance+", normal: "+this.normal+", centroid: "+this.centroid+", point: "+this.point},e}();t.RaycastHit=e}(es||(es={})),function(t){var e=function(){function e(){}return e.reset=function(){this._spatialHash=new t.SpatialHash(this.spatialHashCellSize),this._hitArray[0].reset()},e.clear=function(){this._spatialHash.clear()},e.overlapCircleAll=function(t,e,n,i){if(void 0===i&&(i=-1),0!=n.length)return this._spatialHash.overlapCircle(t,e,n,i);console.error("传入了一个空的结果数组。不会返回任何结果")},e.boxcastBroadphase=function(t,e){return void 0===e&&(e=this.allLayers),this._spatialHash.aabbBroadphase(t,null,e)},e.boxcastBroadphaseExcludingSelf=function(t,e,n){return void 0===n&&(n=this.allLayers),this._spatialHash.aabbBroadphase(e,t,n)},e.boxcastBroadphaseExcludingSelfNonRect=function(t,e){void 0===e&&(e=this.allLayers);var n=t.bounds.clone();return this._spatialHash.aabbBroadphase(n,t,e)},e.addCollider=function(t){e._spatialHash.register(t)},e.removeCollider=function(t){e._spatialHash.remove(t)},e.updateCollider=function(t){this._spatialHash.remove(t),this._spatialHash.register(t)},e.linecast=function(t,n,i){return void 0===i&&(i=e.allLayers),this._hitArray[0].reset(),this.linecastAll(t,n,this._hitArray,i),this._hitArray[0]},e.linecastAll=function(t,n,i,r){return void 0===r&&(r=e.allLayers),0==i.length?(console.warn("传入了一个空的hits数组。没有点击会被返回"),0):this._spatialHash.linecast(t,n,i,r)},e.gravity=new t.Vector2(0,300),e.spatialHashCellSize=100,e.allLayers=-1,e.raycastsHitTriggers=!1,e.raycastsStartInColliders=!1,e._hitArray=[new t.RaycastHit],e}();t.Physics=e}(es||(es={})),function(t){var e=function(){return function(e,n){this.start=e,this.end=n,this.direction=t.Vector2.subtract(this.end,this.start)}}();t.Ray2D=e}(es||(es={})),function(t){var e=function(){function e(e){void 0===e&&(e=100),this.gridBounds=new t.Rectangle,this._overlapTestCircle=new t.Circle(0),this._cellDict=new n,this._tempHashSet=new Set,this._cellSize=e,this._inverseCellSize=1/this._cellSize,this._raycastParser=new i}return e.prototype.register=function(e){var n=e.bounds.clone();e.registeredPhysicsBounds=n;var i=this.cellCoords(n.x,n.y),r=this.cellCoords(n.right,n.bottom);this.gridBounds.contains(i.x,i.y)||(this.gridBounds=t.RectangleExt.union(this.gridBounds,i)),this.gridBounds.contains(r.x,r.y)||(this.gridBounds=t.RectangleExt.union(this.gridBounds,r));for(var o=i.x;o<=r.x;o++)for(var s=i.y;s<=r.y;s++){this.cellAtPosition(o,s,!0).push(e)}},e.prototype.remove=function(t){for(var e=t.registeredPhysicsBounds.clone(),n=this.cellCoords(e.x,e.y),i=this.cellCoords(e.right,e.bottom),r=n.x;r<=i.x;r++)for(var o=n.y;o<=i.y;o++){var s=this.cellAtPosition(r,o);s?new linq.List(s).remove(t):console.log("从不存在碰撞器的单元格中移除碰撞器: ["+t+"]")}},e.prototype.removeWithBruteForce=function(t){this._cellDict.remove(t)},e.prototype.clear=function(){this._cellDict.clear()},e.prototype.aabbBroadphase=function(e,n,i){this._tempHashSet.clear();for(var r=this.cellCoords(e.x,e.y),o=this.cellCoords(e.right,e.bottom),s=r.x;s<=o.x;s++)for(var a=r.y;a<=o.y;a++){var c=this.cellAtPosition(s,a);if(null!=c)for(var h=0;h>>0},t.prototype.clear=function(){this._store.clear()},t}();t.NumberDictionary=n;var i=function(){function e(){this._tempHit=new t.RaycastHit,this._checkedColliders=[],this._cellHits=[]}return e.prototype.start=function(t,e,n){this._ray=t,this._hits=e,this._layerMask=n,this.hitCounter=0},e.prototype.checkRayIntersection=function(n,i,r){for(var o=new t.Ref(0),s=0;s=this.points.length?this.points[0]:this.points[i+1];var o=t.Vector2Ext.perpendicular(r,e);t.Vector2Ext.normalize(o),this._edgeNormals[i]=o}},n.buildSymmetricalPolygon=function(e,n){for(var i=new Array(e),r=0;rr&&(r=s,i=o)}return e[i]},n.getClosestPointOnPolygonToPoint=function(e,n,i,r){i.value=Number.MAX_VALUE,r.x=0,r.y=0;for(var o=t.Vector2.zero,s=0,a=0;at.y!=this.points[i].y>t.y&&t.x<(this.points[i].x-this.points[n].x)*(t.y-this.points[n].y)/(this.points[i].y-this.points[n].y)+this.points[n].x&&(e=!e);return e},n.prototype.pointCollidesWithShape=function(e,n){return t.ShapeCollisions.pointToPoly(e,this,n)},n}(t.Shape);t.Polygon=e}(es||(es={})),function(t){var e=function(e){function n(t,i){var r=e.call(this,n.buildBox(t,i),!0)||this;return r.width=t,r.height=i,r}return __extends(n,e),n.buildBox=function(e,n){var i=e/2,r=n/2,o=new Array(4);return o[0]=new t.Vector2(-i,-r),o[1]=new t.Vector2(i,-r),o[2]=new t.Vector2(i,r),o[3]=new t.Vector2(-i,r),o},n.prototype.updateBox=function(e,n){this.width=e,this.height=n;var i=e/2,r=n/2;this.points[0]=new t.Vector2(-i,-r),this.points[1]=new t.Vector2(i,-r),this.points[2]=new t.Vector2(i,r),this.points[3]=new t.Vector2(-i,r);for(var o=0;o1)return!1;var a,c=t.Vector2.add(s.start,t.Vector2.multiply(s.direction,new t.Vector2(r.value))),h=0;c.xn.bounds.right&&(h|=1),c.yn.bounds.bottom&&(h|=2);var u=a+h;return 3==u&&console.log("m == 3. corner "+t.Time.frameCount),!0},e.corner=function(e,n){var i=new t.Vector2;return i.x=0==(1&n)?e.right:e.left,i.y=0==(1&n)?e.bottom:e.top,i},e.testCircleBox=function(e,n,i){i=n.bounds.getClosestPointOnRectangleToPoint(e.position);var r=t.Vector2.subtract(i,e.position);return t.Vector2.dot(r,r)<=e.radius*e.radius},e}();t.RealtimeCollisions=e}(es||(es={})),function(t){var e=function(){function e(){}return e.polygonToPolygon=function(e,n,i){for(var r,o=!0,s=e.edgeNormals.slice(),a=n.edgeNormals.slice(),c=Number.POSITIVE_INFINITY,h=new t.Vector2,u=t.Vector2.subtract(e.position,n.position),l=0;l0&&(o=!1),!o)return!1;(y=Math.abs(y))r.value&&(r.value=o)},e.circleToPolygon=function(e,n,i){var r,o=t.Vector2.subtract(e.position,n.position),s=new t.Ref(0),a=t.Polygon.getClosestPointOnPolygonToPoint(n.points,o,s,i.normal),c=n.containsPoint(e.position);if(s.value>e.radius*e.radius&&!c)return!1;if(c)r=t.Vector2.multiply(i.normal,new t.Vector2(Math.sqrt(s.value)-e.radius));else if(0==s.value)r=new t.Vector2(i.normal.x*e.radius,i.normal.y*e.radius);else{var h=Math.sqrt(s.value);r=new t.Vector2(-o.x+a.x,-o.y+a.y).multiply(new t.Vector2((e.radius-h)/h))}return i.minimumTranslationVector=r,i.point=t.Vector2.add(a,n.position),!0},e.circleToBox=function(e,n,i){var r=n.bounds.getClosestPointOnRectangleBorderToPoint(e.position,i.normal);if(n.containsPoint(e.position)){i.point=r;var o=t.Vector2.add(r,t.Vector2.multiply(i.normal,new t.Vector2(e.radius)));return i.minimumTranslationVector=t.Vector2.subtract(e.position,o),!0}var s=t.Vector2.distanceSquared(r,e.position);if(0==s)i.minimumTranslationVector=t.Vector2.multiply(i.normal,new t.Vector2(e.radius));else if(s<=e.radius*e.radius){i.normal=t.Vector2.subtract(e.position,r);var a=i.normal.length()-e.radius;return i.point=r,t.Vector2Ext.normalize(i.normal),i.minimumTranslationVector=t.Vector2.multiply(new t.Vector2(a),i.normal),!0}return!1},e.pointToCircle=function(e,n,i){var r=t.Vector2.distanceSquared(e,n.position),o=1+n.radius;if(r1)return!1;var l=(h.x*s.y-h.y*s.x)/c;return!(l<0||l>1)&&(t.Vector2.add(e,t.Vector2.multiply(new t.Vector2(u),s)),!0)},e.lineToCircle=function(e,n,i,r){var o=t.Vector2.distance(e,n),s=t.Vector2.divide(t.Vector2.subtract(n,e),new t.Vector2(o)),a=t.Vector2.subtract(e,i.position),c=t.Vector2.dot(a,s),h=t.Vector2.dot(a,a)-i.radius*i.radius;if(h>0&&c>0)return!1;var u=c*c-h;return!(u<0)&&(r.fraction=-c-Math.sqrt(u),r.fraction<0&&(r.fraction=0),r.point=t.Vector2.add(e,t.Vector2.multiply(new t.Vector2(r.fraction),s)),r.distance=t.Vector2.distance(e,r.point),r.normal=t.Vector2.normalize(t.Vector2.subtract(r.point,i.position)),r.fraction=r.distance/o,!0)},e.boxToBoxCast=function(e,n,i,r){var o=this.minkowskiDifference(e,n);if(o.contains(0,0)){var s=o.getClosestPointOnBoundsToOrigin();return!s.equals(t.Vector2.zero)&&(r.normal=new t.Vector2(-s.x),r.normal.normalize(),r.distance=0,r.fraction=0,!0)}var a=new t.Ray2D(t.Vector2.zero,new t.Vector2(-i.x)),c=new t.Ref(0);return!!(o.rayIntersects(a,c)&&c.value<=1)&&(r.fraction=c.value,r.distance=i.length()*c.value,r.normal=new t.Vector2(-i.x,-i.y),r.normal.normalize(),r.centroid=t.Vector2.add(e.bounds.center,t.Vector2.multiply(i,new t.Vector2(c.value))),!0)},e}();t.ShapeCollisions=e}(es||(es={}));var ArrayUtils=function(){function t(){}return t.bubbleSort=function(t){for(var e=!1,n=0;nn;i--)if(t[i]0&&t[r-1]>i;r--)t[r]=t[r-1];t[r]=i}},t.binarySearch=function(t,e){for(var n=0,i=t.length,r=n+i>>1;n=t[r]&&(n=r+1),r=n+i>>1;return t[n]==e?n:-1},t.findElementIndex=function(t,e){for(var n=t.length,i=0;it[e]&&(e=i);return e},t.getMinElementIndex=function(t){for(var e=0,n=t.length,i=1;i=0;--r)n.unshift(e[r]);return n},t.getDifferAry=function(t,e){t=this.getUniqueAry(t),e=this.getUniqueAry(e);for(var n=t.concat(e),i={},r=[],o=n.length,s=0;s=0;e-=1)t.splice(e,1)},t.cloneList=function(t){return t?t.slice(0,t.length):null},t.equals=function(t,e){if(t==e)return!0;var n=t.length;if(n!=e.length)return!1;for(;n--;)if(t[n]!=e[n])return!1;return!0},t.insert=function(t,e,n){if(!t)return null;var i=t.length;if(e>i&&(e=i),e<0&&(e=0),e==i)t.push(n);else if(0==e)t.unshift(n);else{for(var r=i-1;r>=e;r-=1)t[r+1]=t[r];t[e]=n}return n},t.shuffle=function(t){for(var e=t.length;e>1;){e--;var n=RandomUtils.randint(0,e+1),i=t[n];t[n]=t[e],t[e]=i}},t.addIfNotPresent=function(t,e){return!new linq.List(t).contains(e)&&(t.push(e),!0)},t.lastItem=function(t){return t[t.length-1]},t.randomItem=function(t){return t[RandomUtils.randint(0,t.length-1)]},t.randomItems=function(t,e){for(var n=new Set;n.size!=e;){var i=this.randomItem(t);n.has(i)||n.add(i)}var r=es.ListPool.obtain();return n.forEach(function(t){return r.push(t)}),r},t}();!function(t){var e=function(){function t(){}return Object.defineProperty(t,"nativeBase64",{get:function(){return"function"==typeof window.atob},enumerable:!0,configurable:!0}),t.decode=function(t){if(t=t.replace(/[^A-Za-z0-9\+\/\=]/g,""),this.nativeBase64)return window.atob(t);for(var e,n,i,r,o,s,a=[],c=0;c>4,n=(15&r)<<4|(o=this._keyStr.indexOf(t.charAt(c++)))>>2,i=(3&o)<<6|(s=this._keyStr.indexOf(t.charAt(c++))),a.push(String.fromCharCode(e)),64!==o&&a.push(String.fromCharCode(n)),64!==s&&a.push(String.fromCharCode(i));return a=a.join("")},t.encode=function(t){if(t=t.replace(/\r\n/g,"\n"),!this.nativeBase64){for(var e,n,i,r,o,s,a,c=[],h=0;h>2,o=(3&e)<<4|(n=t.charCodeAt(h++))>>4,s=(15&n)<<2|(i=t.charCodeAt(h++))>>6,a=63&i,isNaN(n)?s=a=64:isNaN(i)&&(a=64),c.push(this._keyStr.charAt(r)),c.push(this._keyStr.charAt(o)),c.push(this._keyStr.charAt(s)),c.push(this._keyStr.charAt(a));return c=c.join("")}window.btoa(t)},t.decodeBase64AsArray=function(e,n){n=n||1;var i,r,o,s=t.decode(e),a=new Uint32Array(s.length/n);for(i=0,o=s.length/n;i=0;--r)a[i]+=s.charCodeAt(i*n+r)<<(r<<3);return a},t.decompress=function(t,e,n){throw new Error("GZIP/ZLIB compressed TMX Tile Map not supported!")},t.decodeCSV=function(t){for(var e=t.replace("\n","").trim().split(","),n=[],i=0;i=0;i--)n[i].func.call(n[i].context,e)},t}();t.Emitter=n}(es||(es={})),function(t){!function(t){t[t.top=0]="top",t[t.bottom=1]="bottom",t[t.left=2]="left",t[t.right=3]="right"}(t.Edge||(t.Edge={}))}(es||(es={})),function(t){var e=function(){function t(){}return t.repeat=function(t,e){for(var n=[];e--;)n.push(t);return n},t}();t.Enumerable=e}(es||(es={})),function(t){var e=function(){function t(){}return t.default=function(){return new t},t.prototype.equals=function(t,e){return"function"==typeof t.equals?t.equals(e):t===e},t.prototype.getHashCode=function(t){var e=this;if("number"==typeof t)return this._getHashCodeForNumber(t);if("string"==typeof t)return this._getHashCodeForString(t);var n=385229220;return this.forOwn(t,function(t){"number"==typeof t?n+=e._getHashCodeForNumber(t):"string"==typeof t?n+=e._getHashCodeForString(t):"object"==typeof t&&e.forOwn(t,function(){n+=e.getHashCode(t)})}),n},t.prototype._getHashCodeForNumber=function(t){return t},t.prototype._getHashCodeForString=function(t){for(var e=385229220,n=0;n=0&&t=0&&t<=this.count){for(var e=this.head,n=0;n=0&&n<=this.count){var i=new e(t);if(0===n)i.next=this.head,this.head=i;else{var r=this.getElementAt(n-1);i.next=r.next,r.next=i}return this.count++,!0}return!1},t.prototype.indexOf=function(t){for(var e=this.head,n=0;n0)for(var e=0;ethis._objectQueue.length;)this._objectQueue.shift()},t.clearCache=function(){this._objectQueue.length=0},t.obtain=function(){return this._objectQueue.length>0?this._objectQueue.shift():[]},t.free=function(t){this._objectQueue.unshift(t),t.length=0},t._objectQueue=[],t}();t.ListPool=e}(es||(es={})),function(t){var e=function(){function t(){}return t.toNumber=function(t){return null==t?0:Number(t)},t}();t.NumberExtension=e}(es||(es={})),function(t){var e=function(){function e(t,e){this.first=t,this.second=e}return e.prototype.clear=function(){this.first=this.second=null},e.prototype.equals=function(t){return this.first==t.first&&this.second==t.second},e.prototype.getHashCode=function(){return 37*t.EqualityComparer.default().getHashCode(this.first)+t.EqualityComparer.default().getHashCode(this.second)},e}();t.Pair=e}(es||(es={})),function(t){var e=function(){function e(){}return e.warmCache=function(t,e){if((e-=this._objectQueue.length)>0)for(var n=0;nthis._objectQueue.length;)this._objectQueue.shift()},e.clearCache=function(){this._objectQueue.length=0},e.obtain=function(t){return this._objectQueue.length>0?this._objectQueue.shift():new t},e.free=function(e){this._objectQueue.unshift(e),t.isIPoolable(e)&&e.reset()},e._objectQueue=[],e}();t.Pool=e,t.isIPoolable=function(t){return void 0!==t.reset}}(es||(es={}));var RandomUtils=function(){function t(){}return t.randrange=function(t,e,n){if(void 0===n&&(n=1),0==n)throw new Error("step 不能为 0");var i=e-t;if(0==i)throw new Error("没有可用的范围("+t+","+e+")");i<0&&(i=t-e);var r=Math.floor((i+n-1)/n);return Math.floor(this.random()*r)*n+Math.min(t,e)},t.randint=function(t,e){return(t=Math.floor(t))>(e=Math.floor(e))?t++:e++,this.randrange(t,e)},t.randnum=function(t,e){return this.random()*(e-t)+t},t.shuffle=function(t){return t.sort(this._randomCompare),t},t.choice=function(t){if(!t.hasOwnProperty("length"))throw new Error("无法对此对象执行此操作");var e=Math.floor(this.random()*t.length);return t instanceof String?String(t).charAt(e):t[e]},t.sample=function(t,e){var n=t.length;if(e<=0||n=0;)s=Math.floor(this.random()*n);i.push(t[s]),r.push(s)}return i},t.random=function(){return Math.random()},t.boolean=function(t){return void 0===t&&(t=.5),this.random().5?1:-1},t}();!function(t){var e=function(){function e(){}return e.getSide=function(e,n){switch(n){case t.Edge.top:return e.top;case t.Edge.bottom:return e.bottom;case t.Edge.left:return e.left;case t.Edge.right:return e.right}},e.union=function(e,n){var i=new t.Rectangle(n.x,n.y,0,0),r=new t.Rectangle;return r.x=Math.min(e.x,i.x),r.y=Math.min(e.y,i.y),r.width=Math.max(e.right,i.right)-r.x,r.height=Math.max(e.bottom,i.bottom)-r.y,r},e.getHalfRect=function(e,n){switch(n){case t.Edge.top:return new t.Rectangle(e.x,e.y,e.width,e.height/2);case t.Edge.bottom:return new t.Rectangle(e.x,e.y+e.height/2,e.width,e.height/2);case t.Edge.left:return new t.Rectangle(e.x,e.y,e.width/2,e.height);case t.Edge.right:return new t.Rectangle(e.x+e.width/2,e.y,e.width/2,e.height)}},e.getRectEdgePortion=function(e,n,i){switch(void 0===i&&(i=1),n){case t.Edge.top:return new t.Rectangle(e.x,e.y,e.width,i);case t.Edge.bottom:return new t.Rectangle(e.x,e.y+e.height-i,e.width,i);case t.Edge.left:return new t.Rectangle(e.x,e.y,i,e.height);case t.Edge.right:return new t.Rectangle(e.x+e.width-i,e.y,i,e.height)}},e.expandSide=function(e,n,i){switch(i=Math.abs(i),n){case t.Edge.top:e.y-=i,e.height+=i;break;case t.Edge.bottom:e.height+=i;break;case t.Edge.left:e.x-=i,e.width+=i;break;case t.Edge.right:e.width+=i}},e.contract=function(t,e,n){t.x+=e,t.y+=n,t.width-=2*e,t.height-=2*n},e}();t.RectangleExt=e}(es||(es={})),function(t){var e=function(){return function(t){this.value=t}}();t.Ref=e}(es||(es={})),function(t){var e=function(t){function e(e){return t.call(this,e)||this}return __extends(e,t),e.prototype.getHashCode=function(t){return t.getHashCode()},e.prototype.areEqual=function(t,e){return t.equals(e)},e}(function(){function t(t){var e=this;this.clear(),t&&t.forEach(function(t){e.add(t)})}return t.prototype.add=function(t){var e=this,n=this.getHashCode(t),i=this.buckets[n];if(void 0===i){var r=new Array;return r.push(t),this.buckets[n]=r,this.count=this.count+1,!0}return!i.some(function(n){return e.areEqual(n,t)})&&(i.push(t),this.count=this.count+1,!0)},t.prototype.remove=function(t){var e=this,n=this.getHashCode(t),i=this.buckets[n];if(void 0===i)return!1;var r=!1,o=new Array;return i.forEach(function(n){e.areEqual(n,t)?r=!0:o.push(t)}),this.buckets[n]=o,r&&(this.count=this.count-1),r},t.prototype.contains=function(t){return this.bucketsContains(this.buckets,t)},t.prototype.getCount=function(){return this.count},t.prototype.clear=function(){this.buckets=new Array,this.count=0},t.prototype.toArray=function(){var t=new Array;return this.buckets.forEach(function(e){e.forEach(function(e){t.push(e)})}),t},t.prototype.exceptWith=function(t){var e=this;t&&t.forEach(function(t){e.remove(t)})},t.prototype.intersectWith=function(t){var e=this;if(t){var n=this.buildInternalBuckets(t);this.toArray().forEach(function(t){e.bucketsContains(n.Buckets,t)||e.remove(t)})}else this.clear()},t.prototype.unionWith=function(t){var e=this;t.forEach(function(t){e.add(t)})},t.prototype.isSubsetOf=function(t){var e=this,n=this.buildInternalBuckets(t);return this.toArray().every(function(t){return e.bucketsContains(n.Buckets,t)})},t.prototype.isSupersetOf=function(t){var e=this;return t.every(function(t){return e.contains(t)})},t.prototype.overlaps=function(t){var e=this;return t.some(function(t){return e.contains(t)})},t.prototype.setEquals=function(t){var e=this;return this.buildInternalBuckets(t).Count===this.count&&t.every(function(t){return e.contains(t)})},t.prototype.buildInternalBuckets=function(t){var e=this,n=new Array,i=0;return t.forEach(function(t){var r=e.getHashCode(t),o=n[r];if(void 0===o){var s=new Array;s.push(t),n[r]=s,i+=1}else o.some(function(n){return e.areEqual(n,t)})||(o.push(t),i+=1)}),{Buckets:n,Count:i}},t.prototype.bucketsContains=function(t,e){var n=this,i=t[this.getHashCode(e)];return void 0!==i&&i.some(function(t){return n.areEqual(t,e)})},t}());t.HashSet=e}(es||(es={})),function(t){var e=function(){function t(){}return t.prototype.update=function(t){this.remainder+=t;var e=Math.trunc(this.remainder);return this.remainder-=e,e},t.prototype.reset=function(){this.remainder=0},t}();t.SubpixelNumber=e}(es||(es={})),function(t){var e=function(){function e(){this.triangleIndices=[],this._triPrev=new Array(12),this._triNext=new Array(12)}return e.testPointTriangle=function(e,n,i,r){return!(t.Vector2Ext.cross(t.Vector2.subtract(e,n),t.Vector2.subtract(i,n))<0)&&(!(t.Vector2Ext.cross(t.Vector2.subtract(e,i),t.Vector2.subtract(r,i))<0)&&!(t.Vector2Ext.cross(t.Vector2.subtract(e,r),t.Vector2.subtract(n,r))<0))},e.prototype.triangulate=function(n,i){void 0===i&&(i=!0);var r=n.length;this.initialize(r);for(var o=0,s=0;r>3&&o<500;){o++;var a=!0,c=n[this._triPrev[s]],h=n[s],u=n[this._triNext[s]];if(t.Vector2Ext.isTriangleCCW(c,h,u)){var l=this._triNext[this._triNext[s]];do{if(e.testPointTriangle(n[l],c,h,u)){a=!1;break}l=this._triNext[l]}while(l!=this._triPrev[s])}else a=!1;a?(this.triangleIndices.push(this._triPrev[s]),this.triangleIndices.push(s),this.triangleIndices.push(this._triNext[s]),this._triNext[this._triPrev[s]]=this._triNext[s],this._triPrev[this._triNext[s]]=this._triPrev[s],r--,s=this._triPrev[s]):s=this._triNext[s]}this.triangleIndices.push(this._triPrev[s]),this.triangleIndices.push(s),this.triangleIndices.push(this._triNext[s]),i||this.triangleIndices.reverse()},e.prototype.initialize=function(t){this.triangleIndices.length=0,this._triNext.lengtht.MathHelper.Epsilon?e.divide(new t.Vector2(n)):e.x=e.y=0},e.transformA=function(t,e,n,i,r,o){for(var s=0;so?e?-1:1:r0},e.prototype.average=function(t){return this.sum(t)/this.count(t)},e.prototype.cast=function(){return new e(this._elements)},e.prototype.clear=function(){this._elements.length=0},e.prototype.concat=function(t){return new e(this._elements.concat(t.toArray()))},e.prototype.contains=function(t){return this.any(function(e){return e===t})},e.prototype.count=function(t){return t?this.where(t).count():this._elements.length},e.prototype.defaultIfEmpty=function(t){return this.count()?this:new e([t])},e.prototype.distinctBy=function(t){var n=this.groupBy(t);return Object.keys(n).reduce(function(t,e){return t.add(n[e][0]),t},new e)},e.prototype.elementAt=function(t){if(t=0)return this._elements[t];throw new Error("ArgumentOutOfRangeException: index is less than 0 or greater than or equal to the number of elements in source.")},e.prototype.elementAtOrDefault=function(t){return t=0?this._elements[t]:void 0},e.prototype.except=function(t){return this.where(function(e){return!t.contains(e)})},e.prototype.first=function(t){if(this.count())return t?this.where(t).first():this._elements[0];throw new Error("InvalidOperationException: The source sequence is empty.")},e.prototype.firstOrDefault=function(t){return this.count(t)?this.first(t):void 0},e.prototype.forEach=function(t){return this._elements.forEach(t)},e.prototype.groupBy=function(t,e){void 0===e&&(e=function(t){return t});return this.aggregate(function(n,i){var r=t(i),o=n[r],s=e(i);return o?o.push(s):n[r]=[s],n},{})},e.prototype.groupJoin=function(t,e,n,i){return this.select(function(r){return i(r,t.where(function(t){return e(r)===n(t)}))})},e.prototype.indexOf=function(t){return this._elements.indexOf(t)},e.prototype.insert=function(t,e){if(t<0||t>this._elements.length)throw new Error("Index is out of range.");this._elements.splice(t,0,e)},e.prototype.intersect=function(t){return this.where(function(e){return t.contains(e)})},e.prototype.join=function(t,e,n,i){return this.selectMany(function(r){return t.where(function(t){return n(t)===e(r)}).select(function(t){return i(r,t)})})},e.prototype.last=function(t){if(this.count())return t?this.where(t).last():this._elements[this.count()-1];throw Error("InvalidOperationException: The source sequence is empty.")},e.prototype.lastOrDefault=function(t){return this.count(t)?this.last(t):void 0},e.prototype.max=function(t){return Math.max.apply(Math,__spread(this._elements.map(t||function(t){return t})))},e.prototype.min=function(t){return Math.min.apply(Math,__spread(this._elements.map(t||function(t){return t})))},e.prototype.ofType=function(t){var e;switch(t){case Number:e="number";break;case String:e="string";break;case Boolean:e=typeof!0;break;case Function:e="function";break;default:e=null}return null===e?this.where(function(e){return e instanceof t}).cast():this.where(function(t){return typeof t===e}).cast()},e.prototype.orderBy=function(e,i){return void 0===i&&(i=t.keyComparer(e,!1)),new n(this._elements,i)},e.prototype.orderByDescending=function(e,i){return void 0===i&&(i=t.keyComparer(e,!0)),new n(this._elements,i)},e.prototype.thenBy=function(t){return this.orderBy(t)},e.prototype.thenByDescending=function(t){return this.orderByDescending(t)},e.prototype.remove=function(t){return-1!==this.indexOf(t)&&(this.removeAt(this.indexOf(t)),!0)},e.prototype.removeAll=function(e){return this.where(t.negate(e))},e.prototype.removeAt=function(t){this._elements.splice(t,1)},e.prototype.reverse=function(){return new e(this._elements.reverse())},e.prototype.select=function(t){return new e(this._elements.map(t))},e.prototype.selectMany=function(t){var n=this;return this.aggregate(function(e,i,r){return e.addRange(n.select(t).elementAt(r).toArray()),e},new e)},e.prototype.sequenceEqual=function(t){return this.all(function(e){return t.contains(e)})},e.prototype.single=function(t){if(1!==this.count(t))throw new Error("The collection does not contain exactly one element.");return this.first(t)},e.prototype.singleOrDefault=function(t){return this.count(t)?this.single(t):void 0},e.prototype.skip=function(t){return new e(this._elements.slice(Math.max(0,t)))},e.prototype.skipLast=function(t){return new e(this._elements.slice(0,-Math.max(0,t)))},e.prototype.skipWhile=function(t){var e=this;return this.skip(this.aggregate(function(n){return t(e.elementAt(n))?++n:n},0))},e.prototype.sum=function(t){return t?this.select(t).sum():this.aggregate(function(t,e){return t+ +e},0)},e.prototype.take=function(t){return new e(this._elements.slice(0,Math.max(0,t)))},e.prototype.takeLast=function(t){return new e(this._elements.slice(-Math.max(0,t)))},e.prototype.takeWhile=function(t){var e=this;return this.take(this.aggregate(function(n){return t(e.elementAt(n))?++n:n},0))},e.prototype.toArray=function(){return this._elements},e.prototype.toDictionary=function(t,n){var i=this;return this.aggregate(function(e,r,o){return e[i.select(t).elementAt(o).toString()]=n?i.select(n).elementAt(o):r,e.add({Key:i.select(t).elementAt(o),Value:n?i.select(n).elementAt(o):r}),e},new e)},e.prototype.toSet=function(){var t,e,n=new Set;try{for(var i=__values(this._elements),r=i.next();!r.done;r=i.next()){var o=r.value;n.add(o)}}catch(e){t={error:e}}finally{try{r&&!r.done&&(e=i.return)&&e.call(i)}finally{if(t)throw t.error}}return n},e.prototype.toList=function(){return this},e.prototype.toLookup=function(t,e){return this.groupBy(t,e)},e.prototype.where=function(t){return new e(this._elements.filter(t))},e.prototype.zip=function(t,e){var n=this;return t.count()e.angle?1:t.angleMath.PI&&(o-=2*Math.PI),r.p1.begin=o>0,r.p2.begin=!r.p1.begin}}catch(e){t={error:e}}finally{try{i&&!i.done&&(e=n.return)&&e.call(n)}finally{if(t)throw t.error}}this._isSpotLight&&(this._spotStartAngle=this._segments[0].p2.angle,this._spotEndAngle=this._segments[1].p2.angle)},e._cornerCache=[],e._openSegments=new t.LinkedList,e}();t.VisibilityComputer=e}(es||(es={})),function(t){var e=function(){function e(){this._timeInSeconds=0,this._repeats=!1,this._isDone=!1,this._elapsedTime=0}return e.prototype.getContext=function(){return this.context},e.prototype.reset=function(){this._elapsedTime=0},e.prototype.stop=function(){this._isDone=!0},e.prototype.tick=function(){return!this._isDone&&this._elapsedTime>this._timeInSeconds&&(this._elapsedTime-=this._timeInSeconds,this._onTime(this),this._isDone||this._repeats||(this._isDone=!0)),this._elapsedTime+=t.Time.deltaTime,this._isDone},e.prototype.initialize=function(t,e,n,i){this._timeInSeconds=t,this._repeats=e,this.context=n,this._onTime=i},e.prototype.unload=function(){this.context=null,this._onTime=null},e}();t.Timer=e}(es||(es={})),function(t){var e=function(e){function n(){var t=null!==e&&e.apply(this,arguments)||this;return t._timers=[],t}return __extends(n,e),n.prototype.update=function(){for(var t=this._timers.length-1;t>=0;t--)this._timers[t].tick()&&(this._timers[t].unload(),new linq.List(this._timers).removeAt(t))},n.prototype.schedule=function(e,n,i,r){var o=new t.Timer;return o.initialize(e,n,i,r),this._timers.push(o),o},n}(t.GlobalManager);t.TimerManager=e}(es||(es={})); \ No newline at end of file +window.es={};var __awaiter=this&&this.__awaiter||function(t,e,n,i){return new(n||(n=Promise))(function(r,o){function s(t){try{c(i.next(t))}catch(t){o(t)}}function a(t){try{c(i.throw(t))}catch(t){o(t)}}function c(t){t.done?r(t.value):new n(function(e){e(t.value)}).then(s,a)}c((i=i.apply(t,e||[])).next())})},__generator=this&&this.__generator||function(t,e){var n,i,r,o,s={label:0,sent:function(){if(1&r[0])throw r[1];return r[1]},trys:[],ops:[]};return o={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function a(o){return function(a){return function(o){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,i&&(r=2&o[0]?i.return:o[0]?i.throw||((r=i.return)&&r.call(i),0):i.next)&&!(r=r.call(i,o[1])).done)return r;switch(i=0,r&&(o=[2&o[0],r.value]),o[0]){case 0:case 1:r=o;break;case 4:return s.label++,{value:o[1],done:!1};case 5:s.label++,i=o[1],o=[0];continue;case 7:o=s.ops.pop(),s.trys.pop();continue;default:if(!(r=(r=s.trys).length>0&&r[r.length-1])&&(6===o[0]||2===o[0])){s=0;continue}if(3===o[0]&&(!r||o[1]>r[0]&&o[1]=t.length&&(t=void 0),{value:t&&t[n++],done:!t}}}},__read=this&&this.__read||function(t,e){var n="function"==typeof Symbol&&t[Symbol.iterator];if(!n)return t;var i,r,o=n.call(t),s=[];try{for(;(void 0===e||e-- >0)&&!(i=o.next()).done;)s.push(i.value)}catch(t){r={error:t}}finally{try{i&&!i.done&&(n=o.return)&&n.call(o)}finally{if(r)throw r.error}}return s},__spread=this&&this.__spread||function(){for(var t=[],e=0;e=1){var e=window.performance.memory;null!=e&&(this._totalMemory=Number((e.totalJSHeapSize/1048576).toFixed(2))),this._titleMemory&&this._titleMemory(this._totalMemory,this._frameCounter),this._frameCounter=0,this._frameCounterElapsedTime-=1}},e.prototype.onSceneChanged=function(){e.emitter.emit(t.CoreEvents.SceneChanged),t.Time.sceneChanged()},e.prototype.onGraphicsDeviceReset=function(){null!=this._graphicsDeviceChangeTimer?this._graphicsDeviceChangeTimer.reset():this._graphicsDeviceChangeTimer=e.schedule(.05,!1,this,function(n){n.context._graphicsDeviceChangeTimer=null,e.emitter.emit(t.CoreEvents.GraphicsDeviceReset)})},e.prototype.initialize=function(){},e.prototype.update=function(e){return __awaiter(this,void 0,void 0,function(){var n;return __generator(this,function(i){if(null!=e&&t.Time.update(e),null!=this._scene){for(n=this._globalManagers.length-1;n>=0;n--)this._globalManagers.buffer[n].enabled&&this._globalManagers.buffer[n].update();this._scene.update(),null!=this._nextScene&&(this._scene.end(),this._scene=this._nextScene,this._nextScene=null,this.onSceneChanged(),this._scene.begin())}return this.startDebugDraw(),[2]})})},e.pauseOnFocusLost=!0,e.debugRenderEndabled=!1,e}();t.Core=e}(es||(es={})),function(t){!function(t){t[t.GraphicsDeviceReset=0]="GraphicsDeviceReset",t[t.SceneChanged=1]="SceneChanged",t[t.OrientationChanged=2]="OrientationChanged",t[t.FrameUpdated=3]="FrameUpdated"}(t.CoreEvents||(t.CoreEvents={}))}(es||(es={})),function(t){var e=function(){function t(){}return t.prototype.compare=function(t,e){var n=t.updateOrder-e.updateOrder;return 0==n&&(n=t.id-e.id),n},t}();t.EntityComparer=e;var n=function(){function n(e){this.updateInterval=1,this._tag=0,this._enabled=!0,this._updateOrder=0,this.components=new t.ComponentList(this),this.transform=new t.Transform(this),this.name=e,this.id=n._idGenerator++,t.Core.entitySystemsEnabled&&(this.componentBits=new t.BitSet)}return Object.defineProperty(n.prototype,"isDestroyed",{get:function(){return this._isDestroyed},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"tag",{get:function(){return this._tag},set:function(t){this.setTag(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"enabled",{get:function(){return this._enabled},set:function(t){this.setEnabled(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"updateOrder",{get:function(){return this._updateOrder},set:function(t){this.setUpdateOrder(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"parent",{get:function(){return this.transform.parent},set:function(t){this.transform.setParent(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"childCount",{get:function(){return this.transform.childCount},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"position",{get:function(){return this.transform.position},set:function(t){this.transform.setPosition(t.x,t.y)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"localPosition",{get:function(){return this.transform.localPosition},set:function(t){this.transform.setLocalPosition(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"rotation",{get:function(){return this.transform.rotation},set:function(t){this.transform.setRotation(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"rotationDegrees",{get:function(){return this.transform.rotationDegrees},set:function(t){this.transform.setRotationDegrees(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"localRotation",{get:function(){return this.transform.localRotation},set:function(t){this.transform.setLocalRotation(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"localRotationDegrees",{get:function(){return this.transform.localRotationDegrees},set:function(t){this.transform.setLocalRotationDegrees(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"scale",{get:function(){return this.transform.scale},set:function(t){this.transform.setScale(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"localScale",{get:function(){return this.transform.localScale},set:function(t){this.transform.setLocalScale(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"worldInverseTransform",{get:function(){return this.transform.worldInverseTransform},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"localToWorldTransform",{get:function(){return this.transform.localToWorldTransform},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"worldToLocalTransform",{get:function(){return this.transform.worldToLocalTransform},enumerable:!0,configurable:!0}),n.prototype.onTransformChanged=function(t){this.components.onEntityTransformChanged(t)},n.prototype.setTag=function(t){return this._tag!=t&&(this.scene&&this.scene.entities.removeFromTagList(this),this._tag=t,this.scene&&this.scene.entities.addToTagList(this)),this},n.prototype.setEnabled=function(t){return this._enabled!=t&&(this._enabled=t,this._enabled?this.components.onEntityEnabled():this.components.onEntityDisabled()),this},n.prototype.setUpdateOrder=function(t){if(this._updateOrder!=t)return this._updateOrder=t,this.scene&&(this.scene.entities.markEntityListUnsorted(),this.scene.entities.markTagUnsorted(this.tag)),this},n.prototype.destroy=function(){this._isDestroyed=!0,this.scene.entities.remove(this),this.transform.parent=null;for(var t=this.transform.childCount-1;t>=0;t--){this.transform.getChild(t).entity.destroy()}},n.prototype.detachFromScene=function(){this.scene.entities.remove(this),this.components.deregisterAllComponents();for(var t=0;t=0;t--)this._sceneComponents.buffer[t].enabled&&this._sceneComponents.buffer[t].update();null!=this.entityProcessors&&this.entityProcessors.update(),this.entities.update(),null!=this.entityProcessors&&this.entityProcessors.lateUpdate()},e.prototype.addSceneComponent=function(t){return t.scene=this,t.onEnabled(),this._sceneComponents.add(t),this._sceneComponents.sort(t),t},e.prototype.getSceneComponent=function(t){for(var e=0;ee.x?-1:1,i=t.Vector2.normalize(t.Vector2.subtract(this.position,e));this.rotation=n*Math.acos(t.Vector2.dot(i,t.Vector2.unitY))},n.prototype.setLocalRotation=function(t){return this._localRotation=t,this._localDirty=this._positionDirty=this._localPositionDirty=this._localRotationDirty=this._localScaleDirty=!0,this.setDirty(e.rotationDirty),this},n.prototype.setLocalRotationDegrees=function(e){return this.setLocalRotation(t.MathHelper.toRadians(e))},n.prototype.setScale=function(e){return this._scale=e,this.parent?this.localScale=t.Vector2.divide(e,this.parent._scale):this.localScale=e,this},n.prototype.setLocalScale=function(t){return this._localScale=t,this._localDirty=this._positionDirty=this._localScaleDirty=!0,this.setDirty(e.scaleDirty),this},n.prototype.roundPosition=function(){this.position=t.Vector2Ext.round(this._position)},n.prototype.updateTransform=function(){this.hierarchyDirty!=e.clean&&(null!=this.parent&&this.parent.updateTransform(),this._localDirty&&(this._localPositionDirty&&(this._translationMatrix=t.Matrix2D.createTranslation(this._localPosition.x,this._localPosition.y),this._localPositionDirty=!1),this._localRotationDirty&&(this._rotationMatrix=t.Matrix2D.createRotation(this._localRotation),this._localRotationDirty=!1),this._localScaleDirty&&(this._scaleMatrix=t.Matrix2D.createScale(this._localScale.x,this._localScale.y),this._localScaleDirty=!1),this._localTransform=this._scaleMatrix.multiply(this._rotationMatrix),this._localTransform=this._localTransform.multiply(this._translationMatrix),null==this.parent&&(this._worldTransform=this._localTransform,this._rotation=this._localRotation,this._scale=this._localScale,this._worldInverseDirty=!0),this._localDirty=!1),null!=this.parent&&(this._worldTransform=this._localTransform.multiply(this.parent._worldTransform),this._rotation=this._localRotation+this.parent._rotation,this._scale=t.Vector2.multiply(this.parent._scale,this._localScale),this._worldInverseDirty=!0),this._worldToLocalDirty=!0,this._positionDirty=!0,this.hierarchyDirty=e.clean)},n.prototype.setDirty=function(e){if(0==(this.hierarchyDirty&e)){switch(this.hierarchyDirty|=e,e){case t.DirtyType.positionDirty:this.entity.onTransformChanged(transform.Component.position);break;case t.DirtyType.rotationDirty:this.entity.onTransformChanged(transform.Component.rotation);break;case t.DirtyType.scaleDirty:this.entity.onTransformChanged(transform.Component.scale)}for(var n=0;n0?this._cache.shift():new this._type}catch(t){throw new Error(this._type+t)}},t.prototype.free=function(t){t.reset(),this._cache.push(t)},t}();t.ComponentPool=e}(es||(es={})),function(t){var e=function(){function t(){}return t.prototype.compare=function(t,e){return t.updateOrder-e.updateOrder},t}();t.IUpdatableComparer=e,t.isIUpdatable=function(t){return void 0!==t.update}}(es||(es={})),function(t){var e=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return __extends(e,t),e}(t.Component);t.PooledComponent=e}(es||(es={})),function(t){var e=function(){function e(){this.updateOrder=0,this._enabled=!0}return Object.defineProperty(e.prototype,"enabled",{get:function(){return this._enabled},set:function(t){this.setEnabled(t)},enumerable:!0,configurable:!0}),e.prototype.onEnabled=function(){},e.prototype.onDisabled=function(){},e.prototype.onRemovedFromScene=function(){},e.prototype.update=function(){},e.prototype.setEnabled=function(t){return this._enabled!=t&&(this._enabled=t,this._enabled?this.onEnabled():this.onDisabled()),this},e.prototype.setUpdateOrder=function(e){return this.updateOrder!=e&&(this.updateOrder=e,t.Core.scene._sceneComponents.sort(this)),this},e.prototype.compare=function(t){return this.updateOrder-t.updateOrder},e}();t.SceneComponent=e}(es||(es={})),function(t){var e=function(e){function n(){var n=e.call(this)||this;return n.shouldUseGravity=!0,n.velocity=new t.Vector2,n._mass=10,n._elasticity=.5,n._friction=.5,n._glue=.01,n._inverseMass=0,n._inverseMass=1/n._mass,n}return __extends(n,e),Object.defineProperty(n.prototype,"mass",{get:function(){return this._mass},set:function(t){this.setMass(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"elasticity",{get:function(){return this._elasticity},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"elasticiy",{set:function(t){this.setElasticity(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"friction",{get:function(){return this._friction},set:function(t){this.setFriction(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"glue",{get:function(){return this._glue},set:function(t){this.setGlue(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"isImmovable",{get:function(){return this._mass<1e-4},enumerable:!0,configurable:!0}),n.prototype.setMass=function(e){return this._mass=t.MathHelper.clamp(e,0,Number.MAX_VALUE),this._mass>1e-4?this._inverseMass=1/this._mass:this._inverseMass=0,this},n.prototype.setElasticity=function(e){return this._elasticity=t.MathHelper.clamp01(e),this},n.prototype.setFriction=function(e){return this._friction=t.MathHelper.clamp01(e),this},n.prototype.setGlue=function(e){return this._glue=t.MathHelper.clamp(e,0,10),this},n.prototype.addImpulse=function(e){this.isImmovable||(this.velocity=t.Vector2.add(this.velocity,t.Vector2.multiply(e,new t.Vector2(1e5)).multiply(new t.Vector2(this._inverseMass*t.Time.deltaTime))))},n.prototype.onAddedToEntity=function(){this._collider=this.entity.getComponent(t.Collider),null==this._collider&&console.warn("ArcadeRigidbody 没有 Collider。ArcadeRigidbody需要一个Collider!")},n.prototype.update=function(){var e,i;if(this.isImmovable||null==this._collider)this.velocity=t.Vector2.zero;else{this.shouldUseGravity&&(this.velocity=t.Vector2.add(this.velocity,t.Vector2.multiply(t.Physics.gravity,new t.Vector2(t.Time.deltaTime)))),this.entity.transform.position=t.Vector2.add(this.entity.transform.position,t.Vector2.multiply(this.velocity,new t.Vector2(t.Time.deltaTime)));var r=new t.CollisionResult,o=t.Physics.boxcastBroadphaseExcludingSelfNonRect(this._collider,this._collider.collidesWithLayers.value);try{for(var s=__values(o),a=s.next();!a.done;a=s.next()){var c=a.value;if(!c.entity.equals(this.entity)&&this._collider.collidesWithNonMotion(c,r)){var h=c.entity.getComponent(n);if(null!=h)this.processOverlap(h,r.minimumTranslationVector),this.processCollision(h,r.minimumTranslationVector);else{this.entity.transform.position=t.Vector2.subtract(this.entity.transform.position,r.minimumTranslationVector);var u=this.velocity.clone();this.calculateResponseVelocity(u,r.minimumTranslationVector,u),this.velocity=t.Vector2.add(this.velocity,u)}}}}catch(t){e={error:t}}finally{try{a&&!a.done&&(i=s.return)&&i.call(s)}finally{if(e)throw e.error}}}},n.prototype.processOverlap=function(e,n){this.isImmovable?e.entity.transform.position=t.Vector2.add(e.entity.transform.position,n):e.isImmovable?this.entity.transform.position=t.Vector2.subtract(this.entity.transform.position,n):(this.entity.transform.position=t.Vector2.subtract(this.entity.transform.position,t.Vector2.multiply(n,t.Vector2Ext.halfVector())),e.entity.transform.position=t.Vector2.add(e.entity.transform.position,t.Vector2.multiply(n,t.Vector2Ext.halfVector())))},n.prototype.processCollision=function(e,n){var i=t.Vector2.subtract(this.velocity,e.velocity);this.calculateResponseVelocity(i,n,i);var r=this._inverseMass+e._inverseMass,o=this._inverseMass/r,s=e._inverseMass/r;this.velocity=t.Vector2.add(this.velocity,new t.Vector2(i.x*o,i.y*o)),e.velocity=t.Vector2.subtract(e.velocity,new t.Vector2(i.x*s,i.y*s))},n.prototype.calculateResponseVelocity=function(e,n,i){void 0===i&&(i=new t.Vector2);var r=t.Vector2.multiply(n,new t.Vector2(-1)),o=t.Vector2.normalize(r),s=t.Vector2.dot(e,o),a=new t.Vector2(o.x*s,o.y*s),c=t.Vector2.subtract(e,a);s>0&&(a=t.Vector2.zero);var h=this._friction;c.lengthSquared()>6;0!=(e&t.LONG_MASK)&&n++,this._bits=new Array(n),this._bits.fill(0)}return t.prototype.and=function(t){for(var e,n=Math.min(this._bits.length,t._bits.length),i=0;i=0;)this._bits[e]&=~t._bits[e]},t.prototype.cardinality=function(){for(var t=0,e=this._bits.length-1;e>=0;e--){var n=this._bits[e];if(0!=n)if(-1!=n){var i=((n=((n=(n>>1&0x5555555555555400)+(0x5555555555555400&n))>>2&0x3333333333333400)+(0x3333333333333400&n))>>32)+n>>>0;t+=((i=((i=(i>>4&252645135)+(252645135&i))>>8&16711935)+(16711935&i))>>16&65535)+(65535&i)}else t+=64}return t},t.prototype.clear=function(t){if(null!=t){var e=t>>6;this.ensure(e),this._bits[e]&=~(1<>6;return!(e>=this._bits.length)&&0!=(this._bits[e]&1<=0;)if(0!=(this._bits[e]&t._bits[e]))return!0;return!1},t.prototype.isEmpty=function(){for(var t=this._bits.length-1;t>=0;t--)if(this._bits[t])return!1;return!0},t.prototype.nextSetBit=function(t){for(var e=t>>6,n=1<>6;this.ensure(n),this._bits[n]|=1<=this._bits.length){var e=this._bits.length;this._bits.length=t+1,this._bits.fill(0,e,t+1)}},t.LONG_MASK=63,t}();t.BitSet=e}(es||(es={})),function(t){var e=function(){function e(e){this._components=new t.FastList,this._updatableComponents=new t.FastList,this._componentsToAdd=[],this._componentsToRemove=[],this._tempBufferList=[],this._entity=e}return Object.defineProperty(e.prototype,"count",{get:function(){return this._components.length},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"buffer",{get:function(){return this._components.buffer},enumerable:!0,configurable:!0}),e.prototype.markEntityListUnsorted=function(){this._isComponentListUnsorted=!0},e.prototype.add=function(t){this._componentsToAdd.push(t)},e.prototype.remove=function(t){var e=new linq.List(this._componentsToRemove),n=new linq.List(this._componentsToAdd);e.contains(t)&&console.warn("您正在尝试删除一个您已经删除的组件("+t+")"),n.contains(t)?n.remove(t):e.add(t)},e.prototype.removeAllComponents=function(){for(var t=0;t0){for(var n=0;n0){n=0;for(var i=this._componentsToAdd.length;n0&&(this._entitiesToRemove.toArray().forEach(function(n){e.removeFromTagList(n),e._entities.remove(n),n.onRemovedFromScene(),n.scene=null,t.Core.entitySystemsEnabled&&e.scene.entityProcessors.onEntityRemoved(n)}),this._entitiesToRemove.clear()),this._entitiesToAdded.getCount()>0&&(this._entitiesToAdded.toArray().forEach(function(n){e._entities.add(n),n.scene=e.scene,e.addToTagList(n),t.Core.entitySystemsEnabled&&e.scene.entityProcessors.onEntityAdded(n)}),this._entitiesToAdded.toArray().forEach(function(t){t.onAddedToScene()}),this._entitiesToAdded.clear(),this._isEntityListUnsorted=!0),this._isEntityListUnsorted&&(this._entities.sort(t.Entity.entityComparer),this._isEntityListUnsorted=!1),this._unsortedTags.size>0&&(this._unsortedTags.forEach(function(t){return e._entityDict.get(t).sort(function(t,e){return t.compareTo(e)})}),this._unsortedTags.clear())},e.prototype.findEntity=function(t){for(var e=0;e=t)return n}for(e=1|t;ethis.maxPrimeArrayLength&&this.maxPrimeArrayLength>t?this.maxPrimeArrayLength:this.getPrime(e)},t.getHashCode=function(t){var e,n=0;if(0==(e="object"==typeof t?JSON.stringify(t):t.toString()).length)return n;for(var i=0;i=0;e=this.allSet.nextSetBit(e+1))if(!t.get(e))return!1;return!(!this.exclusionSet.isEmpty()&&this.exclusionSet.intersects(t))&&!(!this.oneSet.isEmpty()&&!this.oneSet.intersects(t))},e.prototype.all=function(){for(var e=this,n=[],i=0;i=e)return t;var i=!1;"-"==t.substr(0,1)&&(i=!0,t=t.substr(1));for(var r=e-n,o=0;o1?this.reverse(t.substring(1))+t.substring(0,1):t},t.cutOff=function(t,e,n,i){void 0===i&&(i=!0),e=Math.floor(e),n=Math.floor(n);var r=t.length;e>r&&(e=r);var o,s=e,a=e+n;return i?o=t.substring(0,s)+t.substr(a,r):(a=(s=r-1-e-n)+n,o=t.substring(0,s+1)+t.substr(a+1,r)),o},t.strReplace=function(t,e){for(var n=0,i=e.length;n",">",'"',""","'","'","®","®","©","©","™","™"],t}();!function(t){var e=function(){function t(){}return t.update=function(t){var e=(t-this._lastTime)/1e3;this.totalTime+=e,this.deltaTime=e*this.timeScale,this.unscaledDeltaTime=e,this.timeSinceSceneLoad+=e,this.frameCount++,this._lastTime=t},t.sceneChanged=function(){this.timeSinceSceneLoad=0},t.checkEvery=function(t){return this.timeSinceSceneLoad/t>(this.timeSinceSceneLoad-this.deltaTime)/t},t.deltaTime=0,t.timeScale=1,t.frameCount=0,t._lastTime=0,t}();t.Time=e}(es||(es={}));var stopwatch,TimeUtils=function(){function t(){}return t.monthId=function(t){void 0===t&&(t=null);var e=(t=t||new Date).getFullYear(),n=t.getMonth()+1;return parseInt(e+(n<10?"0":"")+n)},t.dateId=function(t){void 0===t&&(t=null);var e=(t=t||new Date).getMonth()+1,n=e<10?"0":"",i=t.getDate(),r=i<10?"0":"";return parseInt(t.getFullYear()+n+e+r+i)},t.weekId=function(t,e){void 0===t&&(t=null),void 0===e&&(e=!0),t=t||new Date;var n=new Date;n.setTime(t.getTime()),n.setDate(1),n.setMonth(0);var i=n.getFullYear(),r=n.getDay();0==r&&(r=7);var o=!1;r<=4?(o=r>1,n.setDate(n.getDate()-(r-1))):n.setDate(n.getDate()+7-r+1);var s=this.diffDay(t,n,!1);if(s<0)return n.setDate(1),n.setMonth(0),n.setDate(n.getDate()-1),this.weekId(n,!1);var a=s/7,c=Math.floor(a)+1;if(53==c){n.setTime(t.getTime()),n.setDate(n.getDate()-1);var h=n.getDay();if(0==h&&(h=7),e&&(!o||h<4))return n.setFullYear(n.getFullYear()+1),n.setDate(1),n.setMonth(0),this.weekId(n,!1)}return parseInt(i+"00"+(c>9?"":"0")+c)},t.diffDay=function(t,e,n){void 0===n&&(n=!1);var i=(t.getTime()-e.getTime())/864e5;return n?Math.ceil(i):Math.floor(i)},t.getFirstDayOfWeek=function(t){var e=(t=t||new Date).getDay()||7;return new Date(t.getFullYear(),t.getMonth(),t.getDate()+1-e,0,0,0,0)},t.getFirstOfDay=function(t){return(t=t||new Date).setHours(0,0,0,0),t},t.getNextFirstOfDay=function(t){return new Date(this.getFirstOfDay(t).getTime()+864e5)},t.formatDate=function(t){var e=t.getFullYear(),n=t.getMonth()+1;n=n<10?"0"+n:n;var i=t.getDate();return e+"-"+n+"-"+(i=i<10?"0"+i:i)},t.formatDateTime=function(t){var e=t.getFullYear(),n=t.getMonth()+1;n=n<10?"0"+n:n;var i=t.getDate();i=i<10?"0"+i:i;var r=t.getHours(),o=t.getMinutes();o=o<10?"0"+o:o;var s=t.getSeconds();return e+"-"+n+"-"+i+" "+r+":"+o+":"+(s=s<10?"0"+s:s)},t.parseDate=function(t){var e=Date.parse(t);return isNaN(e)?new Date:new Date(Date.parse(t.replace(/-/g,"/")))},t.secondToTime=function(t,e,n){void 0===t&&(t=0),void 0===e&&(e=":"),void 0===n&&(n=!0);var i=Math.floor(t/3600),r=Math.floor(t%3600/60),o=Math.floor(t%3600%60),s=i.toString(),a=r.toString(),c=o.toString();return i<10&&(s="0"+s),r<10&&(a="0"+a),o<10&&(c="0"+c),n?s+e+a+e+c:a+e+c},t.timeToMillisecond=function(t,e){void 0===e&&(e=":");for(var n=t.split(e),i=0,r=n.length,o=0;o=1?(e.value=1,n=this._points.length-4):(e.value=t.MathHelper.clamp01(e.value)*this._curveCount,n=~~e,e.value-=n,n*=3),n},e.prototype.setControlPoint=function(e,n){if(e%3==0){var i=t.Vector2.subtract(n,this._points.buffer[e]);e>0&&this._points.buffer[e-1].add(i),e+1n?n:t},e.pointOnCirlce=function(n,i,r){var o=e.toRadians(r);return new t.Vector2(Math.cos(o)*o+n.x,Math.sin(o)*o+n.y)},e.isEven=function(t){return t%2==0},e.clamp01=function(t){return t<0?0:t>1?1:t},e.angleBetweenVectors=function(t,e){return Math.atan2(e.y-t.y,e.x-t.x)},e.angleToVector=function(e,n){return new t.Vector2(Math.cos(e)*n,Math.sin(e)*n)},e.incrementWithWrap=function(t,e){return++t==e?0:t},e.approach=function(t,e,n){return ti&&(i=s.x),s.yr&&(r=s.y)}return this.fromMinMax(e,n,i,r)},e.prototype.getSide=function(e){switch(e){case t.Edge.top:return this.top;case t.Edge.bottom:return this.bottom;case t.Edge.left:return this.left;case t.Edge.right:return this.right;default:throw new Error("Argument Out Of Range")}},e.prototype.contains=function(t,e){return this.x<=t&&tthis.x+this.width)return!1}else{var i=1/t.direction.x,r=(this.x-t.start.x)*i,o=(this.x+this.width-t.start.x)*i;if(r>o){var s=r;r=o,o=s}if(e.value=Math.max(r,e.value),n=Math.min(o,n),e.value>n)return!1}if(Math.abs(t.direction.y)<1e-6){if(t.start.ythis.y+this.height)return!1}else{var a=1/t.direction.y,c=(this.y-t.start.y)*a,h=(this.y+this.height-t.start.y)*a;if(c>h){var u=c;c=h,h=u}if(e.value=Math.max(c,e.value),n=Math.max(h,n),e.value>n)return!1}return!0},e.prototype.containsRect=function(t){return this.x<=t.x&&t.x0?this.x:this.x+t,i.y=n>0?this.y:this.y+n,i.width=t>0?t+this.width:this.width-t,i.height=n>0?n+this.height:this.height-n,i},e.prototype.collisionCheck=function(t,e,n){e.value=n.value=0;var i=t.x-(this.x+this.width),r=t.x+t.width-this.x,o=t.y-(this.y+this.height),s=t.y+t.height-this.y;return!(i>0||r<0||o>0||s<0)&&(e.value=Math.abs(i)=l||Math.abs(u)>=p)return t.Vector2.zero;var f=h>0?l-h:-l-h,d=u>0?p-u:-p-u;return new t.Vector2(f,d)},e.prototype.equals=function(t){return this===t},e.prototype.getHashCode=function(){return this.x^this.y^this.width^this.height},e.prototype.clone=function(){return new e(this.x,this.y,this.width,this.height)},e}();t.Rectangle=e}(es||(es={})),function(t){var e=function(){function t(){this.remainder=0}return t.prototype.update=function(t){this.remainder+=t;var e=Math.floor(Math.trunc(this.remainder));return this.remainder-=e,t=e},t.prototype.reset=function(){this.remainder=0},t}();t.SubpixelFloat=e}(es||(es={})),function(t){var e=function(){function e(){this._x=new t.SubpixelFloat,this._y=new t.SubpixelFloat}return e.prototype.update=function(t){t.x=this._x.update(t.x),t.y=this._y.update(t.y)},e.prototype.reset=function(){this._x.reset(),this._y.reset()},e}();t.SubpixelVector2=e}(es||(es={})),function(t){var e=function(){function e(t,e){this.x=0,this.y=0,this.x=t||0,this.y=null!=e?e:this.x}return Object.defineProperty(e,"zero",{get:function(){return new e(0,0)},enumerable:!0,configurable:!0}),Object.defineProperty(e,"one",{get:function(){return new e(1,1)},enumerable:!0,configurable:!0}),Object.defineProperty(e,"unitX",{get:function(){return new e(1,0)},enumerable:!0,configurable:!0}),Object.defineProperty(e,"unitY",{get:function(){return new e(0,1)},enumerable:!0,configurable:!0}),e.add=function(t,n){var i=e.zero;return i.x=t.x+n.x,i.y=t.y+n.y,i},e.divide=function(t,n){var i=e.zero;return i.x=t.x/n.x,i.y=t.y/n.y,i},e.multiply=function(t,n){var i=new e(0,0);return i.x=t.x*n.x,i.y=t.y*n.y,i},e.subtract=function(t,n){var i=new e(0,0);return i.x=t.x-n.x,i.y=t.y-n.y,i},e.normalize=function(t){var n=new e(t.x,t.y),i=1/Math.sqrt(n.x*n.x+n.y*n.y);return n.x*=i,n.y*=i,n},e.dot=function(t,e){return t.x*e.x+t.y*e.y},e.distanceSquared=function(t,e){var n=t.x-e.x,i=t.y-e.y;return n*n+i*i},e.clamp=function(n,i,r){return new e(t.MathHelper.clamp(n.x,i.x,r.x),t.MathHelper.clamp(n.y,i.y,r.y))},e.lerp=function(n,i,r){return new e(t.MathHelper.lerp(n.x,i.x,r),t.MathHelper.lerp(n.y,i.y,r))},e.transform=function(t,n){return new e(t.x*n.m11+t.y*n.m21+n.m31,t.x*n.m12+t.y*n.m22+n.m32)},e.distance=function(t,e){var n=t.x-e.x,i=t.y-e.y;return Math.sqrt(n*n+i*i)},e.angle=function(n,i){return n=e.normalize(n),i=e.normalize(i),Math.acos(t.MathHelper.clamp(e.dot(n,i),-1,1))*t.MathHelper.Rad2Deg},e.negate=function(t){return t.x=-t.x,t.y=-t.y,t},e.prototype.add=function(t){return this.x+=t.x,this.y+=t.y,this},e.prototype.divide=function(t){return this.x/=t.x,this.y/=t.y,this},e.prototype.multiply=function(t){return this.x*=t.x,this.y*=t.y,this},e.prototype.subtract=function(t){return this.x-=t.x,this.y-=t.y,this},e.prototype.normalize=function(){var t=1/Math.sqrt(this.x*this.x+this.y*this.y);this.x*=t,this.y*=t},e.prototype.length=function(){return Math.sqrt(this.x*this.x+this.y*this.y)},e.prototype.lengthSquared=function(){return this.x*this.x+this.y*this.y},e.prototype.round=function(){return new e(Math.round(this.x),Math.round(this.y))},e.prototype.angleBetween=function(n,i){var r=e.subtract(n,this),o=e.subtract(i,this);return t.Vector2Ext.angle(r,o)},e.prototype.equals=function(t){return t instanceof e&&(t.x==this.x&&t.y==this.y)},e.prototype.clone=function(){return new e(this.x,this.y)},e}();t.Vector2=e}(es||(es={})),function(t){var e=function(){function e(e){this._activeTriggerIntersections=new t.HashSet,this._previousTriggerIntersections=new t.HashSet,this._tempTriggerList=[],this._entity=e}return e.prototype.update=function(){for(var e=this._entity.getComponents(t.Collider),n=0;n1)return!1;var u=(c.x*o.y-c.y*o.x)/a;return!(u<0||u>1)},n.lineToLineIntersection=function(e,n,i,r,o){void 0===o&&(o=new t.Vector2),o.x=0,o.y=0;var s=t.Vector2.subtract(n,e),a=t.Vector2.subtract(r,i),c=s.x*a.y-s.y*a.x;if(0==c)return!1;var h=t.Vector2.subtract(i,e),u=(h.x*a.y-h.y*a.x)/c;if(u<0||u>1)return!1;var l=(h.x*s.y-h.y*s.x)/c;if(l<0||l>1)return!1;var p=t.Vector2.add(e,new t.Vector2(u*s.x,u*s.y));return o.x=p.x,o.y=p.y,!0},n.closestPointOnLine=function(e,n,i){var r=t.Vector2.subtract(n,e),o=t.Vector2.subtract(i,e),s=t.Vector2.dot(o,r)/t.Vector2.dot(r,r);return s=t.MathHelper.clamp(s,0,1),t.Vector2.add(e,new t.Vector2(r.x*s,r.y*s))},n.circleToCircle=function(e,n,i,r){return t.Vector2.distanceSquared(e,i)<(n+r)*(n+r)},n.circleToLine=function(e,n,i,r){return t.Vector2.distanceSquared(e,this.closestPointOnLine(i,r,e))=t&&r.y>=e&&r.x=t+i&&(s|=e.right),o.y=n+r&&(s|=e.bottom),s},n}();t.Collisions=n}(es||(es={})),function(t){var e=function(){function e(e,n,i,r,o){this.fraction=0,this.distance=0,this.point=t.Vector2.zero,this.normal=t.Vector2.zero,this.collider=e,this.fraction=n,this.distance=i,this.point=r,this.centroid=t.Vector2.zero}return e.prototype.setValues=function(t,e,n,i){this.collider=t,this.fraction=e,this.distance=n,this.point=i},e.prototype.setValuesNonCollider=function(t,e,n,i){this.fraction=t,this.distance=e,this.point=n,this.normal=i},e.prototype.reset=function(){this.collider=null,this.fraction=this.distance=0},e.prototype.toString=function(){return"[RaycastHit] fraction: "+this.fraction+", distance: "+this.distance+", normal: "+this.normal+", centroid: "+this.centroid+", point: "+this.point},e}();t.RaycastHit=e}(es||(es={})),function(t){var e=function(){function e(){}return e.reset=function(){this._spatialHash=new t.SpatialHash(this.spatialHashCellSize),this._hitArray[0].reset()},e.clear=function(){this._spatialHash.clear()},e.overlapCircleAll=function(t,e,n,i){if(void 0===i&&(i=-1),0!=n.length)return this._spatialHash.overlapCircle(t,e,n,i);console.error("传入了一个空的结果数组。不会返回任何结果")},e.boxcastBroadphase=function(t,e){return void 0===e&&(e=this.allLayers),this._spatialHash.aabbBroadphase(t,null,e)},e.boxcastBroadphaseExcludingSelf=function(t,e,n){return void 0===n&&(n=this.allLayers),this._spatialHash.aabbBroadphase(e,t,n)},e.boxcastBroadphaseExcludingSelfNonRect=function(t,e){void 0===e&&(e=this.allLayers);var n=t.bounds.clone();return this._spatialHash.aabbBroadphase(n,t,e)},e.addCollider=function(t){e._spatialHash.register(t)},e.removeCollider=function(t){e._spatialHash.remove(t)},e.updateCollider=function(t){this._spatialHash.remove(t),this._spatialHash.register(t)},e.linecast=function(t,n,i){return void 0===i&&(i=e.allLayers),this._hitArray[0].reset(),this.linecastAll(t,n,this._hitArray,i),this._hitArray[0]},e.linecastAll=function(t,n,i,r){return void 0===r&&(r=e.allLayers),0==i.length?(console.warn("传入了一个空的hits数组。没有点击会被返回"),0):this._spatialHash.linecast(t,n,i,r)},e.gravity=new t.Vector2(0,300),e.spatialHashCellSize=100,e.allLayers=-1,e.raycastsHitTriggers=!1,e.raycastsStartInColliders=!1,e._hitArray=[new t.RaycastHit],e}();t.Physics=e}(es||(es={})),function(t){var e=function(){return function(e,n){this.start=e,this.end=n,this.direction=t.Vector2.subtract(this.end,this.start)}}();t.Ray2D=e}(es||(es={})),function(t){var e=function(){function e(e){void 0===e&&(e=100),this.gridBounds=new t.Rectangle,this._overlapTestCircle=new t.Circle(0),this._cellDict=new n,this._tempHashSet=new Set,this._cellSize=e,this._inverseCellSize=1/this._cellSize,this._raycastParser=new i}return e.prototype.register=function(e){var n=e.bounds.clone();e.registeredPhysicsBounds=n;var i=this.cellCoords(n.x,n.y),r=this.cellCoords(n.right,n.bottom);this.gridBounds.contains(i.x,i.y)||(this.gridBounds=t.RectangleExt.union(this.gridBounds,i)),this.gridBounds.contains(r.x,r.y)||(this.gridBounds=t.RectangleExt.union(this.gridBounds,r));for(var o=i.x;o<=r.x;o++)for(var s=i.y;s<=r.y;s++){this.cellAtPosition(o,s,!0).push(e)}},e.prototype.remove=function(t){for(var e=t.registeredPhysicsBounds.clone(),n=this.cellCoords(e.x,e.y),i=this.cellCoords(e.right,e.bottom),r=n.x;r<=i.x;r++)for(var o=n.y;o<=i.y;o++){var s=this.cellAtPosition(r,o);s?new linq.List(s).remove(t):console.log("从不存在碰撞器的单元格中移除碰撞器: ["+t+"]")}},e.prototype.removeWithBruteForce=function(t){this._cellDict.remove(t)},e.prototype.clear=function(){this._cellDict.clear()},e.prototype.aabbBroadphase=function(e,n,i){this._tempHashSet.clear();for(var r=this.cellCoords(e.x,e.y),o=this.cellCoords(e.right,e.bottom),s=r.x;s<=o.x;s++)for(var a=r.y;a<=o.y;a++){var c=this.cellAtPosition(s,a);if(null!=c)for(var h=0;h>>0},t.prototype.clear=function(){this._store.clear()},t}();t.NumberDictionary=n;var i=function(){function e(){this._tempHit=new t.RaycastHit,this._checkedColliders=[],this._cellHits=[]}return e.prototype.start=function(t,e,n){this._ray=t,this._hits=e,this._layerMask=n,this.hitCounter=0},e.prototype.checkRayIntersection=function(n,i,r){for(var o=new t.Ref(0),s=0;s=this.points.length?this.points[0]:this.points[i+1];var o=t.Vector2Ext.perpendicular(r,e);t.Vector2Ext.normalize(o),this._edgeNormals[i]=o}},n.buildSymmetricalPolygon=function(e,n){for(var i=new Array(e),r=0;rr&&(r=s,i=o)}return e[i]},n.getClosestPointOnPolygonToPoint=function(e,n,i,r){i.value=Number.MAX_VALUE,r.x=0,r.y=0;for(var o=t.Vector2.zero,s=0,a=0;at.y!=this.points[i].y>t.y&&t.x<(this.points[i].x-this.points[n].x)*(t.y-this.points[n].y)/(this.points[i].y-this.points[n].y)+this.points[n].x&&(e=!e);return e},n.prototype.pointCollidesWithShape=function(e,n){return t.ShapeCollisions.pointToPoly(e,this,n)},n}(t.Shape);t.Polygon=e}(es||(es={})),function(t){var e=function(e){function n(t,i){var r=e.call(this,n.buildBox(t,i),!0)||this;return r.width=t,r.height=i,r}return __extends(n,e),n.buildBox=function(e,n){var i=e/2,r=n/2,o=new Array(4);return o[0]=new t.Vector2(-i,-r),o[1]=new t.Vector2(i,-r),o[2]=new t.Vector2(i,r),o[3]=new t.Vector2(-i,r),o},n.prototype.updateBox=function(e,n){this.width=e,this.height=n;var i=e/2,r=n/2;this.points[0]=new t.Vector2(-i,-r),this.points[1]=new t.Vector2(i,-r),this.points[2]=new t.Vector2(i,r),this.points[3]=new t.Vector2(-i,r);for(var o=0;o1)return!1;var a,c=t.Vector2.add(s.start,t.Vector2.multiply(s.direction,new t.Vector2(r.value))),h=0;c.xn.bounds.right&&(h|=1),c.yn.bounds.bottom&&(h|=2);var u=a+h;return 3==u&&console.log("m == 3. corner "+t.Time.frameCount),!0},e.corner=function(e,n){var i=new t.Vector2;return i.x=0==(1&n)?e.right:e.left,i.y=0==(1&n)?e.bottom:e.top,i},e.testCircleBox=function(e,n,i){i=n.bounds.getClosestPointOnRectangleToPoint(e.position);var r=t.Vector2.subtract(i,e.position);return t.Vector2.dot(r,r)<=e.radius*e.radius},e}();t.RealtimeCollisions=e}(es||(es={})),function(t){var e=function(){function e(){}return e.polygonToPolygon=function(e,n,i){for(var r,o=!0,s=e.edgeNormals.slice(),a=n.edgeNormals.slice(),c=Number.POSITIVE_INFINITY,h=new t.Vector2,u=t.Vector2.subtract(e.position,n.position),l=0;l0&&(o=!1),!o)return!1;(y=Math.abs(y))r.value&&(r.value=o)},e.circleToPolygon=function(e,n,i){void 0===i&&(i=new t.CollisionResult);var r,o=t.Vector2.subtract(e.position,n.position),s=new t.Ref(0),a=t.Polygon.getClosestPointOnPolygonToPoint(n.points,o,s,i.normal),c=n.containsPoint(e.position);if(s.value>e.radius*e.radius&&!c)return!1;if(c)r=t.Vector2.multiply(i.normal,new t.Vector2(Math.sqrt(s.value)-e.radius));else if(0==s.value)r=new t.Vector2(i.normal.x*e.radius,i.normal.y*e.radius);else{var h=Math.sqrt(s.value);r=t.Vector2.subtract(new t.Vector2(-1),t.Vector2.subtract(o,a)).multiply(new t.Vector2((e.radius-h)/h))}return i.minimumTranslationVector=r,i.point=t.Vector2.add(a,n.position),!0},e.circleToBox=function(e,n,i){void 0===i&&(i=new t.CollisionResult);var r=n.bounds.getClosestPointOnRectangleBorderToPoint(e.position,i.normal);if(n.containsPoint(e.position)){i.point=r.clone();var o=t.Vector2.add(r,t.Vector2.multiply(i.normal,new t.Vector2(e.radius)));return i.minimumTranslationVector=t.Vector2.subtract(e.position,o),!0}var s=t.Vector2.distanceSquared(r,e.position);if(0==s)i.minimumTranslationVector=t.Vector2.multiply(i.normal,new t.Vector2(e.radius));else if(s<=e.radius*e.radius){i.normal=t.Vector2.subtract(e.position,r);var a=i.normal.length()-e.radius;return i.point=r,t.Vector2Ext.normalize(i.normal),i.minimumTranslationVector=t.Vector2.multiply(new t.Vector2(a),i.normal),!0}return!1},e.pointToCircle=function(e,n,i){var r=t.Vector2.distanceSquared(e,n.position),o=1+n.radius;if(r1)return!1;var l=(h.x*s.y-h.y*s.x)/c;return!(l<0||l>1)&&(t.Vector2.add(e,t.Vector2.multiply(new t.Vector2(u),s)),!0)},e.lineToCircle=function(e,n,i,r){var o=t.Vector2.distance(e,n),s=t.Vector2.divide(t.Vector2.subtract(n,e),new t.Vector2(o)),a=t.Vector2.subtract(e,i.position),c=t.Vector2.dot(a,s),h=t.Vector2.dot(a,a)-i.radius*i.radius;if(h>0&&c>0)return!1;var u=c*c-h;return!(u<0)&&(r.fraction=-c-Math.sqrt(u),r.fraction<0&&(r.fraction=0),r.point=t.Vector2.add(e,t.Vector2.multiply(new t.Vector2(r.fraction),s)),r.distance=t.Vector2.distance(e,r.point),r.normal=t.Vector2.normalize(t.Vector2.subtract(r.point,i.position)),r.fraction=r.distance/o,!0)},e.boxToBoxCast=function(e,n,i,r){var o=this.minkowskiDifference(e,n);if(o.contains(0,0)){var s=o.getClosestPointOnBoundsToOrigin();return!s.equals(t.Vector2.zero)&&(r.normal=new t.Vector2(-s.x),r.normal.normalize(),r.distance=0,r.fraction=0,!0)}var a=new t.Ray2D(t.Vector2.zero,new t.Vector2(-i.x)),c=new t.Ref(0);return!!(o.rayIntersects(a,c)&&c.value<=1)&&(r.fraction=c.value,r.distance=i.length()*c.value,r.normal=new t.Vector2(-i.x,-i.y),r.normal.normalize(),r.centroid=t.Vector2.add(e.bounds.center,t.Vector2.multiply(i,new t.Vector2(c.value))),!0)},e}();t.ShapeCollisions=e}(es||(es={})),function(t){var e=function(){return function(t,e){this.func=t,this.context=e}}();t.FuncPack=e;var n=function(){function t(){this._messageTable=new Map}return t.prototype.addObserver=function(t,n,i){var r=this._messageTable.get(t);r||(r=[],this._messageTable.set(t,r)),-1!=r.findIndex(function(t){return t.func==n})&&console.warn("您试图添加相同的观察者两次"),r.push(new e(n,i))},t.prototype.removeObserver=function(t,e){var n=this._messageTable.get(t),i=n.findIndex(function(t){return t.func==e});-1!=i&&new linq.List(n).removeAt(i)},t.prototype.emit=function(t,e){var n=this._messageTable.get(t);if(n)for(var i=n.length-1;i>=0;i--)n[i].func.call(n[i].context,e)},t}();t.Emitter=n}(es||(es={})),function(t){!function(t){t[t.top=0]="top",t[t.bottom=1]="bottom",t[t.left=2]="left",t[t.right=3]="right"}(t.Edge||(t.Edge={}))}(es||(es={})),function(t){var e=function(){function t(){}return t.repeat=function(t,e){for(var n=[];e--;)n.push(t);return n},t}();t.Enumerable=e}(es||(es={})),function(t){var e=function(){function t(){}return t.default=function(){return new t},t.prototype.equals=function(t,e){return"function"==typeof t.equals?t.equals(e):t===e},t.prototype.getHashCode=function(t){var e=this;if("number"==typeof t)return this._getHashCodeForNumber(t);if("string"==typeof t)return this._getHashCodeForString(t);var n=385229220;return this.forOwn(t,function(t){"number"==typeof t?n+=e._getHashCodeForNumber(t):"string"==typeof t?n+=e._getHashCodeForString(t):"object"==typeof t&&e.forOwn(t,function(){n+=e.getHashCode(t)})}),n},t.prototype._getHashCodeForNumber=function(t){return t},t.prototype._getHashCodeForString=function(t){for(var e=385229220,n=0;n3&&o<500;){o++;var a=!0,c=n[this._triPrev[s]],h=n[s],u=n[this._triNext[s]];if(t.Vector2Ext.isTriangleCCW(c,h,u)){var l=this._triNext[this._triNext[s]];do{if(e.testPointTriangle(n[l],c,h,u)){a=!1;break}l=this._triNext[l]}while(l!=this._triPrev[s])}else a=!1;a?(this.triangleIndices.push(this._triPrev[s]),this.triangleIndices.push(s),this.triangleIndices.push(this._triNext[s]),this._triNext[this._triPrev[s]]=this._triNext[s],this._triPrev[this._triNext[s]]=this._triPrev[s],r--,s=this._triPrev[s]):s=this._triNext[s]}this.triangleIndices.push(this._triPrev[s]),this.triangleIndices.push(s),this.triangleIndices.push(this._triNext[s]),i||this.triangleIndices.reverse()},e.prototype.initialize=function(t){this.triangleIndices.length=0,this._triNext.length=this.length)throw new Error("index超出范围!");this.length--,new linq.List(this.buffer).removeAt(t)},e.prototype.contains=function(e){for(var n=t.EqualityComparer.default(),i=0;i=this.buffer.length&&(this.buffer.length=Math.max(this.buffer.length<<1,this.length+t))},e.prototype.addRange=function(t){var e,n;try{for(var i=__values(t),r=i.next();!r.done;r=i.next()){var o=r.value;this.add(o)}}catch(t){e={error:t}}finally{try{r&&!r.done&&(n=i.return)&&n.call(i)}finally{if(e)throw e.error}}},e.prototype.sort=function(t){this.buffer.sort(t.compare)},e}();t.FastList=e}(es||(es={})),function(t){var e=function(){function e(e){void 0===e&&(e=1),this._freeValueCellIndex=0,this._collisions=0,this._valuesInfo=new Array(e),this._values=new Array(e),this._buckets=new Array(t.HashHelpers.getPrime(e))}return e.prototype.getValuesArray=function(t){return t.value=this._freeValueCellIndex,this._values},Object.defineProperty(e.prototype,"valuesArray",{get:function(){return this._values},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"count",{get:function(){return this._freeValueCellIndex},enumerable:!0,configurable:!0}),e.prototype.add=function(t,e){if(!this.addValue(t,e,{value:0}))throw new Error("key 已经存在")},e.prototype.addValue=function(i,r,o){var s=t.HashHelpers.getHashCode(i),a=e.reduce(s,this._buckets.length);if(this._freeValueCellIndex==this._values.length){var c=t.HashHelpers.expandPrime(this._freeValueCellIndex);this._values.length=c,this._valuesInfo.length=c}var h=t.NumberExtension.toNumber(this._buckets[a])-1;if(-1==h)this._valuesInfo[this._freeValueCellIndex]=new n(i,s);else{var u=h;do{if(this._valuesInfo[u].hashcode==s&&this._valuesInfo[u].key==i)return this._values[u]=r,o.value=u,!1;u=this._valuesInfo[u].previous}while(-1!=u);this._collisions++,this._valuesInfo[this._freeValueCellIndex]=new n(i,s,h),this._valuesInfo[h].next=this._freeValueCellIndex}if(this._buckets[a]=this._freeValueCellIndex+1,this._values[this._freeValueCellIndex]=r,o.value=this._freeValueCellIndex,this._freeValueCellIndex++,this._collisions>this._buckets.length){this._buckets=new Array(t.HashHelpers.expandPrime(this._collisions)),this._collisions=0;for(var l=0;l=e?t%e:t},e}();t.FasterDictionary=e;var n=function(){return function(t,e,n){void 0===n&&(n=-1),this.key=t,this.hashcode=e,this.previous=n,this.next=-1}}();t.FastNode=n}(es||(es={})),function(t){var e=function(){return function(t,e){this.element=t,this.next=e}}();function n(t,e){return t===e}t.Node=e,t.defaultEquals=n;var i=function(){function t(t){void 0===t&&(t=n),this.count=0,this.next=void 0,this.equalsFn=t,this.head=null}return t.prototype.push=function(t){var n,i=new e(t);if(null==this.head)this.head=i;else{for(n=this.head;null!=n.next;)n=n.next;n.next=i}this.count++},t.prototype.removeAt=function(t){if(t>=0&&t=0&&t<=this.count){for(var e=this.head,n=0;n=0&&n<=this.count){var i=new e(t);if(0===n)i.next=this.head,this.head=i;else{var r=this.getElementAt(n-1);i.next=r.next,r.next=i}return this.count++,!0}return!1},t.prototype.indexOf=function(t){for(var e=this.head,n=0;n0)for(var e=0;ethis._objectQueue.length;)this._objectQueue.shift()},t.clearCache=function(){this._objectQueue.length=0},t.obtain=function(){return this._objectQueue.length>0?this._objectQueue.shift():[]},t.free=function(t){this._objectQueue.unshift(t),t.length=0},t._objectQueue=[],t}();t.ListPool=e}(es||(es={})),function(t){var e=function(){function e(t,e){this.first=t,this.second=e}return e.prototype.clear=function(){this.first=this.second=null},e.prototype.equals=function(t){return this.first==t.first&&this.second==t.second},e.prototype.getHashCode=function(){return 37*t.EqualityComparer.default().getHashCode(this.first)+t.EqualityComparer.default().getHashCode(this.second)},e}();t.Pair=e}(es||(es={})),function(t){var e=function(){function e(){}return e.warmCache=function(t,e){if((e-=this._objectQueue.length)>0)for(var n=0;nthis._objectQueue.length;)this._objectQueue.shift()},e.clearCache=function(){this._objectQueue.length=0},e.obtain=function(t){return this._objectQueue.length>0?this._objectQueue.shift():new t},e.free=function(e){this._objectQueue.unshift(e),t.isIPoolable(e)&&e.reset()},e._objectQueue=[],e}();t.Pool=e,t.isIPoolable=function(t){return void 0!==t.reset}}(es||(es={})),function(t){var e=function(t){function e(e){return t.call(this,e)||this}return __extends(e,t),e.prototype.getHashCode=function(t){return t.getHashCode()},e.prototype.areEqual=function(t,e){return t.equals(e)},e}(function(){function t(t){var e=this;this.clear(),t&&t.forEach(function(t){e.add(t)})}return t.prototype.add=function(t){var e=this,n=this.getHashCode(t),i=this.buckets[n];if(void 0===i){var r=new Array;return r.push(t),this.buckets[n]=r,this.count=this.count+1,!0}return!i.some(function(n){return e.areEqual(n,t)})&&(i.push(t),this.count=this.count+1,!0)},t.prototype.remove=function(t){var e=this,n=this.getHashCode(t),i=this.buckets[n];if(void 0===i)return!1;var r=!1,o=new Array;return i.forEach(function(n){e.areEqual(n,t)?r=!0:o.push(t)}),this.buckets[n]=o,r&&(this.count=this.count-1),r},t.prototype.contains=function(t){return this.bucketsContains(this.buckets,t)},t.prototype.getCount=function(){return this.count},t.prototype.clear=function(){this.buckets=new Array,this.count=0},t.prototype.toArray=function(){var t=new Array;return this.buckets.forEach(function(e){e.forEach(function(e){t.push(e)})}),t},t.prototype.exceptWith=function(t){var e=this;t&&t.forEach(function(t){e.remove(t)})},t.prototype.intersectWith=function(t){var e=this;if(t){var n=this.buildInternalBuckets(t);this.toArray().forEach(function(t){e.bucketsContains(n.Buckets,t)||e.remove(t)})}else this.clear()},t.prototype.unionWith=function(t){var e=this;t.forEach(function(t){e.add(t)})},t.prototype.isSubsetOf=function(t){var e=this,n=this.buildInternalBuckets(t);return this.toArray().every(function(t){return e.bucketsContains(n.Buckets,t)})},t.prototype.isSupersetOf=function(t){var e=this;return t.every(function(t){return e.contains(t)})},t.prototype.overlaps=function(t){var e=this;return t.some(function(t){return e.contains(t)})},t.prototype.setEquals=function(t){var e=this;return this.buildInternalBuckets(t).Count===this.count&&t.every(function(t){return e.contains(t)})},t.prototype.buildInternalBuckets=function(t){var e=this,n=new Array,i=0;return t.forEach(function(t){var r=e.getHashCode(t),o=n[r];if(void 0===o){var s=new Array;s.push(t),n[r]=s,i+=1}else o.some(function(n){return e.areEqual(n,t)})||(o.push(t),i+=1)}),{Buckets:n,Count:i}},t.prototype.bucketsContains=function(t,e){var n=this,i=t[this.getHashCode(e)];return void 0!==i&&i.some(function(t){return n.areEqual(t,e)})},t}());t.HashSet=e}(es||(es={}));var ArrayUtils=function(){function t(){}return t.bubbleSort=function(t){for(var e=!1,n=0;nn;i--)if(t[i]0&&t[r-1]>i;r--)t[r]=t[r-1];t[r]=i}},t.binarySearch=function(t,e){for(var n=0,i=t.length,r=n+i>>1;n=t[r]&&(n=r+1),r=n+i>>1;return t[n]==e?n:-1},t.findElementIndex=function(t,e){for(var n=t.length,i=0;it[e]&&(e=i);return e},t.getMinElementIndex=function(t){for(var e=0,n=t.length,i=1;i=0;--r)n.unshift(e[r]);return n},t.getDifferAry=function(t,e){t=this.getUniqueAry(t),e=this.getUniqueAry(e);for(var n=t.concat(e),i={},r=[],o=n.length,s=0;s=0;e-=1)t.splice(e,1)},t.cloneList=function(t){return t?t.slice(0,t.length):null},t.equals=function(t,e){if(t==e)return!0;var n=t.length;if(n!=e.length)return!1;for(;n--;)if(t[n]!=e[n])return!1;return!0},t.insert=function(t,e,n){if(!t)return null;var i=t.length;if(e>i&&(e=i),e<0&&(e=0),e==i)t.push(n);else if(0==e)t.unshift(n);else{for(var r=i-1;r>=e;r-=1)t[r+1]=t[r];t[e]=n}return n},t.shuffle=function(t){for(var e=t.length;e>1;){e--;var n=RandomUtils.randint(0,e+1),i=t[n];t[n]=t[e],t[e]=i}},t.addIfNotPresent=function(t,e){return!new linq.List(t).contains(e)&&(t.push(e),!0)},t.lastItem=function(t){return t[t.length-1]},t.randomItem=function(t){return t[RandomUtils.randint(0,t.length-1)]},t.randomItems=function(t,e){for(var n=new Set;n.size!=e;){var i=this.randomItem(t);n.has(i)||n.add(i)}var r=es.ListPool.obtain();return n.forEach(function(t){return r.push(t)}),r},t}();!function(t){var e=function(){function t(){}return Object.defineProperty(t,"nativeBase64",{get:function(){return"function"==typeof window.atob},enumerable:!0,configurable:!0}),t.decode=function(t){if(t=t.replace(/[^A-Za-z0-9\+\/\=]/g,""),this.nativeBase64)return window.atob(t);for(var e,n,i,r,o,s,a=[],c=0;c>4,n=(15&r)<<4|(o=this._keyStr.indexOf(t.charAt(c++)))>>2,i=(3&o)<<6|(s=this._keyStr.indexOf(t.charAt(c++))),a.push(String.fromCharCode(e)),64!==o&&a.push(String.fromCharCode(n)),64!==s&&a.push(String.fromCharCode(i));return a=a.join("")},t.encode=function(t){if(t=t.replace(/\r\n/g,"\n"),!this.nativeBase64){for(var e,n,i,r,o,s,a,c=[],h=0;h>2,o=(3&e)<<4|(n=t.charCodeAt(h++))>>4,s=(15&n)<<2|(i=t.charCodeAt(h++))>>6,a=63&i,isNaN(n)?s=a=64:isNaN(i)&&(a=64),c.push(this._keyStr.charAt(r)),c.push(this._keyStr.charAt(o)),c.push(this._keyStr.charAt(s)),c.push(this._keyStr.charAt(a));return c=c.join("")}window.btoa(t)},t.decodeBase64AsArray=function(e,n){n=n||1;var i,r,o,s=t.decode(e),a=new Uint32Array(s.length/n);for(i=0,o=s.length/n;i=0;--r)a[i]+=s.charCodeAt(i*n+r)<<(r<<3);return a},t.decompress=function(t,e,n){throw new Error("GZIP/ZLIB compressed TMX Tile Map not supported!")},t.decodeCSV=function(t){for(var e=t.replace("\n","").trim().split(","),n=[],i=0;i(e=Math.floor(e))?t++:e++,this.randrange(t,e)},t.randnum=function(t,e){return this.random()*(e-t)+t},t.shuffle=function(t){return t.sort(this._randomCompare),t},t.choice=function(t){if(!t.hasOwnProperty("length"))throw new Error("无法对此对象执行此操作");var e=Math.floor(this.random()*t.length);return t instanceof String?String(t).charAt(e):t[e]},t.sample=function(t,e){var n=t.length;if(e<=0||n=0;)s=Math.floor(this.random()*n);i.push(t[s]),r.push(s)}return i},t.random=function(){return Math.random()},t.boolean=function(t){return void 0===t&&(t=.5),this.random().5?1:-1},t}();!function(t){var e=function(){function e(){}return e.getSide=function(e,n){switch(n){case t.Edge.top:return e.top;case t.Edge.bottom:return e.bottom;case t.Edge.left:return e.left;case t.Edge.right:return e.right}},e.union=function(e,n){var i=new t.Rectangle(n.x,n.y,0,0),r=new t.Rectangle;return r.x=Math.min(e.x,i.x),r.y=Math.min(e.y,i.y),r.width=Math.max(e.right,i.right)-r.x,r.height=Math.max(e.bottom,i.bottom)-r.y,r},e.getHalfRect=function(e,n){switch(n){case t.Edge.top:return new t.Rectangle(e.x,e.y,e.width,e.height/2);case t.Edge.bottom:return new t.Rectangle(e.x,e.y+e.height/2,e.width,e.height/2);case t.Edge.left:return new t.Rectangle(e.x,e.y,e.width/2,e.height);case t.Edge.right:return new t.Rectangle(e.x+e.width/2,e.y,e.width/2,e.height)}},e.getRectEdgePortion=function(e,n,i){switch(void 0===i&&(i=1),n){case t.Edge.top:return new t.Rectangle(e.x,e.y,e.width,i);case t.Edge.bottom:return new t.Rectangle(e.x,e.y+e.height-i,e.width,i);case t.Edge.left:return new t.Rectangle(e.x,e.y,i,e.height);case t.Edge.right:return new t.Rectangle(e.x+e.width-i,e.y,i,e.height)}},e.expandSide=function(e,n,i){switch(i=Math.abs(i),n){case t.Edge.top:e.y-=i,e.height+=i;break;case t.Edge.bottom:e.height+=i;break;case t.Edge.left:e.x-=i,e.width+=i;break;case t.Edge.right:e.width+=i}},e.contract=function(t,e,n){t.x+=e,t.y+=n,t.width-=2*e,t.height-=2*n},e.boundsFromPolygonVector=function(e){for(var n=Number.POSITIVE_INFINITY,i=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY,o=Number.NEGATIVE_INFINITY,s=0;sr&&(r=a.x),a.yo&&(o=a.y)}return this.fromMinMaxVector(new t.Vector2(n,i),new t.Vector2(r,o))},e.fromMinMaxVector=function(e,n){return new t.Rectangle(e.x,e.y,n.x-e.x,n.y-e.y)},e.getSweptBroadphaseBounds=function(e,n,i){var r=t.Rectangle.empty;return r.x=n>0?e.x:e.x+n,r.y=i>0?e.y:e.y+i,r.width=n>0?n+e.width:e.width-n,r.height=i>0?i+e.height:e.height-i,r},e.prototype.collisionCheck=function(t,e,n,i){n.value=i.value=0;var r=e.x-(t.x+t.width),o=e.x+e.width-t.x,s=e.y-(t.y+t.height),a=e.y+e.height-t.y;return!(r>0||o<0||s>0||a<0)&&(n.value=Math.abs(r)=l||Math.abs(u)>=p)return t.Vector2.zero;var f=h>0?l-h:-l-h,d=u>0?p-u:-p-u;return new t.Vector2(f,d)},e}();t.RectangleExt=e}(es||(es={})),function(t){var e=function(){function t(){}return t.getType=function(t){return t.__proto__.constructor},t}();t.TypeUtils=e}(es||(es={})),function(t){var e=function(){function e(){}return e.isTriangleCCW=function(e,n,i){return this.cross(t.Vector2.subtract(n,e),t.Vector2.subtract(i,n))<0},e.halfVector=function(){return new t.Vector2(.5,.5)},e.cross=function(t,e){return t.y*e.x-t.x*e.y},e.perpendicular=function(e,n){return new t.Vector2(-1*(n.y-e.y),n.x-e.x)},e.angle=function(e,n){return this.normalize(e),this.normalize(n),Math.acos(t.MathHelper.clamp(t.Vector2.dot(e,n),-1,1))*t.MathHelper.Rad2Deg},e.getRayIntersection=function(e,n,i,r,o){void 0===o&&(o=new t.Vector2);var s=n.y-e.y,a=n.x-e.x,c=r.y-i.y,h=r.x-i.x;if(s*h==c*a)return o.x=Number.NaN,o.y=Number.NaN,!1;var u=((i.y-e.y)*a*h+s*h*e.x-c*a*i.x)/(s*h-c*a),l=e.y+s/a*(u-e.x);return o.x=u,o.y=l,!0},e.normalize=function(e){var n=Math.sqrt(e.x*e.x+e.y*e.y);n>t.MathHelper.Epsilon?e.divide(new t.Vector2(n)):e.x=e.y=0},e.transformA=function(t,e,n,i,r,o){for(var s=0;so?e?-1:1:r0},e.prototype.average=function(t){return this.sum(t)/this.count(t)},e.prototype.cast=function(){return new e(this._elements)},e.prototype.clear=function(){this._elements.length=0},e.prototype.concat=function(t){return new e(this._elements.concat(t.toArray()))},e.prototype.contains=function(t){return this.any(function(e){return e===t})},e.prototype.count=function(t){return t?this.where(t).count():this._elements.length},e.prototype.defaultIfEmpty=function(t){return this.count()?this:new e([t])},e.prototype.distinctBy=function(t){var n=this.groupBy(t);return Object.keys(n).reduce(function(t,e){return t.add(n[e][0]),t},new e)},e.prototype.elementAt=function(t){if(t=0)return this._elements[t];throw new Error("ArgumentOutOfRangeException: index is less than 0 or greater than or equal to the number of elements in source.")},e.prototype.elementAtOrDefault=function(t){return t=0?this._elements[t]:void 0},e.prototype.except=function(t){return this.where(function(e){return!t.contains(e)})},e.prototype.first=function(t){if(this.count())return t?this.where(t).first():this._elements[0];throw new Error("InvalidOperationException: The source sequence is empty.")},e.prototype.firstOrDefault=function(t){return this.count(t)?this.first(t):void 0},e.prototype.forEach=function(t){return this._elements.forEach(t)},e.prototype.groupBy=function(t,e){void 0===e&&(e=function(t){return t});return this.aggregate(function(n,i){var r=t(i),o=n[r],s=e(i);return o?o.push(s):n[r]=[s],n},{})},e.prototype.groupJoin=function(t,e,n,i){return this.select(function(r){return i(r,t.where(function(t){return e(r)===n(t)}))})},e.prototype.indexOf=function(t){return this._elements.indexOf(t)},e.prototype.insert=function(t,e){if(t<0||t>this._elements.length)throw new Error("Index is out of range.");this._elements.splice(t,0,e)},e.prototype.intersect=function(t){return this.where(function(e){return t.contains(e)})},e.prototype.join=function(t,e,n,i){return this.selectMany(function(r){return t.where(function(t){return n(t)===e(r)}).select(function(t){return i(r,t)})})},e.prototype.last=function(t){if(this.count())return t?this.where(t).last():this._elements[this.count()-1];throw Error("InvalidOperationException: The source sequence is empty.")},e.prototype.lastOrDefault=function(t){return this.count(t)?this.last(t):void 0},e.prototype.max=function(t){return Math.max.apply(Math,__spread(this._elements.map(t||function(t){return t})))},e.prototype.min=function(t){return Math.min.apply(Math,__spread(this._elements.map(t||function(t){return t})))},e.prototype.ofType=function(t){var e;switch(t){case Number:e="number";break;case String:e="string";break;case Boolean:e=typeof!0;break;case Function:e="function";break;default:e=null}return null===e?this.where(function(e){return e instanceof t}).cast():this.where(function(t){return typeof t===e}).cast()},e.prototype.orderBy=function(e,i){return void 0===i&&(i=t.keyComparer(e,!1)),new n(this._elements,i)},e.prototype.orderByDescending=function(e,i){return void 0===i&&(i=t.keyComparer(e,!0)),new n(this._elements,i)},e.prototype.thenBy=function(t){return this.orderBy(t)},e.prototype.thenByDescending=function(t){return this.orderByDescending(t)},e.prototype.remove=function(t){return-1!==this.indexOf(t)&&(this.removeAt(this.indexOf(t)),!0)},e.prototype.removeAll=function(e){return this.where(t.negate(e))},e.prototype.removeAt=function(t){this._elements.splice(t,1)},e.prototype.reverse=function(){return new e(this._elements.reverse())},e.prototype.select=function(t){return new e(this._elements.map(t))},e.prototype.selectMany=function(t){var n=this;return this.aggregate(function(e,i,r){return e.addRange(n.select(t).elementAt(r).toArray()),e},new e)},e.prototype.sequenceEqual=function(t){return this.all(function(e){return t.contains(e)})},e.prototype.single=function(t){if(1!==this.count(t))throw new Error("The collection does not contain exactly one element.");return this.first(t)},e.prototype.singleOrDefault=function(t){return this.count(t)?this.single(t):void 0},e.prototype.skip=function(t){return new e(this._elements.slice(Math.max(0,t)))},e.prototype.skipLast=function(t){return new e(this._elements.slice(0,-Math.max(0,t)))},e.prototype.skipWhile=function(t){var e=this;return this.skip(this.aggregate(function(n){return t(e.elementAt(n))?++n:n},0))},e.prototype.sum=function(t){return t?this.select(t).sum():this.aggregate(function(t,e){return t+ +e},0)},e.prototype.take=function(t){return new e(this._elements.slice(0,Math.max(0,t)))},e.prototype.takeLast=function(t){return new e(this._elements.slice(-Math.max(0,t)))},e.prototype.takeWhile=function(t){var e=this;return this.take(this.aggregate(function(n){return t(e.elementAt(n))?++n:n},0))},e.prototype.toArray=function(){return this._elements},e.prototype.toDictionary=function(t,n){var i=this;return this.aggregate(function(e,r,o){return e[i.select(t).elementAt(o).toString()]=n?i.select(n).elementAt(o):r,e.add({Key:i.select(t).elementAt(o),Value:n?i.select(n).elementAt(o):r}),e},new e)},e.prototype.toSet=function(){var t,e,n=new Set;try{for(var i=__values(this._elements),r=i.next();!r.done;r=i.next()){var o=r.value;n.add(o)}}catch(e){t={error:e}}finally{try{r&&!r.done&&(e=i.return)&&e.call(i)}finally{if(t)throw t.error}}return n},e.prototype.toList=function(){return this},e.prototype.toLookup=function(t,e){return this.groupBy(t,e)},e.prototype.where=function(t){return new e(this._elements.filter(t))},e.prototype.zip=function(t,e){var n=this;return t.count()e.angle?1:t.angleMath.PI&&(o-=2*Math.PI),r.p1.begin=o>0,r.p2.begin=!r.p1.begin}}catch(e){t={error:e}}finally{try{i&&!i.done&&(e=n.return)&&e.call(n)}finally{if(t)throw t.error}}this._isSpotLight&&(this._spotStartAngle=this._segments[0].p2.angle,this._spotEndAngle=this._segments[1].p2.angle)},e._cornerCache=[],e._openSegments=new t.LinkedList,e}();t.VisibilityComputer=e}(es||(es={})),function(t){var e=function(){function e(){this._timeInSeconds=0,this._repeats=!1,this._isDone=!1,this._elapsedTime=0}return e.prototype.getContext=function(){return this.context},e.prototype.reset=function(){this._elapsedTime=0},e.prototype.stop=function(){this._isDone=!0},e.prototype.tick=function(){return!this._isDone&&this._elapsedTime>this._timeInSeconds&&(this._elapsedTime-=this._timeInSeconds,this._onTime(this),this._isDone||this._repeats||(this._isDone=!0)),this._elapsedTime+=t.Time.deltaTime,this._isDone},e.prototype.initialize=function(t,e,n,i){this._timeInSeconds=t,this._repeats=e,this.context=n,this._onTime=i},e.prototype.unload=function(){this.context=null,this._onTime=null},e}();t.Timer=e}(es||(es={})),function(t){var e=function(e){function n(){var t=null!==e&&e.apply(this,arguments)||this;return t._timers=[],t}return __extends(n,e),n.prototype.update=function(){for(var t=this._timers.length-1;t>=0;t--)this._timers[t].tick()&&(this._timers[t].unload(),new linq.List(this._timers).removeAt(t))},n.prototype.schedule=function(e,n,i,r){var o=new t.Timer;return o.initialize(e,n,i,r),this._timers.push(o),o},n}(t.GlobalManager);t.TimerManager=e}(es||(es={})); \ No newline at end of file diff --git a/source/gulpfile.js b/source/gulpfile.js index c7ccc029..edfad49b 100644 --- a/source/gulpfile.js +++ b/source/gulpfile.js @@ -3,7 +3,7 @@ const gulp = require("gulp"); const minify = require('gulp-minify'); const inject = require("gulp-inject-string"); const ts = require('gulp-typescript'); -const compile = require("gulp-typescript"); +const merge = require('merge2'); const tsProject = ts.createProject('tsconfig.json'); gulp.task('buildJs', () => { @@ -23,7 +23,16 @@ gulp.task("buildDts", ["buildJs"], () => { .pipe(gulp.dest('./bin')); }); -gulp.task("build", ["buildDts"], () => { +gulp.task("copy", ["buildDts"], () => { return gulp.src('bin/**/*') - // .pipe(gulp.dest('../demo_egret/libs/framework/')) + .pipe(gulp.dest('../demo/egret_demo/libs/framework/')) +}); + +gulp.task('build', ['copy'], ()=>{ + return merge([ + gulp.src('bin/*.js') + .pipe(gulp.dest('../demo/laya_demo/bin/libs/')), + gulp.src('bin/*.ts') + .pipe(gulp.dest('../demo/laya_demo/libs/')) + ]) }); \ No newline at end of file diff --git a/source/package-lock.json b/source/package-lock.json index 9ea998f9..973d58d8 100644 --- a/source/package-lock.json +++ b/source/package-lock.json @@ -4096,6 +4096,12 @@ "readable-stream": "^2.0.1" } }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npm.taobao.org/merge2/download/merge2-1.4.1.tgz", + "integrity": "sha1-Q2iJL4hekHRVpv19xVwMnUBJkK4=", + "dev": true + }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", diff --git a/source/package.json b/source/package.json index 03d35907..6c28abf9 100644 --- a/source/package.json +++ b/source/package.json @@ -28,7 +28,8 @@ "typedoc": "^0.19.2", "typescript": "^2.2.2", "vinyl-source-stream": "^1.1.0", - "watchify": "^3.9.0" + "watchify": "^3.9.0", + "merge2": "^1.4.1" }, "publishConfig": { "registry": "https://npm.pkg.github.com/359807859@qq.com" diff --git a/source/src/ECS/Core.ts b/source/src/ECS/Core.ts index be3b7303..16b32d21 100644 --- a/source/src/ECS/Core.ts +++ b/source/src/ECS/Core.ts @@ -86,8 +86,8 @@ module es { if (this._instance._scene == null) { this._instance._scene = value; + this._instance.onSceneChanged(); this._instance._scene.begin(); - Core.Instance.onSceneChanged(); } else { this._instance._nextScene = value; } diff --git a/source/src/ECS/Transform.ts b/source/src/ECS/Transform.ts index 5be244d4..78e20bac 100644 --- a/source/src/ECS/Transform.ts +++ b/source/src/ECS/Transform.ts @@ -398,7 +398,7 @@ module es { * 对精灵坐标进行四舍五入 */ public roundPosition() { - this.position = this._position.round(); + this.position = Vector2Ext.round(this._position); } public updateTransform() { diff --git a/source/src/Physics/Shapes/ShapeCollisions/ShapeCollisions.ts b/source/src/Physics/Shapes/ShapeCollisions/ShapeCollisions.ts index 43ed74eb..8fcaa6ae 100644 --- a/source/src/Physics/Shapes/ShapeCollisions/ShapeCollisions.ts +++ b/source/src/Physics/Shapes/ShapeCollisions/ShapeCollisions.ts @@ -116,7 +116,7 @@ module es { * @param polygon * @param result */ - public static circleToPolygon(circle: Circle, polygon: Polygon, result: CollisionResult): boolean { + public static circleToPolygon(circle: Circle, polygon: Polygon, result: CollisionResult = new CollisionResult()): boolean { // 圆圈在多边形中的位置坐标 let poly2Circle = Vector2.subtract(circle.position, polygon.position); @@ -141,7 +141,7 @@ module es { mtv = new Vector2(result.normal.x * circle.radius, result.normal.y * circle.radius); } else { let distance = Math.sqrt(distanceSquared.value); - mtv = new Vector2(-poly2Circle.x + closestPoint.x, -poly2Circle.y + closestPoint.y) + mtv = Vector2.subtract(new Vector2(-1), Vector2.subtract(poly2Circle, closestPoint)) .multiply(new Vector2((circle.radius - distance) / distance)); } } @@ -153,19 +153,19 @@ module es { } /** - * 适用于圆心在方框内以及只与方框外圆心重叠的圆。 + * 适用于中心在框内的圆,也适用于与框外中心重合的圆。 * @param circle * @param box * @param result */ - public static circleToBox(circle: Circle, box: Box, result: CollisionResult): boolean { + public static circleToBox(circle: Circle, box: Box, result: CollisionResult = new CollisionResult()): boolean { let closestPointOnBounds = box.bounds.getClosestPointOnRectangleBorderToPoint(circle.position, result.normal); - // 处理那些中心在盒子里的圆,因为比较好操作, + // 先处理中心在盒子里的圆,如果我们是包含的, 它的成本更低, if (box.containsPoint(circle.position)) { - result.point = closestPointOnBounds; + result.point = closestPointOnBounds.clone(); - // 计算mtv。找到安全的,没有碰撞的位置,然后从那里得到mtv + // 计算MTV。找出安全的、非碰撞的位置,并从中得到MTV let safePlace = Vector2.add(closestPointOnBounds, Vector2.multiply(result.normal, new Vector2(circle.radius))); result.minimumTranslationVector = Vector2.subtract(circle.position, safePlace); @@ -173,7 +173,8 @@ module es { } let sqrDistance = Vector2.distanceSquared(closestPointOnBounds, circle.position); - // 看盒子上的点与圆的距离是否小于半径 + + // 看框上的点距圆的半径是否小于圆的半径 if (sqrDistance == 0) { result.minimumTranslationVector = Vector2.multiply(result.normal, new Vector2(circle.radius)); } else if (sqrDistance <= circle.radius * circle.radius) { @@ -236,7 +237,7 @@ module es { let t = Vector2.dot(w, v) / Vector2.dot(v, v); t = MathHelper.clamp(t, 0, 1); - return Vector2.add(lineA, Vector2.multiply(v, new Vector2(t, t))); + return Vector2.add(lineA, Vector2.multiply(v, new Vector2(t))); } /** @@ -265,7 +266,7 @@ module es { * @param second * @param result */ - public static circleToCircle(first: Circle, second: Circle, result: CollisionResult): boolean { + public static circleToCircle(first: Circle, second: Circle, result: CollisionResult = new CollisionResult()): boolean { let distanceSquared = Vector2.distanceSquared(first.position, second.position); let sumOfRadii = first.radius + second.radius; let collided = distanceSquared < sumOfRadii * sumOfRadii; @@ -275,6 +276,11 @@ module es { result.minimumTranslationVector = Vector2.multiply(new Vector2(-depth), result.normal); result.point = Vector2.add(second.position, Vector2.multiply(result.normal, new Vector2(second.radius))); + // 这可以得到实际的碰撞点,可能有用也可能没用,所以我们暂时把它留在这里 + // let collisionPointX = ((first.position.x * second.radius) + (second.position.x * first.radius)) / sumOfRadii; + // let collisionPointY = ((first.position.y * second.radius) + (second.position.y * first.radius)) / sumOfRadii; + // result.point = new Vector2(collisionPointX, collisionPointY); + return true; } @@ -315,7 +321,7 @@ module es { return new Rectangle(topLeft.x, topLeft.y, fullSize.x, fullSize.y) } - public static lineToPoly(start: Vector2, end: Vector2, polygon: Polygon, hit: RaycastHit): boolean { + public static lineToPoly(start: Vector2, end: Vector2, polygon: Polygon, hit: RaycastHit = new RaycastHit()): boolean { let normal = Vector2.zero; let intersectionPoint = Vector2.zero; let fraction = Number.MAX_VALUE; diff --git a/source/src/ECS/Utils/FastList.ts b/source/src/Utils/Collections/FastList.ts similarity index 100% rename from source/src/ECS/Utils/FastList.ts rename to source/src/Utils/Collections/FastList.ts diff --git a/source/src/ECS/Utils/FastDirectory.ts b/source/src/Utils/Collections/FasterDictionary.ts similarity index 100% rename from source/src/ECS/Utils/FastDirectory.ts rename to source/src/Utils/Collections/FasterDictionary.ts diff --git a/source/src/Utils/LinkList.ts b/source/src/Utils/Collections/LinkList.ts similarity index 100% rename from source/src/Utils/LinkList.ts rename to source/src/Utils/Collections/LinkList.ts diff --git a/source/src/Utils/ListPool.ts b/source/src/Utils/Collections/ListPool.ts similarity index 100% rename from source/src/Utils/ListPool.ts rename to source/src/Utils/Collections/ListPool.ts diff --git a/source/src/Utils/Pair.ts b/source/src/Utils/Collections/Pair.ts similarity index 100% rename from source/src/Utils/Pair.ts rename to source/src/Utils/Collections/Pair.ts diff --git a/source/src/Utils/Pool.ts b/source/src/Utils/Collections/Pool.ts similarity index 100% rename from source/src/Utils/Pool.ts rename to source/src/Utils/Collections/Pool.ts diff --git a/source/src/Utils/Set.ts b/source/src/Utils/Collections/Set.ts similarity index 100% rename from source/src/Utils/Set.ts rename to source/src/Utils/Collections/Set.ts diff --git a/source/src/Utils/ArrayUtils.ts b/source/src/Utils/Extensions/ArrayUtils.ts similarity index 96% rename from source/src/Utils/ArrayUtils.ts rename to source/src/Utils/Extensions/ArrayUtils.ts index 15c7a3d2..a72f2652 100644 --- a/source/src/Utils/ArrayUtils.ts +++ b/source/src/Utils/Extensions/ArrayUtils.ts @@ -1,297 +1,297 @@ -class ArrayUtils { - /** - * 执行冒泡排序 - * @param ary - */ - public static bubbleSort(ary: number[]): void { - let isExchange: Boolean = false; - for (let i: number = 0; i < ary.length; i++) { - isExchange = false; - for (let j: number = ary.length - 1; j > i; j--) { - if (ary[j] < ary[j - 1]) { - let temp: number = ary[j]; - ary[j] = ary[j - 1]; - ary[j - 1] = temp; - isExchange = true; - } - } - if (!isExchange) - break; - } - } - - /** - * 执行插入排序 - * @param ary - */ - public static insertionSort(ary: number[]): void { - let len: number = ary.length; - for (let i: number = 1; i < len; i++) { - let val: number = ary[i]; - for (var j: number = i; j > 0 && ary[j - 1] > val; j--) { - ary[j] = ary[j - 1]; - } - ary[j] = val; - } - } - - /** - * 执行二分搜索 - * @param ary 搜索的数组(必须排序过) - * @param value 需要搜索的值 - * @returns 返回匹配结果的数组索引 - */ - public static binarySearch(ary: number[], value: number): number { - let startIndex: number = 0; - let endIndex: number = ary.length; - let sub: number = (startIndex + endIndex) >> 1; - while (startIndex < endIndex) { - if (value <= ary[sub]) endIndex = sub; - else if (value >= ary[sub]) startIndex = sub + 1; - sub = (startIndex + endIndex) >> 1; - } - if (ary[startIndex] == value) return startIndex; - return -1; - } - - - /** - * 返回匹配项的索引 - * @param ary - * @param num - */ - public static findElementIndex(ary: any[], num: any): any { - let len: number = ary.length; - for (let i: number = 0; i < len; ++i) { - if (ary[i] == num) - return i; - } - return null; - } - - /** - * 返回数组中最大值的索引 - * @param ary - */ - public static getMaxElementIndex(ary: number[]): number { - let matchIndex: number = 0; - let len: number = ary.length; - for (let j: number = 1; j < len; j++) { - if (ary[j] > ary[matchIndex]) - matchIndex = j; - } - return matchIndex; - } - - /** - * 返回数组中最小值的索引 - * @param ary - */ - public static getMinElementIndex(ary: number[]): number { - let matchIndex: number = 0; - let len: number = ary.length; - for (let j: number = 1; j < len; j++) { - if (ary[j] < ary[matchIndex]) - matchIndex = j; - } - return matchIndex; - } - - /** - * 返回一个"唯一性"数组 - * @param ary 需要唯一性的数组 - * @returns 唯一性的数组 - * - * @tutorial - * 比如: [1, 2, 2, 3, 4] - * 返回: [1, 2, 3, 4] - */ - public static getUniqueAry(ary: number[]): number[] { - let uAry: number[] = []; - let newAry: number[] = []; - let count = ary.length; - for (let i: number = 0; i < count; ++i) { - let value: number = ary[i]; - if (uAry.indexOf(value) == -1) uAry.push(value); - } - - count = uAry.length; - for (let i: number = count - 1; i >= 0; --i) { - newAry.unshift(uAry[i]); - } - return newAry; - } - - - /** - * 返回2个数组中不同的部分 - * 比如数组A = [1, 2, 3, 4, 6] - * 数组B = [0, 2, 1, 3, 4] - * 返回[6, 0] - * @param aryA - * @param aryB - * @return - */ - public static getDifferAry(aryA: number[], aryB: number[]): number[] { - aryA = this.getUniqueAry(aryA); - aryB = this.getUniqueAry(aryB); - let ary: number[] = aryA.concat(aryB); - let uObj: Object = {}; - let newAry: number[] = []; - let count: number = ary.length; - for (let j: number = 0; j < count; ++j) { - if (!uObj[ary[j]]) { - uObj[ary[j]] = {}; - uObj[ary[j]].count = 0; - uObj[ary[j]].key = ary[j]; - uObj[ary[j]].count++; - } else { - if (uObj[ary[j]] instanceof Object) { - uObj[ary[j]].count++; - } - } - } - for (let i in uObj) { - if (uObj[i].count != 2) { - newAry.unshift(uObj[i].key); - } - } - return newAry; - } - - /** - * 交换数组元素 - * @param array 目标数组 - * @param index1 交换后的索引 - * @param index2 交换前的索引 - */ - public static swap(array: any[], index1: number, index2: number): void { - let temp: any = array[index1]; - array[index1] = array[index2]; - array[index2] = temp; - } - - - /** - * 清除列表 - * @param ary - */ - public static clearList(ary: any[]): void { - if (!ary) return; - let length: number = ary.length; - for (let i: number = length - 1; i >= 0; i -= 1) { - ary.splice(i, 1); - } - } - - /** - * 克隆一个数组 - * @param ary 需要克隆的数组 - * @return 克隆的数组 - */ - public static cloneList(ary: any[]): any[] { - if (!ary) return null; - return ary.slice(0, ary.length); - } - - /** - * 判断2个数组是否相同 - * @param ary1 数组1 - * @param ary2 数组2 - */ - public static equals(ary1: number[], ary2: number[]): Boolean { - if (ary1 == ary2) return true; - let length: number = ary1.length; - if (length != ary2.length) return false; - while (length--) { - if (ary1[length] != ary2[length]) - return false; - } - return true; - } - - /** - * 根据索引插入元素,索引和索引后的元素都向后移动一位 - * @param ary - * @param index 插入索引 - * @param value 插入的元素 - * @returns 插入的元素 未插入则返回空 - */ - public static insert(ary: any[], index: number, value: any): any { - if (!ary) return null; - let length: number = ary.length; - if (index > length) index = length; - if (index < 0) index = 0; - if (index == length) ary.push(value); //插入最后 - else if (index == 0) ary.unshift(value); //插入头 - else { - for (let i: number = length - 1; i >= index; i -= 1) { - ary[i + 1] = ary[i]; - } - ary[index] = value; - } - return value; - } - - /** - * 打乱数组 Fisher–Yates shuffle - * @param list - */ - public static shuffle(list: T[]) { - let n = list.length; - while (n > 1) { - n--; - let k = RandomUtils.randint(0, n + 1); - let value: T = list[k]; - list[k] = list[n]; - list[n] = value; - } - } - - /** - * 如果项目已经在列表中,返回false,如果成功添加,返回true - * @param list - * @param item - */ - public static addIfNotPresent(list: T[], item: T) { - if (new linq.List(list).contains(item)) - return false; - - list.push(item); - return true; - } - - /** - * 返回列表中的最后一项。列表中至少应该有一个项目 - * @param list - */ - public static lastItem(list: T[]) { - return list[list.length - 1]; - } - - /** - * 从列表中随机获取一个项目。不清空检查列表! - * @param list - */ - public static randomItem(list: T[]) { - return list[RandomUtils.randint(0, list.length - 1)]; - } - - /** - * 从列表中随机获取物品。不清空检查列表,也不验证列表数是否大于项目数。返回的List可以通过ListPool.free放回池中 - * @param list - * @param itemCount 从列表中返回的随机项目的数量 - */ - public static randomItems(list: T[], itemCount: number){ - let set = new Set(); - while (set.size != itemCount) { - let item = this.randomItem(list); - if (!set.has(item)) - set.add(item); - } - - let items = es.ListPool.obtain(); - set.forEach(value => items.push(value)); - return items; - } +class ArrayUtils { + /** + * 执行冒泡排序 + * @param ary + */ + public static bubbleSort(ary: number[]): void { + let isExchange: Boolean = false; + for (let i: number = 0; i < ary.length; i++) { + isExchange = false; + for (let j: number = ary.length - 1; j > i; j--) { + if (ary[j] < ary[j - 1]) { + let temp: number = ary[j]; + ary[j] = ary[j - 1]; + ary[j - 1] = temp; + isExchange = true; + } + } + if (!isExchange) + break; + } + } + + /** + * 执行插入排序 + * @param ary + */ + public static insertionSort(ary: number[]): void { + let len: number = ary.length; + for (let i: number = 1; i < len; i++) { + let val: number = ary[i]; + for (var j: number = i; j > 0 && ary[j - 1] > val; j--) { + ary[j] = ary[j - 1]; + } + ary[j] = val; + } + } + + /** + * 执行二分搜索 + * @param ary 搜索的数组(必须排序过) + * @param value 需要搜索的值 + * @returns 返回匹配结果的数组索引 + */ + public static binarySearch(ary: number[], value: number): number { + let startIndex: number = 0; + let endIndex: number = ary.length; + let sub: number = (startIndex + endIndex) >> 1; + while (startIndex < endIndex) { + if (value <= ary[sub]) endIndex = sub; + else if (value >= ary[sub]) startIndex = sub + 1; + sub = (startIndex + endIndex) >> 1; + } + if (ary[startIndex] == value) return startIndex; + return -1; + } + + + /** + * 返回匹配项的索引 + * @param ary + * @param num + */ + public static findElementIndex(ary: any[], num: any): any { + let len: number = ary.length; + for (let i: number = 0; i < len; ++i) { + if (ary[i] == num) + return i; + } + return null; + } + + /** + * 返回数组中最大值的索引 + * @param ary + */ + public static getMaxElementIndex(ary: number[]): number { + let matchIndex: number = 0; + let len: number = ary.length; + for (let j: number = 1; j < len; j++) { + if (ary[j] > ary[matchIndex]) + matchIndex = j; + } + return matchIndex; + } + + /** + * 返回数组中最小值的索引 + * @param ary + */ + public static getMinElementIndex(ary: number[]): number { + let matchIndex: number = 0; + let len: number = ary.length; + for (let j: number = 1; j < len; j++) { + if (ary[j] < ary[matchIndex]) + matchIndex = j; + } + return matchIndex; + } + + /** + * 返回一个"唯一性"数组 + * @param ary 需要唯一性的数组 + * @returns 唯一性的数组 + * + * @tutorial + * 比如: [1, 2, 2, 3, 4] + * 返回: [1, 2, 3, 4] + */ + public static getUniqueAry(ary: number[]): number[] { + let uAry: number[] = []; + let newAry: number[] = []; + let count = ary.length; + for (let i: number = 0; i < count; ++i) { + let value: number = ary[i]; + if (uAry.indexOf(value) == -1) uAry.push(value); + } + + count = uAry.length; + for (let i: number = count - 1; i >= 0; --i) { + newAry.unshift(uAry[i]); + } + return newAry; + } + + + /** + * 返回2个数组中不同的部分 + * 比如数组A = [1, 2, 3, 4, 6] + * 数组B = [0, 2, 1, 3, 4] + * 返回[6, 0] + * @param aryA + * @param aryB + * @return + */ + public static getDifferAry(aryA: number[], aryB: number[]): number[] { + aryA = this.getUniqueAry(aryA); + aryB = this.getUniqueAry(aryB); + let ary: number[] = aryA.concat(aryB); + let uObj: Object = {}; + let newAry: number[] = []; + let count: number = ary.length; + for (let j: number = 0; j < count; ++j) { + if (!uObj[ary[j]]) { + uObj[ary[j]] = {}; + uObj[ary[j]].count = 0; + uObj[ary[j]].key = ary[j]; + uObj[ary[j]].count++; + } else { + if (uObj[ary[j]] instanceof Object) { + uObj[ary[j]].count++; + } + } + } + for (let i in uObj) { + if (uObj[i].count != 2) { + newAry.unshift(uObj[i].key); + } + } + return newAry; + } + + /** + * 交换数组元素 + * @param array 目标数组 + * @param index1 交换后的索引 + * @param index2 交换前的索引 + */ + public static swap(array: any[], index1: number, index2: number): void { + let temp: any = array[index1]; + array[index1] = array[index2]; + array[index2] = temp; + } + + + /** + * 清除列表 + * @param ary + */ + public static clearList(ary: any[]): void { + if (!ary) return; + let length: number = ary.length; + for (let i: number = length - 1; i >= 0; i -= 1) { + ary.splice(i, 1); + } + } + + /** + * 克隆一个数组 + * @param ary 需要克隆的数组 + * @return 克隆的数组 + */ + public static cloneList(ary: any[]): any[] { + if (!ary) return null; + return ary.slice(0, ary.length); + } + + /** + * 判断2个数组是否相同 + * @param ary1 数组1 + * @param ary2 数组2 + */ + public static equals(ary1: number[], ary2: number[]): Boolean { + if (ary1 == ary2) return true; + let length: number = ary1.length; + if (length != ary2.length) return false; + while (length--) { + if (ary1[length] != ary2[length]) + return false; + } + return true; + } + + /** + * 根据索引插入元素,索引和索引后的元素都向后移动一位 + * @param ary + * @param index 插入索引 + * @param value 插入的元素 + * @returns 插入的元素 未插入则返回空 + */ + public static insert(ary: any[], index: number, value: any): any { + if (!ary) return null; + let length: number = ary.length; + if (index > length) index = length; + if (index < 0) index = 0; + if (index == length) ary.push(value); //插入最后 + else if (index == 0) ary.unshift(value); //插入头 + else { + for (let i: number = length - 1; i >= index; i -= 1) { + ary[i + 1] = ary[i]; + } + ary[index] = value; + } + return value; + } + + /** + * 打乱数组 Fisher–Yates shuffle + * @param list + */ + public static shuffle(list: T[]) { + let n = list.length; + while (n > 1) { + n--; + let k = RandomUtils.randint(0, n + 1); + let value: T = list[k]; + list[k] = list[n]; + list[n] = value; + } + } + + /** + * 如果项目已经在列表中,返回false,如果成功添加,返回true + * @param list + * @param item + */ + public static addIfNotPresent(list: T[], item: T) { + if (new linq.List(list).contains(item)) + return false; + + list.push(item); + return true; + } + + /** + * 返回列表中的最后一项。列表中至少应该有一个项目 + * @param list + */ + public static lastItem(list: T[]) { + return list[list.length - 1]; + } + + /** + * 从列表中随机获取一个项目。不清空检查列表! + * @param list + */ + public static randomItem(list: T[]) { + return list[RandomUtils.randint(0, list.length - 1)]; + } + + /** + * 从列表中随机获取物品。不清空检查列表,也不验证列表数是否大于项目数。返回的List可以通过ListPool.free放回池中 + * @param list + * @param itemCount 从列表中返回的随机项目的数量 + */ + public static randomItems(list: T[], itemCount: number){ + let set = new Set(); + while (set.size != itemCount) { + let item = this.randomItem(list); + if (!set.has(item)) + set.add(item); + } + + let items = es.ListPool.obtain(); + set.forEach(value => items.push(value)); + return items; + } } \ No newline at end of file diff --git a/source/src/Utils/Base64Utils.ts b/source/src/Utils/Extensions/Base64Utils.ts similarity index 97% rename from source/src/Utils/Base64Utils.ts rename to source/src/Utils/Extensions/Base64Utils.ts index 1259a9c2..412be9de 100644 --- a/source/src/Utils/Base64Utils.ts +++ b/source/src/Utils/Extensions/Base64Utils.ts @@ -1,134 +1,134 @@ -module es{ - export class Base64Utils { - private static _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; - - /** - * 判断是否原生支持Base64位解析 - */ - static get nativeBase64() { - return (typeof (window.atob) === "function"); - } - - - /** - * 解码 - * @param input - */ - static decode(input:string): string { - input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); - - if (this.nativeBase64) { - return window.atob(input); - } else { - var output: any = [], chr1: number, chr2: number, chr3: number, enc1: number, enc2: number, enc3: number, enc4: number, i: number = 0; - - while (i < input.length) { - enc1 = this._keyStr.indexOf(input.charAt(i++)); - enc2 = this._keyStr.indexOf(input.charAt(i++)); - enc3 = this._keyStr.indexOf(input.charAt(i++)); - enc4 = this._keyStr.indexOf(input.charAt(i++)); - - chr1 = (enc1 << 2) | (enc2 >> 4); - chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); - chr3 = ((enc3 & 3) << 6) | enc4; - - output.push(String.fromCharCode(chr1)); - - if (enc3 !== 64) { - output.push(String.fromCharCode(chr2)); - } - if (enc4 !== 64) { - output.push(String.fromCharCode(chr3)); - } - } - - output = output.join(""); - return output; - } - } - - - /** - * 编码 - * @param input - */ - static encode(input:string): string { - input = input.replace(/\r\n/g, "\n"); - if (this.nativeBase64) { - window.btoa(input); - } else { - var output: any = [], chr1: number, chr2: number, chr3: number, enc1: number, enc2: number, enc3: number, enc4: number, i: number = 0; - while (i < input.length) { - chr1 = input.charCodeAt(i++); - chr2 = input.charCodeAt(i++); - chr3 = input.charCodeAt(i++); - - enc1 = chr1 >> 2; - enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); - enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); - enc4 = chr3 & 63; - - if (isNaN(chr2)) { - enc3 = enc4 = 64; - } else if (isNaN(chr3)) { - enc4 = 64; - } - - output.push(this._keyStr.charAt(enc1)); - output.push(this._keyStr.charAt(enc2)); - output.push(this._keyStr.charAt(enc3)); - output.push(this._keyStr.charAt(enc4)); - } - - output = output.join(""); - return output; - } - } - - - /** - * 解析Base64格式数据 - * @param input - * @param bytes - */ - static decodeBase64AsArray(input: string, bytes: number): Uint32Array { - bytes = bytes || 1; - - var dec = Base64Utils.decode(input), i, j, len; - var ar: Uint32Array = new Uint32Array(dec.length / bytes); - - for (i = 0, len = dec.length / bytes; i < len; i++) { - ar[i] = 0; - for (j = bytes - 1; j >= 0; --j) { - ar[i] += dec.charCodeAt((i * bytes) + j) << (j << 3); - } - } - return ar; - } - - /** - * 暂时不支持 - * @param data - * @param decoded - * @param compression - * @private - */ - static decompress(data: string, decoded: any, compression: string): any { - throw new Error("GZIP/ZLIB compressed TMX Tile Map not supported!"); - } - - /** - * 解析csv数据 - * @param input - */ - static decodeCSV(input: string): Array { - var entries: Array = input.replace("\n", "").trim().split(","); - - var result:Array = []; - for (var i:number = 0; i < entries.length; i++) { - result.push(+entries[i]); - } - return result; - } - } -} +module es{ + export class Base64Utils { + private static _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + + /** + * 判断是否原生支持Base64位解析 + */ + static get nativeBase64() { + return (typeof (window.atob) === "function"); + } + + + /** + * 解码 + * @param input + */ + static decode(input:string): string { + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + + if (this.nativeBase64) { + return window.atob(input); + } else { + var output: any = [], chr1: number, chr2: number, chr3: number, enc1: number, enc2: number, enc3: number, enc4: number, i: number = 0; + + while (i < input.length) { + enc1 = this._keyStr.indexOf(input.charAt(i++)); + enc2 = this._keyStr.indexOf(input.charAt(i++)); + enc3 = this._keyStr.indexOf(input.charAt(i++)); + enc4 = this._keyStr.indexOf(input.charAt(i++)); + + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + + output.push(String.fromCharCode(chr1)); + + if (enc3 !== 64) { + output.push(String.fromCharCode(chr2)); + } + if (enc4 !== 64) { + output.push(String.fromCharCode(chr3)); + } + } + + output = output.join(""); + return output; + } + } + + + /** + * 编码 + * @param input + */ + static encode(input:string): string { + input = input.replace(/\r\n/g, "\n"); + if (this.nativeBase64) { + window.btoa(input); + } else { + var output: any = [], chr1: number, chr2: number, chr3: number, enc1: number, enc2: number, enc3: number, enc4: number, i: number = 0; + while (i < input.length) { + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } else if (isNaN(chr3)) { + enc4 = 64; + } + + output.push(this._keyStr.charAt(enc1)); + output.push(this._keyStr.charAt(enc2)); + output.push(this._keyStr.charAt(enc3)); + output.push(this._keyStr.charAt(enc4)); + } + + output = output.join(""); + return output; + } + } + + + /** + * 解析Base64格式数据 + * @param input + * @param bytes + */ + static decodeBase64AsArray(input: string, bytes: number): Uint32Array { + bytes = bytes || 1; + + var dec = Base64Utils.decode(input), i, j, len; + var ar: Uint32Array = new Uint32Array(dec.length / bytes); + + for (i = 0, len = dec.length / bytes; i < len; i++) { + ar[i] = 0; + for (j = bytes - 1; j >= 0; --j) { + ar[i] += dec.charCodeAt((i * bytes) + j) << (j << 3); + } + } + return ar; + } + + /** + * 暂时不支持 + * @param data + * @param decoded + * @param compression + * @private + */ + static decompress(data: string, decoded: any, compression: string): any { + throw new Error("GZIP/ZLIB compressed TMX Tile Map not supported!"); + } + + /** + * 解析csv数据 + * @param input + */ + static decodeCSV(input: string): Array { + var entries: Array = input.replace("\n", "").trim().split(","); + + var result:Array = []; + for (var i:number = 0; i < entries.length; i++) { + result.push(+entries[i]); + } + return result; + } + } +} diff --git a/source/src/Utils/EdgeExt.ts b/source/src/Utils/Extensions/EdgeExt.ts similarity index 100% rename from source/src/Utils/EdgeExt.ts rename to source/src/Utils/Extensions/EdgeExt.ts diff --git a/source/src/Utils/NumberExtension.ts b/source/src/Utils/Extensions/NumberExtension.ts similarity index 100% rename from source/src/Utils/NumberExtension.ts rename to source/src/Utils/Extensions/NumberExtension.ts diff --git a/source/src/Utils/RandomUtils.ts b/source/src/Utils/Extensions/RandomUtils.ts similarity index 96% rename from source/src/Utils/RandomUtils.ts rename to source/src/Utils/Extensions/RandomUtils.ts index 6aca63de..39d4116d 100644 --- a/source/src/Utils/RandomUtils.ts +++ b/source/src/Utils/Extensions/RandomUtils.ts @@ -1,133 +1,133 @@ -class RandomUtils { - /** - * 在 start 与 stop之间取一个随机整数,可以用step指定间隔, 但不包括较大的端点(start与stop较大的一个) - * 如 - * this.randrange(1, 10, 3) - * 则返回的可能是 1 或 4 或 7 , 注意 这里面不会返回10,因为是10是大端点 - * - * @param start - * @param stop - * @param step - * @return 假设 start < stop, [start, stop) 区间内的随机整数 - * - */ - public static randrange(start: number, stop: number, step: number = 1): number { - if (step == 0) - throw new Error('step 不能为 0'); - - let width: number = stop - start; - if (width == 0) - throw new Error('没有可用的范围(' + start + ',' + stop + ')'); - if (width < 0) - width = start - stop; - - let n: number = Math.floor((width + step - 1) / step); - return Math.floor(this.random() * n) * step + Math.min(start, stop); - } - - /** - * 返回a 到 b直间的随机整数,包括 a 和 b - * @param a - * @param b - * @return [a, b] 直接的随机整数 - * - */ - public static randint(a: number, b: number): number { - a = Math.floor(a); - b = Math.floor(b); - if (a > b) - a++; - else - b++; - return this.randrange(a, b); - } - - /** - * 返回 a - b之间的随机数,不包括 Math.max(a, b) - * @param a - * @param b - * @return 假设 a < b, [a, b) - */ - public static randnum(a: number, b: number): number { - return this.random() * (b - a) + a; - } - - /** - * 打乱数组 - * @param array - * @return - */ - public static shuffle(array: any[]): any[] { - array.sort(this._randomCompare); - return array; - } - - /** - * 从序列中随机取一个元素 - * @param sequence 可以是 数组、 vector,等只要是有length属性,并且可以用数字索引获取元素的对象, - * 另外,字符串也是允许的。 - * @return 序列中的某一个元素 - * - */ - public static choice(sequence: any): any { - if (!sequence.hasOwnProperty("length")) - throw new Error('无法对此对象执行此操作'); - let index: number = Math.floor(this.random() * sequence.length); - if (sequence instanceof String) - return String(sequence).charAt(index); - else - return sequence[index]; - } - - /** - * 对列表中的元素进行随机采æ ? - *
-     * this.sample([1, 2, 3, 4, 5],  3)  // Choose 3 elements
-     * [4, 1, 5]
-     * 
- * @param sequence - * @param num - * @return - * - */ - public static sample(sequence: any[], num: number): any[] { - let len: number = sequence.length; - if (num <= 0 || len < num) - throw new Error("采样数量不够"); - - let selected: any[] = []; - let indices: any[] = []; - for (let i: number = 0; i < num; i++) { - let index: number = 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() - * - */ - public static random(): number { - return Math.random(); - } - - /** - * 计算概率 - * @param chance 概率 - * @return - */ - public static boolean(chance: number = .5): boolean { - return (this.random() < chance) ? true : false; - } - - private static _randomCompare(a: Object, b: Object): number { - return (this.random() > .5) ? 1 : -1; - } +class RandomUtils { + /** + * 在 start 与 stop之间取一个随机整数,可以用step指定间隔, 但不包括较大的端点(start与stop较大的一个) + * 如 + * this.randrange(1, 10, 3) + * 则返回的可能是 1 或 4 或 7 , 注意 这里面不会返回10,因为是10是大端点 + * + * @param start + * @param stop + * @param step + * @return 假设 start < stop, [start, stop) 区间内的随机整数 + * + */ + public static randrange(start: number, stop: number, step: number = 1): number { + if (step == 0) + throw new Error('step 不能为 0'); + + let width: number = stop - start; + if (width == 0) + throw new Error('没有可用的范围(' + start + ',' + stop + ')'); + if (width < 0) + width = start - stop; + + let n: number = Math.floor((width + step - 1) / step); + return Math.floor(this.random() * n) * step + Math.min(start, stop); + } + + /** + * 返回a 到 b直间的随机整数,包括 a 和 b + * @param a + * @param b + * @return [a, b] 直接的随机整数 + * + */ + public static randint(a: number, b: number): number { + a = Math.floor(a); + b = Math.floor(b); + if (a > b) + a++; + else + b++; + return this.randrange(a, b); + } + + /** + * 返回 a - b之间的随机数,不包括 Math.max(a, b) + * @param a + * @param b + * @return 假设 a < b, [a, b) + */ + public static randnum(a: number, b: number): number { + return this.random() * (b - a) + a; + } + + /** + * 打乱数组 + * @param array + * @return + */ + public static shuffle(array: any[]): any[] { + array.sort(this._randomCompare); + return array; + } + + /** + * 从序列中随机取一个元素 + * @param sequence 可以是 数组、 vector,等只要是有length属性,并且可以用数字索引获取元素的对象, + * 另外,字符串也是允许的。 + * @return 序列中的某一个元素 + * + */ + public static choice(sequence: any): any { + if (!sequence.hasOwnProperty("length")) + throw new Error('无法对此对象执行此操作'); + let index: number = Math.floor(this.random() * sequence.length); + if (sequence instanceof String) + return String(sequence).charAt(index); + else + return sequence[index]; + } + + /** + * 对列表中的元素进行随机采æ ? + *
+     * this.sample([1, 2, 3, 4, 5],  3)  // Choose 3 elements
+     * [4, 1, 5]
+     * 
+ * @param sequence + * @param num + * @return + * + */ + public static sample(sequence: any[], num: number): any[] { + let len: number = sequence.length; + if (num <= 0 || len < num) + throw new Error("采样数量不够"); + + let selected: any[] = []; + let indices: any[] = []; + for (let i: number = 0; i < num; i++) { + let index: number = 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() + * + */ + public static random(): number { + return Math.random(); + } + + /** + * 计算概率 + * @param chance 概率 + * @return + */ + public static boolean(chance: number = .5): boolean { + return (this.random() < chance) ? true : false; + } + + private static _randomCompare(a: Object, b: Object): number { + return (this.random() > .5) ? 1 : -1; + } } \ No newline at end of file diff --git a/source/src/Utils/Extensions/RectangleExt.ts b/source/src/Utils/Extensions/RectangleExt.ts new file mode 100644 index 00000000..310de0c7 --- /dev/null +++ b/source/src/Utils/Extensions/RectangleExt.ts @@ -0,0 +1,220 @@ +module es { + export class RectangleExt { + /** + * 获取指定边的位置 + * @param rect + * @param edge + */ + public static getSide(rect: Rectangle, edge: Edge) { + switch (edge) { + case Edge.top: + return rect.top; + case Edge.bottom: + return rect.bottom; + case es.Edge.left: + return rect.left; + case Edge.right: + return rect.right; + } + } + + /** + * 计算两个矩形的并集。结果将是一个包含其他两个的矩形。 + * @param first + * @param point + */ + public static union(first: Rectangle, point: Vector2) { + let rect = new Rectangle(point.x, point.y, 0, 0); + let result = new 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, rect.bottom) - result.y; + return result; + } + + public static getHalfRect(rect: Rectangle, edge: Edge) { + switch (edge) { + case Edge.top: + return new Rectangle(rect.x, rect.y, rect.width, rect.height / 2); + case Edge.bottom: + return new Rectangle(rect.x, rect.y + rect.height / 2, rect.width, rect.height / 2); + case Edge.left: + return new Rectangle(rect.x, rect.y, rect.width / 2, rect.height); + case Edge.right: + return new Rectangle(rect.x + rect.width / 2, rect.y, rect.width / 2, rect.height); + } + } + + /** + * 获取矩形的一部分,其宽度/高度的大小位于矩形的边缘,但仍然包含在其中。 + * @param rect + * @param edge + * @param size + */ + public static getRectEdgePortion(rect: Rectangle, edge: Edge, size: number = 1) { + switch (edge) { + case es.Edge.top: + return new Rectangle(rect.x, rect.y, rect.width, size); + case Edge.bottom: + return new Rectangle(rect.x, rect.y + rect.height - size, rect.width, size); + case Edge.left: + return new Rectangle(rect.x, rect.y, size, rect.height); + case Edge.right: + return new Rectangle(rect.x + rect.width - size, rect.y, size, rect.height); + } + } + + public static expandSide(rect: Rectangle, edge: Edge, amount: number) { + amount = Math.abs(amount); + + switch (edge) { + case Edge.top: + rect.y -= amount; + rect.height += amount; + break; + case es.Edge.bottom: + rect.height += amount; + break; + case Edge.left: + rect.x -= amount; + rect.width += amount; + break; + case Edge.right: + rect.width += amount; + break; + } + } + + public static contract(rect: Rectangle, horizontalAmount, verticalAmount) { + rect.x += horizontalAmount; + rect.y += verticalAmount; + rect.width -= horizontalAmount * 2; + rect.height -= verticalAmount * 2; + } + + /** + * 给定多边形的点,计算其边界 + * @param points + */ + public static boundsFromPolygonVector(points: Vector2[]) { + // 我们需要找到最小/最大的x/y值。 + let minX = Number.POSITIVE_INFINITY; + let minY = Number.POSITIVE_INFINITY; + let maxX = Number.NEGATIVE_INFINITY; + let maxY = Number.NEGATIVE_INFINITY; + + for (let i = 0; i < points.length; i ++) { + let 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.fromMinMaxVector(new Vector2(minX, minY), new Vector2(maxX, maxY)); + } + + /** + * 创建一个给定最小/最大点(左上角,右下角)的矩形 + * @param min + * @param max + */ + public static fromMinMaxVector(min: Vector2, max: Vector2) { + return new Rectangle(min.x, min.y, max.x - min.x, max.y - min.y); + } + + /** + * 返回一个跨越当前边界和提供的delta位置的Bounds + * @param rect + * @param deltaX + * @param deltaY + */ + public static getSweptBroadphaseBounds(rect: Rectangle, deltaX: number, deltaY: number){ + let broadphasebox = Rectangle.empty; + + broadphasebox.x = deltaX > 0 ? rect.x : rect.x + deltaX; + broadphasebox.y = deltaY > 0 ? rect.y : rect.y + deltaY; + broadphasebox.width = deltaX > 0 ? deltaX + rect.width : rect.width - deltaX; + broadphasebox.height = deltaY > 0 ? deltaY + rect.height : rect.height - deltaY; + + return broadphasebox; + } + + /** + * 如果矩形发生碰撞,返回true + * moveX和moveY将返回b1为避免碰撞而必须移动的移动量 + * @param rect + * @param other + * @param moveX + * @param moveY + */ + public collisionCheck(rect: Rectangle, other: Rectangle, moveX: Ref, moveY: Ref) { + moveX.value = moveY.value = 0; + + let l = other.x - (rect.x + rect.width); + let r = (other.x + other.width) - rect.x; + let t = other.y - (rect.y + rect.height); + let b = (other.y + other.height) - rect.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。 + */ + public static getIntersectionDepth(rectA: Rectangle, rectB: Rectangle) { + // 计算半尺寸 + let halfWidthA = rectA.width / 2; + let halfHeightA = rectA.height / 2; + let halfWidthB = rectB.width / 2; + let halfHeightB = rectB.height / 2; + + // 计算中心 + let centerA = new Vector2(rectA.left + halfWidthA, rectA.top + halfHeightA); + let centerB = new Vector2(rectB.left + halfWidthB, rectB.top + halfHeightB); + + // 计算当前中心间的距离和最小非相交距离 + let distanceX = centerA.x - centerB.x; + let distanceY = centerA.y - centerB.y; + let minDistanceX = halfWidthA + halfWidthB; + let minDistanceY = halfHeightA + halfHeightB; + + // 如果我们根本不相交,则返回(0,0) + if (Math.abs(distanceX) >= minDistanceX || Math.abs(distanceY) >= minDistanceY) + return Vector2.zero; + + // 计算并返回交叉点深度 + let depthX = distanceX > 0 ? minDistanceX - distanceX : -minDistanceX - distanceX; + let depthY = distanceY > 0 ? minDistanceY - distanceY : -minDistanceY - distanceY; + + return new Vector2(depthX, depthY); + } + } +} diff --git a/source/src/Utils/TypeUtils.ts b/source/src/Utils/Extensions/TypeUtils.ts similarity index 100% rename from source/src/Utils/TypeUtils.ts rename to source/src/Utils/Extensions/TypeUtils.ts diff --git a/source/src/Utils/Vector2Ext.ts b/source/src/Utils/Extensions/Vector2Ext.ts similarity index 100% rename from source/src/Utils/Vector2Ext.ts rename to source/src/Utils/Extensions/Vector2Ext.ts diff --git a/source/src/Utils/WebGLUtils.ts b/source/src/Utils/Extensions/WebGLUtils.ts similarity index 96% rename from source/src/Utils/WebGLUtils.ts rename to source/src/Utils/Extensions/WebGLUtils.ts index be82c9a5..2a9c9f0a 100644 --- a/source/src/Utils/WebGLUtils.ts +++ b/source/src/Utils/Extensions/WebGLUtils.ts @@ -1,9 +1,9 @@ -class WebGLUtils { - /** - * 获取webgl context - */ - public static getContext() { - const canvas = document.getElementsByTagName('canvas')[0]; - return canvas.getContext('2d'); - } +class WebGLUtils { + /** + * 获取webgl context + */ + public static getContext() { + const canvas = document.getElementsByTagName('canvas')[0]; + return canvas.getContext('2d'); + } } \ No newline at end of file diff --git a/source/src/Utils/PolygonLight/VisibilityComputer.ts b/source/src/Utils/PolygonLight/VisibilityComputer.ts index fecb8a4e..dd00ae62 100644 --- a/source/src/Utils/PolygonLight/VisibilityComputer.ts +++ b/source/src/Utils/PolygonLight/VisibilityComputer.ts @@ -1,4 +1,4 @@ -/// +/// module es { /** * 类,它可以计算出一个网格,表示从给定的一组遮挡物的原点可以看到哪些区域。使用方法如下。 diff --git a/source/src/Utils/RectangleExt.ts b/source/src/Utils/RectangleExt.ts deleted file mode 100644 index 95bdd9be..00000000 --- a/source/src/Utils/RectangleExt.ts +++ /dev/null @@ -1,96 +0,0 @@ -module es { - export class RectangleExt { - /** - * 获取指定边的位置 - * @param rect - * @param edge - */ - public static getSide(rect: Rectangle, edge: Edge) { - switch (edge) { - case Edge.top: - return rect.top; - case Edge.bottom: - return rect.bottom; - case es.Edge.left: - return rect.left; - case Edge.right: - return rect.right; - } - } - - /** - * 计算两个矩形的并集。结果将是一个包含其他两个的矩形。 - * @param first - * @param point - */ - public static union(first: Rectangle, point: Vector2) { - let rect = new Rectangle(point.x, point.y, 0, 0); - let result = new 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, rect.bottom) - result.y; - return result; - } - - public static getHalfRect(rect: Rectangle, edge: Edge) { - switch (edge) { - case Edge.top: - return new Rectangle(rect.x, rect.y, rect.width, rect.height / 2); - case Edge.bottom: - return new Rectangle(rect.x, rect.y + rect.height / 2, rect.width, rect.height / 2); - case Edge.left: - return new Rectangle(rect.x, rect.y, rect.width / 2, rect.height); - case Edge.right: - return new Rectangle(rect.x + rect.width / 2, rect.y, rect.width / 2, rect.height); - } - } - - /** - * 获取矩形的一部分,其宽度/高度的大小位于矩形的边缘,但仍然包含在其中。 - * @param rect - * @param edge - * @param size - */ - public static getRectEdgePortion(rect: Rectangle, edge: Edge, size: number = 1) { - switch (edge) { - case es.Edge.top: - return new Rectangle(rect.x, rect.y, rect.width, size); - case Edge.bottom: - return new Rectangle(rect.x, rect.y + rect.height - size, rect.width, size); - case Edge.left: - return new Rectangle(rect.x, rect.y, size, rect.height); - case Edge.right: - return new Rectangle(rect.x + rect.width - size, rect.y, size, rect.height); - } - } - - public static expandSide(rect: Rectangle, edge: Edge, amount: number) { - amount = Math.abs(amount); - - switch (edge) { - case Edge.top: - rect.y -= amount; - rect.height += amount; - break; - case es.Edge.bottom: - rect.height += amount; - break; - case Edge.left: - rect.x -= amount; - rect.width += amount; - break; - case Edge.right: - rect.width += amount; - break; - } - } - - public static contract(rect: Rectangle, horizontalAmount, verticalAmount) { - rect.x += horizontalAmount; - rect.y += verticalAmount; - rect.width -= horizontalAmount * 2; - rect.height -= verticalAmount * 2; - } - } -}