新增子模块与文件迁移
This commit is contained in:
@@ -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
|
||||||
Submodule
+1
Submodule demo/egret_demo added at b478905960
Submodule
+1
Submodule demo/laya_demo added at ef025467dc
Vendored
+639
-602
File diff suppressed because it is too large
Load Diff
+1550
-1439
File diff suppressed because it is too large
Load Diff
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+12
-3
@@ -3,7 +3,7 @@ const gulp = require("gulp");
|
|||||||
const minify = require('gulp-minify');
|
const minify = require('gulp-minify');
|
||||||
const inject = require("gulp-inject-string");
|
const inject = require("gulp-inject-string");
|
||||||
const ts = require('gulp-typescript');
|
const ts = require('gulp-typescript');
|
||||||
const compile = require("gulp-typescript");
|
const merge = require('merge2');
|
||||||
const tsProject = ts.createProject('tsconfig.json');
|
const tsProject = ts.createProject('tsconfig.json');
|
||||||
|
|
||||||
gulp.task('buildJs', () => {
|
gulp.task('buildJs', () => {
|
||||||
@@ -23,7 +23,16 @@ gulp.task("buildDts", ["buildJs"], () => {
|
|||||||
.pipe(gulp.dest('./bin'));
|
.pipe(gulp.dest('./bin'));
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task("build", ["buildDts"], () => {
|
gulp.task("copy", ["buildDts"], () => {
|
||||||
return gulp.src('bin/**/*')
|
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/'))
|
||||||
|
])
|
||||||
});
|
});
|
||||||
Generated
+6
@@ -4096,6 +4096,12 @@
|
|||||||
"readable-stream": "^2.0.1"
|
"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": {
|
"micromatch": {
|
||||||
"version": "3.1.10",
|
"version": "3.1.10",
|
||||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
|
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
|
||||||
|
|||||||
+2
-1
@@ -28,7 +28,8 @@
|
|||||||
"typedoc": "^0.19.2",
|
"typedoc": "^0.19.2",
|
||||||
"typescript": "^2.2.2",
|
"typescript": "^2.2.2",
|
||||||
"vinyl-source-stream": "^1.1.0",
|
"vinyl-source-stream": "^1.1.0",
|
||||||
"watchify": "^3.9.0"
|
"watchify": "^3.9.0",
|
||||||
|
"merge2": "^1.4.1"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"registry": "https://npm.pkg.github.com/359807859@qq.com"
|
"registry": "https://npm.pkg.github.com/359807859@qq.com"
|
||||||
|
|||||||
@@ -86,8 +86,8 @@ module es {
|
|||||||
|
|
||||||
if (this._instance._scene == null) {
|
if (this._instance._scene == null) {
|
||||||
this._instance._scene = value;
|
this._instance._scene = value;
|
||||||
|
this._instance.onSceneChanged();
|
||||||
this._instance._scene.begin();
|
this._instance._scene.begin();
|
||||||
Core.Instance.onSceneChanged();
|
|
||||||
} else {
|
} else {
|
||||||
this._instance._nextScene = value;
|
this._instance._nextScene = value;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -398,7 +398,7 @@ module es {
|
|||||||
* 对精灵坐标进行四舍五入
|
* 对精灵坐标进行四舍五入
|
||||||
*/
|
*/
|
||||||
public roundPosition() {
|
public roundPosition() {
|
||||||
this.position = this._position.round();
|
this.position = Vector2Ext.round(this._position);
|
||||||
}
|
}
|
||||||
|
|
||||||
public updateTransform() {
|
public updateTransform() {
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ module es {
|
|||||||
* @param polygon
|
* @param polygon
|
||||||
* @param result
|
* @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);
|
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);
|
mtv = new Vector2(result.normal.x * circle.radius, result.normal.y * circle.radius);
|
||||||
} else {
|
} else {
|
||||||
let distance = Math.sqrt(distanceSquared.value);
|
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));
|
.multiply(new Vector2((circle.radius - distance) / distance));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,19 +153,19 @@ module es {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 适用于圆心在方框内以及只与方框外圆心重叠的圆。
|
* 适用于中心在框内的圆,也适用于与框外中心重合的圆。
|
||||||
* @param circle
|
* @param circle
|
||||||
* @param box
|
* @param box
|
||||||
* @param result
|
* @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);
|
let closestPointOnBounds = box.bounds.getClosestPointOnRectangleBorderToPoint(circle.position, result.normal);
|
||||||
|
|
||||||
// 处理那些中心在盒子里的圆,因为比较好操作,
|
// 先处理中心在盒子里的圆,如果我们是包含的, 它的成本更低,
|
||||||
if (box.containsPoint(circle.position)) {
|
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)));
|
let safePlace = Vector2.add(closestPointOnBounds, Vector2.multiply(result.normal, new Vector2(circle.radius)));
|
||||||
result.minimumTranslationVector = Vector2.subtract(circle.position, safePlace);
|
result.minimumTranslationVector = Vector2.subtract(circle.position, safePlace);
|
||||||
|
|
||||||
@@ -173,7 +173,8 @@ module es {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let sqrDistance = Vector2.distanceSquared(closestPointOnBounds, circle.position);
|
let sqrDistance = Vector2.distanceSquared(closestPointOnBounds, circle.position);
|
||||||
// 看盒子上的点与圆的距离是否小于半径
|
|
||||||
|
// 看框上的点距圆的半径是否小于圆的半径
|
||||||
if (sqrDistance == 0) {
|
if (sqrDistance == 0) {
|
||||||
result.minimumTranslationVector = Vector2.multiply(result.normal, new Vector2(circle.radius));
|
result.minimumTranslationVector = Vector2.multiply(result.normal, new Vector2(circle.radius));
|
||||||
} else if (sqrDistance <= circle.radius * 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);
|
let t = Vector2.dot(w, v) / Vector2.dot(v, v);
|
||||||
t = MathHelper.clamp(t, 0, 1);
|
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 second
|
||||||
* @param result
|
* @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 distanceSquared = Vector2.distanceSquared(first.position, second.position);
|
||||||
let sumOfRadii = first.radius + second.radius;
|
let sumOfRadii = first.radius + second.radius;
|
||||||
let collided = distanceSquared < sumOfRadii * sumOfRadii;
|
let collided = distanceSquared < sumOfRadii * sumOfRadii;
|
||||||
@@ -275,6 +276,11 @@ module es {
|
|||||||
result.minimumTranslationVector = Vector2.multiply(new Vector2(-depth), result.normal);
|
result.minimumTranslationVector = Vector2.multiply(new Vector2(-depth), result.normal);
|
||||||
result.point = Vector2.add(second.position, Vector2.multiply(result.normal, new Vector2(second.radius)));
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,7 +321,7 @@ module es {
|
|||||||
return new Rectangle(topLeft.x, topLeft.y, fullSize.x, fullSize.y)
|
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 normal = Vector2.zero;
|
||||||
let intersectionPoint = Vector2.zero;
|
let intersectionPoint = Vector2.zero;
|
||||||
let fraction = Number.MAX_VALUE;
|
let fraction = Number.MAX_VALUE;
|
||||||
|
|||||||
@@ -1,297 +1,297 @@
|
|||||||
class ArrayUtils {
|
class ArrayUtils {
|
||||||
/**
|
/**
|
||||||
* 执行冒泡排序
|
* 执行冒泡排序
|
||||||
* @param ary
|
* @param ary
|
||||||
*/
|
*/
|
||||||
public static bubbleSort(ary: number[]): void {
|
public static bubbleSort(ary: number[]): void {
|
||||||
let isExchange: Boolean = false;
|
let isExchange: Boolean = false;
|
||||||
for (let i: number = 0; i < ary.length; i++) {
|
for (let i: number = 0; i < ary.length; i++) {
|
||||||
isExchange = false;
|
isExchange = false;
|
||||||
for (let j: number = ary.length - 1; j > i; j--) {
|
for (let j: number = ary.length - 1; j > i; j--) {
|
||||||
if (ary[j] < ary[j - 1]) {
|
if (ary[j] < ary[j - 1]) {
|
||||||
let temp: number = ary[j];
|
let temp: number = ary[j];
|
||||||
ary[j] = ary[j - 1];
|
ary[j] = ary[j - 1];
|
||||||
ary[j - 1] = temp;
|
ary[j - 1] = temp;
|
||||||
isExchange = true;
|
isExchange = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!isExchange)
|
if (!isExchange)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行插入排序
|
* 执行插入排序
|
||||||
* @param ary
|
* @param ary
|
||||||
*/
|
*/
|
||||||
public static insertionSort(ary: number[]): void {
|
public static insertionSort(ary: number[]): void {
|
||||||
let len: number = ary.length;
|
let len: number = ary.length;
|
||||||
for (let i: number = 1; i < len; i++) {
|
for (let i: number = 1; i < len; i++) {
|
||||||
let val: number = ary[i];
|
let val: number = ary[i];
|
||||||
for (var j: number = i; j > 0 && ary[j - 1] > val; j--) {
|
for (var j: number = i; j > 0 && ary[j - 1] > val; j--) {
|
||||||
ary[j] = ary[j - 1];
|
ary[j] = ary[j - 1];
|
||||||
}
|
}
|
||||||
ary[j] = val;
|
ary[j] = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行二分搜索
|
* 执行二分搜索
|
||||||
* @param ary 搜索的数组(必须排序过)
|
* @param ary 搜索的数组(必须排序过)
|
||||||
* @param value 需要搜索的值
|
* @param value 需要搜索的值
|
||||||
* @returns 返回匹配结果的数组索引
|
* @returns 返回匹配结果的数组索引
|
||||||
*/
|
*/
|
||||||
public static binarySearch(ary: number[], value: number): number {
|
public static binarySearch(ary: number[], value: number): number {
|
||||||
let startIndex: number = 0;
|
let startIndex: number = 0;
|
||||||
let endIndex: number = ary.length;
|
let endIndex: number = ary.length;
|
||||||
let sub: number = (startIndex + endIndex) >> 1;
|
let sub: number = (startIndex + endIndex) >> 1;
|
||||||
while (startIndex < endIndex) {
|
while (startIndex < endIndex) {
|
||||||
if (value <= ary[sub]) endIndex = sub;
|
if (value <= ary[sub]) endIndex = sub;
|
||||||
else if (value >= ary[sub]) startIndex = sub + 1;
|
else if (value >= ary[sub]) startIndex = sub + 1;
|
||||||
sub = (startIndex + endIndex) >> 1;
|
sub = (startIndex + endIndex) >> 1;
|
||||||
}
|
}
|
||||||
if (ary[startIndex] == value) return startIndex;
|
if (ary[startIndex] == value) return startIndex;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回匹配项的索引
|
* 返回匹配项的索引
|
||||||
* @param ary
|
* @param ary
|
||||||
* @param num
|
* @param num
|
||||||
*/
|
*/
|
||||||
public static findElementIndex(ary: any[], num: any): any {
|
public static findElementIndex(ary: any[], num: any): any {
|
||||||
let len: number = ary.length;
|
let len: number = ary.length;
|
||||||
for (let i: number = 0; i < len; ++i) {
|
for (let i: number = 0; i < len; ++i) {
|
||||||
if (ary[i] == num)
|
if (ary[i] == num)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回数组中最大值的索引
|
* 返回数组中最大值的索引
|
||||||
* @param ary
|
* @param ary
|
||||||
*/
|
*/
|
||||||
public static getMaxElementIndex(ary: number[]): number {
|
public static getMaxElementIndex(ary: number[]): number {
|
||||||
let matchIndex: number = 0;
|
let matchIndex: number = 0;
|
||||||
let len: number = ary.length;
|
let len: number = ary.length;
|
||||||
for (let j: number = 1; j < len; j++) {
|
for (let j: number = 1; j < len; j++) {
|
||||||
if (ary[j] > ary[matchIndex])
|
if (ary[j] > ary[matchIndex])
|
||||||
matchIndex = j;
|
matchIndex = j;
|
||||||
}
|
}
|
||||||
return matchIndex;
|
return matchIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回数组中最小值的索引
|
* 返回数组中最小值的索引
|
||||||
* @param ary
|
* @param ary
|
||||||
*/
|
*/
|
||||||
public static getMinElementIndex(ary: number[]): number {
|
public static getMinElementIndex(ary: number[]): number {
|
||||||
let matchIndex: number = 0;
|
let matchIndex: number = 0;
|
||||||
let len: number = ary.length;
|
let len: number = ary.length;
|
||||||
for (let j: number = 1; j < len; j++) {
|
for (let j: number = 1; j < len; j++) {
|
||||||
if (ary[j] < ary[matchIndex])
|
if (ary[j] < ary[matchIndex])
|
||||||
matchIndex = j;
|
matchIndex = j;
|
||||||
}
|
}
|
||||||
return matchIndex;
|
return matchIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回一个"唯一性"数组
|
* 返回一个"唯一性"数组
|
||||||
* @param ary 需要唯一性的数组
|
* @param ary 需要唯一性的数组
|
||||||
* @returns 唯一性的数组
|
* @returns 唯一性的数组
|
||||||
*
|
*
|
||||||
* @tutorial
|
* @tutorial
|
||||||
* 比如: [1, 2, 2, 3, 4]
|
* 比如: [1, 2, 2, 3, 4]
|
||||||
* 返回: [1, 2, 3, 4]
|
* 返回: [1, 2, 3, 4]
|
||||||
*/
|
*/
|
||||||
public static getUniqueAry(ary: number[]): number[] {
|
public static getUniqueAry(ary: number[]): number[] {
|
||||||
let uAry: number[] = [];
|
let uAry: number[] = [];
|
||||||
let newAry: number[] = [];
|
let newAry: number[] = [];
|
||||||
let count = ary.length;
|
let count = ary.length;
|
||||||
for (let i: number = 0; i < count; ++i) {
|
for (let i: number = 0; i < count; ++i) {
|
||||||
let value: number = ary[i];
|
let value: number = ary[i];
|
||||||
if (uAry.indexOf(value) == -1) uAry.push(value);
|
if (uAry.indexOf(value) == -1) uAry.push(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
count = uAry.length;
|
count = uAry.length;
|
||||||
for (let i: number = count - 1; i >= 0; --i) {
|
for (let i: number = count - 1; i >= 0; --i) {
|
||||||
newAry.unshift(uAry[i]);
|
newAry.unshift(uAry[i]);
|
||||||
}
|
}
|
||||||
return newAry;
|
return newAry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回2个数组中不同的部分
|
* 返回2个数组中不同的部分
|
||||||
* 比如数组A = [1, 2, 3, 4, 6]
|
* 比如数组A = [1, 2, 3, 4, 6]
|
||||||
* 数组B = [0, 2, 1, 3, 4]
|
* 数组B = [0, 2, 1, 3, 4]
|
||||||
* 返回[6, 0]
|
* 返回[6, 0]
|
||||||
* @param aryA
|
* @param aryA
|
||||||
* @param aryB
|
* @param aryB
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static getDifferAry(aryA: number[], aryB: number[]): number[] {
|
public static getDifferAry(aryA: number[], aryB: number[]): number[] {
|
||||||
aryA = this.getUniqueAry(aryA);
|
aryA = this.getUniqueAry(aryA);
|
||||||
aryB = this.getUniqueAry(aryB);
|
aryB = this.getUniqueAry(aryB);
|
||||||
let ary: number[] = aryA.concat(aryB);
|
let ary: number[] = aryA.concat(aryB);
|
||||||
let uObj: Object = {};
|
let uObj: Object = {};
|
||||||
let newAry: number[] = [];
|
let newAry: number[] = [];
|
||||||
let count: number = ary.length;
|
let count: number = ary.length;
|
||||||
for (let j: number = 0; j < count; ++j) {
|
for (let j: number = 0; j < count; ++j) {
|
||||||
if (!uObj[ary[j]]) {
|
if (!uObj[ary[j]]) {
|
||||||
uObj[ary[j]] = {};
|
uObj[ary[j]] = {};
|
||||||
uObj[ary[j]].count = 0;
|
uObj[ary[j]].count = 0;
|
||||||
uObj[ary[j]].key = ary[j];
|
uObj[ary[j]].key = ary[j];
|
||||||
uObj[ary[j]].count++;
|
uObj[ary[j]].count++;
|
||||||
} else {
|
} else {
|
||||||
if (uObj[ary[j]] instanceof Object) {
|
if (uObj[ary[j]] instanceof Object) {
|
||||||
uObj[ary[j]].count++;
|
uObj[ary[j]].count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let i in uObj) {
|
for (let i in uObj) {
|
||||||
if (uObj[i].count != 2) {
|
if (uObj[i].count != 2) {
|
||||||
newAry.unshift(uObj[i].key);
|
newAry.unshift(uObj[i].key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return newAry;
|
return newAry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 交换数组元素
|
* 交换数组元素
|
||||||
* @param array 目标数组
|
* @param array 目标数组
|
||||||
* @param index1 交换后的索引
|
* @param index1 交换后的索引
|
||||||
* @param index2 交换前的索引
|
* @param index2 交换前的索引
|
||||||
*/
|
*/
|
||||||
public static swap(array: any[], index1: number, index2: number): void {
|
public static swap(array: any[], index1: number, index2: number): void {
|
||||||
let temp: any = array[index1];
|
let temp: any = array[index1];
|
||||||
array[index1] = array[index2];
|
array[index1] = array[index2];
|
||||||
array[index2] = temp;
|
array[index2] = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 清除列表
|
* 清除列表
|
||||||
* @param ary
|
* @param ary
|
||||||
*/
|
*/
|
||||||
public static clearList(ary: any[]): void {
|
public static clearList(ary: any[]): void {
|
||||||
if (!ary) return;
|
if (!ary) return;
|
||||||
let length: number = ary.length;
|
let length: number = ary.length;
|
||||||
for (let i: number = length - 1; i >= 0; i -= 1) {
|
for (let i: number = length - 1; i >= 0; i -= 1) {
|
||||||
ary.splice(i, 1);
|
ary.splice(i, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 克隆一个数组
|
* 克隆一个数组
|
||||||
* @param ary 需要克隆的数组
|
* @param ary 需要克隆的数组
|
||||||
* @return 克隆的数组
|
* @return 克隆的数组
|
||||||
*/
|
*/
|
||||||
public static cloneList(ary: any[]): any[] {
|
public static cloneList(ary: any[]): any[] {
|
||||||
if (!ary) return null;
|
if (!ary) return null;
|
||||||
return ary.slice(0, ary.length);
|
return ary.slice(0, ary.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断2个数组是否相同
|
* 判断2个数组是否相同
|
||||||
* @param ary1 数组1
|
* @param ary1 数组1
|
||||||
* @param ary2 数组2
|
* @param ary2 数组2
|
||||||
*/
|
*/
|
||||||
public static equals(ary1: number[], ary2: number[]): Boolean {
|
public static equals(ary1: number[], ary2: number[]): Boolean {
|
||||||
if (ary1 == ary2) return true;
|
if (ary1 == ary2) return true;
|
||||||
let length: number = ary1.length;
|
let length: number = ary1.length;
|
||||||
if (length != ary2.length) return false;
|
if (length != ary2.length) return false;
|
||||||
while (length--) {
|
while (length--) {
|
||||||
if (ary1[length] != ary2[length])
|
if (ary1[length] != ary2[length])
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据索引插入元素,索引和索引后的元素都向后移动一位
|
* 根据索引插入元素,索引和索引后的元素都向后移动一位
|
||||||
* @param ary
|
* @param ary
|
||||||
* @param index 插入索引
|
* @param index 插入索引
|
||||||
* @param value 插入的元素
|
* @param value 插入的元素
|
||||||
* @returns 插入的元素 未插入则返回空
|
* @returns 插入的元素 未插入则返回空
|
||||||
*/
|
*/
|
||||||
public static insert(ary: any[], index: number, value: any): any {
|
public static insert(ary: any[], index: number, value: any): any {
|
||||||
if (!ary) return null;
|
if (!ary) return null;
|
||||||
let length: number = ary.length;
|
let length: number = ary.length;
|
||||||
if (index > length) index = length;
|
if (index > length) index = length;
|
||||||
if (index < 0) index = 0;
|
if (index < 0) index = 0;
|
||||||
if (index == length) ary.push(value); //插入最后
|
if (index == length) ary.push(value); //插入最后
|
||||||
else if (index == 0) ary.unshift(value); //插入头
|
else if (index == 0) ary.unshift(value); //插入头
|
||||||
else {
|
else {
|
||||||
for (let i: number = length - 1; i >= index; i -= 1) {
|
for (let i: number = length - 1; i >= index; i -= 1) {
|
||||||
ary[i + 1] = ary[i];
|
ary[i + 1] = ary[i];
|
||||||
}
|
}
|
||||||
ary[index] = value;
|
ary[index] = value;
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打乱数组 Fisher–Yates shuffle
|
* 打乱数组 Fisher–Yates shuffle
|
||||||
* @param list
|
* @param list
|
||||||
*/
|
*/
|
||||||
public static shuffle<T>(list: T[]) {
|
public static shuffle<T>(list: T[]) {
|
||||||
let n = list.length;
|
let n = list.length;
|
||||||
while (n > 1) {
|
while (n > 1) {
|
||||||
n--;
|
n--;
|
||||||
let k = RandomUtils.randint(0, n + 1);
|
let k = RandomUtils.randint(0, n + 1);
|
||||||
let value: T = list[k];
|
let value: T = list[k];
|
||||||
list[k] = list[n];
|
list[k] = list[n];
|
||||||
list[n] = value;
|
list[n] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 如果项目已经在列表中,返回false,如果成功添加,返回true
|
* 如果项目已经在列表中,返回false,如果成功添加,返回true
|
||||||
* @param list
|
* @param list
|
||||||
* @param item
|
* @param item
|
||||||
*/
|
*/
|
||||||
public static addIfNotPresent<T>(list: T[], item: T) {
|
public static addIfNotPresent<T>(list: T[], item: T) {
|
||||||
if (new linq.List(list).contains(item))
|
if (new linq.List(list).contains(item))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
list.push(item);
|
list.push(item);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回列表中的最后一项。列表中至少应该有一个项目
|
* 返回列表中的最后一项。列表中至少应该有一个项目
|
||||||
* @param list
|
* @param list
|
||||||
*/
|
*/
|
||||||
public static lastItem<T>(list: T[]) {
|
public static lastItem<T>(list: T[]) {
|
||||||
return list[list.length - 1];
|
return list[list.length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从列表中随机获取一个项目。不清空检查列表!
|
* 从列表中随机获取一个项目。不清空检查列表!
|
||||||
* @param list
|
* @param list
|
||||||
*/
|
*/
|
||||||
public static randomItem<T>(list: T[]) {
|
public static randomItem<T>(list: T[]) {
|
||||||
return list[RandomUtils.randint(0, list.length - 1)];
|
return list[RandomUtils.randint(0, list.length - 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从列表中随机获取物品。不清空检查列表,也不验证列表数是否大于项目数。返回的List可以通过ListPool.free放回池中
|
* 从列表中随机获取物品。不清空检查列表,也不验证列表数是否大于项目数。返回的List可以通过ListPool.free放回池中
|
||||||
* @param list
|
* @param list
|
||||||
* @param itemCount 从列表中返回的随机项目的数量
|
* @param itemCount 从列表中返回的随机项目的数量
|
||||||
*/
|
*/
|
||||||
public static randomItems<T>(list: T[], itemCount: number){
|
public static randomItems<T>(list: T[], itemCount: number){
|
||||||
let set = new Set<T>();
|
let set = new Set<T>();
|
||||||
while (set.size != itemCount) {
|
while (set.size != itemCount) {
|
||||||
let item = this.randomItem(list);
|
let item = this.randomItem(list);
|
||||||
if (!set.has(item))
|
if (!set.has(item))
|
||||||
set.add(item);
|
set.add(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
let items = es.ListPool.obtain<T>();
|
let items = es.ListPool.obtain<T>();
|
||||||
set.forEach(value => items.push(value));
|
set.forEach(value => items.push(value));
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,134 +1,134 @@
|
|||||||
module es{
|
module es{
|
||||||
export class Base64Utils {
|
export class Base64Utils {
|
||||||
private static _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
private static _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断是否原生支持Base64位解析
|
* 判断是否原生支持Base64位解析
|
||||||
*/
|
*/
|
||||||
static get nativeBase64() {
|
static get nativeBase64() {
|
||||||
return (typeof (window.atob) === "function");
|
return (typeof (window.atob) === "function");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解码
|
* 解码
|
||||||
* @param input
|
* @param input
|
||||||
*/
|
*/
|
||||||
static decode(input:string): string {
|
static decode(input:string): string {
|
||||||
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
|
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
|
||||||
|
|
||||||
if (this.nativeBase64) {
|
if (this.nativeBase64) {
|
||||||
return window.atob(input);
|
return window.atob(input);
|
||||||
} else {
|
} else {
|
||||||
var output: any = [], chr1: number, chr2: number, chr3: number, enc1: number, enc2: number, enc3: number, enc4: number, i: number = 0;
|
var output: any = [], chr1: number, chr2: number, chr3: number, enc1: number, enc2: number, enc3: number, enc4: number, i: number = 0;
|
||||||
|
|
||||||
while (i < input.length) {
|
while (i < input.length) {
|
||||||
enc1 = this._keyStr.indexOf(input.charAt(i++));
|
enc1 = this._keyStr.indexOf(input.charAt(i++));
|
||||||
enc2 = this._keyStr.indexOf(input.charAt(i++));
|
enc2 = this._keyStr.indexOf(input.charAt(i++));
|
||||||
enc3 = this._keyStr.indexOf(input.charAt(i++));
|
enc3 = this._keyStr.indexOf(input.charAt(i++));
|
||||||
enc4 = this._keyStr.indexOf(input.charAt(i++));
|
enc4 = this._keyStr.indexOf(input.charAt(i++));
|
||||||
|
|
||||||
chr1 = (enc1 << 2) | (enc2 >> 4);
|
chr1 = (enc1 << 2) | (enc2 >> 4);
|
||||||
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
|
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
|
||||||
chr3 = ((enc3 & 3) << 6) | enc4;
|
chr3 = ((enc3 & 3) << 6) | enc4;
|
||||||
|
|
||||||
output.push(String.fromCharCode(chr1));
|
output.push(String.fromCharCode(chr1));
|
||||||
|
|
||||||
if (enc3 !== 64) {
|
if (enc3 !== 64) {
|
||||||
output.push(String.fromCharCode(chr2));
|
output.push(String.fromCharCode(chr2));
|
||||||
}
|
}
|
||||||
if (enc4 !== 64) {
|
if (enc4 !== 64) {
|
||||||
output.push(String.fromCharCode(chr3));
|
output.push(String.fromCharCode(chr3));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
output = output.join("");
|
output = output.join("");
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 编码
|
* 编码
|
||||||
* @param input
|
* @param input
|
||||||
*/
|
*/
|
||||||
static encode(input:string): string {
|
static encode(input:string): string {
|
||||||
input = input.replace(/\r\n/g, "\n");
|
input = input.replace(/\r\n/g, "\n");
|
||||||
if (this.nativeBase64) {
|
if (this.nativeBase64) {
|
||||||
window.btoa(input);
|
window.btoa(input);
|
||||||
} else {
|
} else {
|
||||||
var output: any = [], chr1: number, chr2: number, chr3: number, enc1: number, enc2: number, enc3: number, enc4: number, i: number = 0;
|
var output: any = [], chr1: number, chr2: number, chr3: number, enc1: number, enc2: number, enc3: number, enc4: number, i: number = 0;
|
||||||
while (i < input.length) {
|
while (i < input.length) {
|
||||||
chr1 = input.charCodeAt(i++);
|
chr1 = input.charCodeAt(i++);
|
||||||
chr2 = input.charCodeAt(i++);
|
chr2 = input.charCodeAt(i++);
|
||||||
chr3 = input.charCodeAt(i++);
|
chr3 = input.charCodeAt(i++);
|
||||||
|
|
||||||
enc1 = chr1 >> 2;
|
enc1 = chr1 >> 2;
|
||||||
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
|
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
|
||||||
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
|
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
|
||||||
enc4 = chr3 & 63;
|
enc4 = chr3 & 63;
|
||||||
|
|
||||||
if (isNaN(chr2)) {
|
if (isNaN(chr2)) {
|
||||||
enc3 = enc4 = 64;
|
enc3 = enc4 = 64;
|
||||||
} else if (isNaN(chr3)) {
|
} else if (isNaN(chr3)) {
|
||||||
enc4 = 64;
|
enc4 = 64;
|
||||||
}
|
}
|
||||||
|
|
||||||
output.push(this._keyStr.charAt(enc1));
|
output.push(this._keyStr.charAt(enc1));
|
||||||
output.push(this._keyStr.charAt(enc2));
|
output.push(this._keyStr.charAt(enc2));
|
||||||
output.push(this._keyStr.charAt(enc3));
|
output.push(this._keyStr.charAt(enc3));
|
||||||
output.push(this._keyStr.charAt(enc4));
|
output.push(this._keyStr.charAt(enc4));
|
||||||
}
|
}
|
||||||
|
|
||||||
output = output.join("");
|
output = output.join("");
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析Base64格式数据
|
* 解析Base64格式数据
|
||||||
* @param input
|
* @param input
|
||||||
* @param bytes
|
* @param bytes
|
||||||
*/
|
*/
|
||||||
static decodeBase64AsArray(input: string, bytes: number): Uint32Array {
|
static decodeBase64AsArray(input: string, bytes: number): Uint32Array {
|
||||||
bytes = bytes || 1;
|
bytes = bytes || 1;
|
||||||
|
|
||||||
var dec = Base64Utils.decode(input), i, j, len;
|
var dec = Base64Utils.decode(input), i, j, len;
|
||||||
var ar: Uint32Array = new Uint32Array(dec.length / bytes);
|
var ar: Uint32Array = new Uint32Array(dec.length / bytes);
|
||||||
|
|
||||||
for (i = 0, len = dec.length / bytes; i < len; i++) {
|
for (i = 0, len = dec.length / bytes; i < len; i++) {
|
||||||
ar[i] = 0;
|
ar[i] = 0;
|
||||||
for (j = bytes - 1; j >= 0; --j) {
|
for (j = bytes - 1; j >= 0; --j) {
|
||||||
ar[i] += dec.charCodeAt((i * bytes) + j) << (j << 3);
|
ar[i] += dec.charCodeAt((i * bytes) + j) << (j << 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ar;
|
return ar;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 暂时不支持
|
* 暂时不支持
|
||||||
* @param data
|
* @param data
|
||||||
* @param decoded
|
* @param decoded
|
||||||
* @param compression
|
* @param compression
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
static decompress(data: string, decoded: any, compression: string): any {
|
static decompress(data: string, decoded: any, compression: string): any {
|
||||||
throw new Error("GZIP/ZLIB compressed TMX Tile Map not supported!");
|
throw new Error("GZIP/ZLIB compressed TMX Tile Map not supported!");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析csv数据
|
* 解析csv数据
|
||||||
* @param input
|
* @param input
|
||||||
*/
|
*/
|
||||||
static decodeCSV(input: string): Array<number> {
|
static decodeCSV(input: string): Array<number> {
|
||||||
var entries: Array<any> = input.replace("\n", "").trim().split(",");
|
var entries: Array<any> = input.replace("\n", "").trim().split(",");
|
||||||
|
|
||||||
var result:Array<number> = [];
|
var result:Array<number> = [];
|
||||||
for (var i:number = 0; i < entries.length; i++) {
|
for (var i:number = 0; i < entries.length; i++) {
|
||||||
result.push(+entries[i]);
|
result.push(+entries[i]);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,133 +1,133 @@
|
|||||||
class RandomUtils {
|
class RandomUtils {
|
||||||
/**
|
/**
|
||||||
* 在 start 与 stop之间取一个随机整数,可以用step指定间隔, 但不包括较大的端点(start与stop较大的一个)
|
* 在 start 与 stop之间取一个随机整数,可以用step指定间隔, 但不包括较大的端点(start与stop较大的一个)
|
||||||
* 如
|
* 如
|
||||||
* this.randrange(1, 10, 3)
|
* this.randrange(1, 10, 3)
|
||||||
* 则返回的可能是 1 或 4 或 7 , 注意 这里面不会返回10,因为是10是大端点
|
* 则返回的可能是 1 或 4 或 7 , 注意 这里面不会返回10,因为是10是大端点
|
||||||
*
|
*
|
||||||
* @param start
|
* @param start
|
||||||
* @param stop
|
* @param stop
|
||||||
* @param step
|
* @param step
|
||||||
* @return 假设 start < stop, [start, stop) 区间内的随机整数
|
* @return 假设 start < stop, [start, stop) 区间内的随机整数
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public static randrange(start: number, stop: number, step: number = 1): number {
|
public static randrange(start: number, stop: number, step: number = 1): number {
|
||||||
if (step == 0)
|
if (step == 0)
|
||||||
throw new Error('step 不能为 0');
|
throw new Error('step 不能为 0');
|
||||||
|
|
||||||
let width: number = stop - start;
|
let width: number = stop - start;
|
||||||
if (width == 0)
|
if (width == 0)
|
||||||
throw new Error('没有可用的范围(' + start + ',' + stop + ')');
|
throw new Error('没有可用的范围(' + start + ',' + stop + ')');
|
||||||
if (width < 0)
|
if (width < 0)
|
||||||
width = start - stop;
|
width = start - stop;
|
||||||
|
|
||||||
let n: number = Math.floor((width + step - 1) / step);
|
let n: number = Math.floor((width + step - 1) / step);
|
||||||
return Math.floor(this.random() * n) * step + Math.min(start, stop);
|
return Math.floor(this.random() * n) * step + Math.min(start, stop);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回a 到 b直间的随机整数,包括 a 和 b
|
* 返回a 到 b直间的随机整数,包括 a 和 b
|
||||||
* @param a
|
* @param a
|
||||||
* @param b
|
* @param b
|
||||||
* @return [a, b] 直接的随机整数
|
* @return [a, b] 直接的随机整数
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public static randint(a: number, b: number): number {
|
public static randint(a: number, b: number): number {
|
||||||
a = Math.floor(a);
|
a = Math.floor(a);
|
||||||
b = Math.floor(b);
|
b = Math.floor(b);
|
||||||
if (a > b)
|
if (a > b)
|
||||||
a++;
|
a++;
|
||||||
else
|
else
|
||||||
b++;
|
b++;
|
||||||
return this.randrange(a, b);
|
return this.randrange(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回 a - b之间的随机数,不包括 Math.max(a, b)
|
* 返回 a - b之间的随机数,不包括 Math.max(a, b)
|
||||||
* @param a
|
* @param a
|
||||||
* @param b
|
* @param b
|
||||||
* @return 假设 a < b, [a, b)
|
* @return 假设 a < b, [a, b)
|
||||||
*/
|
*/
|
||||||
public static randnum(a: number, b: number): number {
|
public static randnum(a: number, b: number): number {
|
||||||
return this.random() * (b - a) + a;
|
return this.random() * (b - a) + a;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打乱数组
|
* 打乱数组
|
||||||
* @param array
|
* @param array
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static shuffle(array: any[]): any[] {
|
public static shuffle(array: any[]): any[] {
|
||||||
array.sort(this._randomCompare);
|
array.sort(this._randomCompare);
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从序列中随机取一个元素
|
* 从序列中随机取一个元素
|
||||||
* @param sequence 可以是 数组、 vector,等只要是有length属性,并且可以用数字索引获取元素的对象,
|
* @param sequence 可以是 数组、 vector,等只要是有length属性,并且可以用数字索引获取元素的对象,
|
||||||
* 另外,字符串也是允许的。
|
* 另外,字符串也是允许的。
|
||||||
* @return 序列中的某一个元素
|
* @return 序列中的某一个元素
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public static choice(sequence: any): any {
|
public static choice(sequence: any): any {
|
||||||
if (!sequence.hasOwnProperty("length"))
|
if (!sequence.hasOwnProperty("length"))
|
||||||
throw new Error('无法对此对象执行此操作');
|
throw new Error('无法对此对象执行此操作');
|
||||||
let index: number = Math.floor(this.random() * sequence.length);
|
let index: number = Math.floor(this.random() * sequence.length);
|
||||||
if (sequence instanceof String)
|
if (sequence instanceof String)
|
||||||
return String(sequence).charAt(index);
|
return String(sequence).charAt(index);
|
||||||
else
|
else
|
||||||
return sequence[index];
|
return sequence[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 对列表中的元素进行随机采æ ?
|
* 对列表中的元素进行随机采æ ?
|
||||||
* <pre>
|
* <pre>
|
||||||
* this.sample([1, 2, 3, 4, 5], 3) // Choose 3 elements
|
* this.sample([1, 2, 3, 4, 5], 3) // Choose 3 elements
|
||||||
* [4, 1, 5]
|
* [4, 1, 5]
|
||||||
* </pre>
|
* </pre>
|
||||||
* @param sequence
|
* @param sequence
|
||||||
* @param num
|
* @param num
|
||||||
* @return
|
* @return
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public static sample(sequence: any[], num: number): any[] {
|
public static sample(sequence: any[], num: number): any[] {
|
||||||
let len: number = sequence.length;
|
let len: number = sequence.length;
|
||||||
if (num <= 0 || len < num)
|
if (num <= 0 || len < num)
|
||||||
throw new Error("采样数量不够");
|
throw new Error("采样数量不够");
|
||||||
|
|
||||||
let selected: any[] = [];
|
let selected: any[] = [];
|
||||||
let indices: any[] = [];
|
let indices: any[] = [];
|
||||||
for (let i: number = 0; i < num; i++) {
|
for (let i: number = 0; i < num; i++) {
|
||||||
let index: number = Math.floor(this.random() * len);
|
let index: number = Math.floor(this.random() * len);
|
||||||
while (indices.indexOf(index) >= 0)
|
while (indices.indexOf(index) >= 0)
|
||||||
index = Math.floor(this.random() * len);
|
index = Math.floor(this.random() * len);
|
||||||
|
|
||||||
selected.push(sequence[index]);
|
selected.push(sequence[index]);
|
||||||
indices.push(index);
|
indices.push(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
return selected;
|
return selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 返回 0.0 - 1.0 之间的随机数,等同于 Math.random()
|
* 返回 0.0 - 1.0 之间的随机数,等同于 Math.random()
|
||||||
* @return Math.random()
|
* @return Math.random()
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public static random(): number {
|
public static random(): number {
|
||||||
return Math.random();
|
return Math.random();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算概率
|
* 计算概率
|
||||||
* @param chance 概率
|
* @param chance 概率
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static boolean(chance: number = .5): boolean {
|
public static boolean(chance: number = .5): boolean {
|
||||||
return (this.random() < chance) ? true : false;
|
return (this.random() < chance) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static _randomCompare(a: Object, b: Object): number {
|
private static _randomCompare(a: Object, b: Object): number {
|
||||||
return (this.random() > .5) ? 1 : -1;
|
return (this.random() > .5) ? 1 : -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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<number>, moveY: Ref<number>) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
class WebGLUtils {
|
class WebGLUtils {
|
||||||
/**
|
/**
|
||||||
* 获取webgl context
|
* 获取webgl context
|
||||||
*/
|
*/
|
||||||
public static getContext() {
|
public static getContext() {
|
||||||
const canvas = document.getElementsByTagName('canvas')[0];
|
const canvas = document.getElementsByTagName('canvas')[0];
|
||||||
return canvas.getContext('2d');
|
return canvas.getContext('2d');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
///<reference path="../LinkList.ts" />
|
///<reference path="../Collections/LinkList.ts" />
|
||||||
module es {
|
module es {
|
||||||
/**
|
/**
|
||||||
* 类,它可以计算出一个网格,表示从给定的一组遮挡物的原点可以看到哪些区域。使用方法如下。
|
* 类,它可以计算出一个网格,表示从给定的一组遮挡物的原点可以看到哪些区域。使用方法如下。
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user