补全注释
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
{
|
{
|
||||||
"toolchains": []
|
"toolchains": [],
|
||||||
|
"backend.maxHeapSizeMb": 896
|
||||||
}
|
}
|
||||||
Vendored
+94
-50
@@ -3344,27 +3344,31 @@ declare module es {
|
|||||||
declare module es {
|
declare module es {
|
||||||
class MatrixHelper {
|
class MatrixHelper {
|
||||||
/**
|
/**
|
||||||
* 创建一个新的Matrix2D,其中包含两个矩阵的和
|
* 该静态方法用于计算两个 Matrix2D 对象的和。
|
||||||
* @param matrix1
|
* @param {Matrix2D} matrix1 - 加数矩阵。
|
||||||
* @param matrix2
|
* @param {Matrix2D} matrix2 - 加数矩阵。
|
||||||
|
* @returns {Matrix2D} - 计算结果的 Matrix2D 对象。
|
||||||
*/
|
*/
|
||||||
static add(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D;
|
static add(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D;
|
||||||
/**
|
/**
|
||||||
* 将一个Matrix2D的元素除以另一个矩阵的元素
|
* 该静态方法用于计算两个 Matrix2D 对象的商。
|
||||||
* @param matrix1
|
* @param {Matrix2D} matrix1 - 被除数矩阵。
|
||||||
* @param matrix2
|
* @param {Matrix2D} matrix2 - 除数矩阵。
|
||||||
|
* @returns {Matrix2D} - 计算结果的 Matrix2D 对象。
|
||||||
*/
|
*/
|
||||||
static divide(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D;
|
static divide(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D;
|
||||||
/**
|
/**
|
||||||
* 创建一个新的Matrix2D,包含两个矩阵的乘法
|
* 该静态方法用于计算两个 Matrix2D 对象或一个 Matrix2D 对象和一个数字的乘积。
|
||||||
* @param matrix1
|
* @param {Matrix2D} matrix1 - 第一个矩阵。
|
||||||
* @param matrix2
|
* @param {Matrix2D | number} matrix2 - 第二个矩阵或一个数字。
|
||||||
|
* @returns {Matrix2D} - 计算结果的 Matrix2D 对象。
|
||||||
*/
|
*/
|
||||||
static mutiply(matrix1: Matrix2D, matrix2: Matrix2D | number): Matrix2D;
|
static multiply(matrix1: Matrix2D, matrix2: Matrix2D | number): Matrix2D;
|
||||||
/**
|
/**
|
||||||
* 创建一个新的Matrix2D,包含一个矩阵与另一个矩阵的减法。
|
* 该静态方法用于计算两个 Matrix2D 对象的差。
|
||||||
* @param matrix1
|
* @param {Matrix2D} matrix1 - 第一个矩阵。
|
||||||
* @param matrix2
|
* @param {Matrix2D} matrix2 - 第二个矩阵。
|
||||||
|
* @returns {Matrix2D} - 计算结果的 Matrix2D 对象。
|
||||||
*/
|
*/
|
||||||
static subtract(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D;
|
static subtract(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D;
|
||||||
}
|
}
|
||||||
@@ -3511,7 +3515,7 @@ declare module es {
|
|||||||
* @param offsetX 要添加到这个矩形的X坐标
|
* @param offsetX 要添加到这个矩形的X坐标
|
||||||
* @param offsetY 要添加到这个矩形的y坐标
|
* @param offsetY 要添加到这个矩形的y坐标
|
||||||
*/
|
*/
|
||||||
offset(offsetX: number, offsetY: number): void;
|
offset(offsetX: number, offsetY: number): this;
|
||||||
/**
|
/**
|
||||||
* 创建一个完全包含两个其他矩形的新矩形
|
* 创建一个完全包含两个其他矩形的新矩形
|
||||||
* @param value1
|
* @param value1
|
||||||
@@ -3563,37 +3567,46 @@ declare module es {
|
|||||||
}
|
}
|
||||||
declare module es {
|
declare module es {
|
||||||
/**
|
/**
|
||||||
* 它存储值,直到累计的总数大于1。一旦超过1,该值将在调用update时添加到amount中
|
* 该类用于存储具有亚像素分辨率的浮点数。
|
||||||
* 一般用法如下:
|
|
||||||
*
|
|
||||||
* let deltaMove = this.velocity * es.Time.deltaTime;
|
|
||||||
* deltaMove.x = this._x.update(deltaMove.x);
|
|
||||||
* deltaMove.y = this._y.update(deltaMove.y);
|
|
||||||
*/
|
*/
|
||||||
class SubpixelFloat {
|
class SubpixelFloat {
|
||||||
|
/**
|
||||||
|
* 存储 SubpixelFloat 值的浮点余数。
|
||||||
|
*/
|
||||||
remainder: number;
|
remainder: number;
|
||||||
/**
|
/**
|
||||||
* 以amount递增余数,将值截断,存储新的余数并将amount设置为当前值
|
* 通过将给定数量的像素添加到余数中来更新 SubpixelFloat 值。
|
||||||
* @param amount
|
* 返回更新后的整数部分,余数表示当前值中包含的亚像素部分。
|
||||||
|
* @param {number} amount - 要添加到余数中的像素数。
|
||||||
|
* @returns {number} 更新后的整数部分。
|
||||||
*/
|
*/
|
||||||
update(amount: number): number;
|
update(amount: number): number;
|
||||||
/**
|
/**
|
||||||
* 将余数重置为0
|
* 将 SubpixelFloat 值重置为零。
|
||||||
*/
|
*/
|
||||||
reset(): void;
|
reset(): void;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
declare module es {
|
declare module es {
|
||||||
|
/**
|
||||||
|
* 该类用于存储具有亚像素分辨率的二维向量。
|
||||||
|
*/
|
||||||
class SubpixelVector2 {
|
class SubpixelVector2 {
|
||||||
|
/**
|
||||||
|
* 用于存储 x 坐标的 SubpixelFloat 对象。
|
||||||
|
*/
|
||||||
_x: SubpixelFloat;
|
_x: SubpixelFloat;
|
||||||
|
/**
|
||||||
|
* 用于存储 y 坐标的 SubpixelFloat 对象。
|
||||||
|
*/
|
||||||
_y: SubpixelFloat;
|
_y: SubpixelFloat;
|
||||||
/**
|
/**
|
||||||
* 以数量递增s/y余数,将值截断为整数,存储新的余数并将amount设置为当前值
|
* 通过将给定数量的像素添加到余数中来更新 SubpixelVector2 值。
|
||||||
* @param amount
|
* @param {Vector2} amount - 要添加到余数中的像素向量。
|
||||||
*/
|
*/
|
||||||
update(amount: Vector2): void;
|
update(amount: Vector2): void;
|
||||||
/**
|
/**
|
||||||
* 将余数重置为0
|
* 将 SubpixelVector2 值的余数重置为零。
|
||||||
*/
|
*/
|
||||||
reset(): void;
|
reset(): void;
|
||||||
}
|
}
|
||||||
@@ -3989,25 +4002,46 @@ declare module es {
|
|||||||
}
|
}
|
||||||
declare module es {
|
declare module es {
|
||||||
abstract class Shape {
|
abstract class Shape {
|
||||||
/**
|
|
||||||
* 有一个单独的位置字段可以让我们改变形状的位置来进行碰撞检查,而不是改变entity.position。
|
|
||||||
* 触发碰撞器/边界/散列更新的位置。
|
|
||||||
* 内部字段
|
|
||||||
*/
|
|
||||||
position: Vector2;
|
position: Vector2;
|
||||||
/**
|
|
||||||
* 这不是中心。这个值不一定是物体的中心。对撞机更准确。
|
|
||||||
* 应用任何转换旋转的localOffset
|
|
||||||
* 内部字段
|
|
||||||
*/
|
|
||||||
center: Vector2;
|
center: Vector2;
|
||||||
/** 缓存的形状边界 内部字段 */
|
|
||||||
bounds: Rectangle;
|
bounds: Rectangle;
|
||||||
|
/**
|
||||||
|
* 根据形状的碰撞器重新计算形状的边界。
|
||||||
|
* @param {Collider} collider - 用于重新计算形状边界的碰撞器。
|
||||||
|
*/
|
||||||
abstract recalculateBounds(collider: Collider): any;
|
abstract recalculateBounds(collider: Collider): any;
|
||||||
|
/**
|
||||||
|
* 确定形状是否与另一个形状重叠。
|
||||||
|
* @param {Shape} other - 要检查重叠的形状。
|
||||||
|
* @returns {boolean} 如果形状重叠,则为 true;否则为 false。
|
||||||
|
*/
|
||||||
abstract overlaps(other: Shape): boolean;
|
abstract overlaps(other: Shape): boolean;
|
||||||
|
/**
|
||||||
|
* 确定形状是否与另一个形状碰撞。
|
||||||
|
* @param {Shape} other - 要检查碰撞的形状。
|
||||||
|
* @param {Out<CollisionResult>} collisionResult - 如果形状碰撞,则要填充的碰撞结果对象。
|
||||||
|
* @returns {boolean} 如果形状碰撞,则为 true;否则为 false。
|
||||||
|
*/
|
||||||
abstract collidesWithShape(other: Shape, collisionResult: Out<CollisionResult>): boolean;
|
abstract collidesWithShape(other: Shape, collisionResult: Out<CollisionResult>): boolean;
|
||||||
|
/**
|
||||||
|
* 确定形状是否与线段相交。
|
||||||
|
* @param {Vector2} start - 线段的起点。
|
||||||
|
* @param {Vector2} end - 线段的终点。
|
||||||
|
* @param {Out<RaycastHit>} hit - 如果形状与线段相交,则要填充的射线命中结果对象。
|
||||||
|
* @returns {boolean} 如果形状与线段相交,则为 true;否则为 false。
|
||||||
|
*/
|
||||||
abstract collidesWithLine(start: Vector2, end: Vector2, hit: Out<RaycastHit>): boolean;
|
abstract collidesWithLine(start: Vector2, end: Vector2, hit: Out<RaycastHit>): boolean;
|
||||||
|
/**
|
||||||
|
* 确定形状是否包含一个点。
|
||||||
|
* @param {Vector2} point - 要检查包含的点。
|
||||||
|
*/
|
||||||
abstract containsPoint(point: Vector2): any;
|
abstract containsPoint(point: Vector2): any;
|
||||||
|
/**
|
||||||
|
* 确定一个点是否与形状相交。
|
||||||
|
* @param {Vector2} point - 要检查与形状相交的点。
|
||||||
|
* @param {Out<CollisionResult>} result - 如果点与形状相交,则要填充的碰撞结果对象。
|
||||||
|
* @returns {boolean} 如果点与形状相交,则为 true;否则为 false。
|
||||||
|
*/
|
||||||
abstract pointCollidesWithShape(point: Vector2, result: Out<CollisionResult>): boolean;
|
abstract pointCollidesWithShape(point: Vector2, result: Out<CollisionResult>): boolean;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4184,8 +4218,8 @@ declare module es {
|
|||||||
reset(): void;
|
reset(): void;
|
||||||
cloneTo(cr: CollisionResult): void;
|
cloneTo(cr: CollisionResult): void;
|
||||||
/**
|
/**
|
||||||
* 改变最小平移向量,如果没有相同方向上的运动,它将移除平移的x分量。
|
* 从移动向量中移除水平方向的位移,以确保形状只沿垂直方向运动。如果移动向量包含水平移动,则通过计算垂直位移来修复响应距离。
|
||||||
* @param deltaMovement
|
* @param deltaMovement - 移动向量
|
||||||
*/
|
*/
|
||||||
removeHorizontalTranslation(deltaMovement: Vector2): void;
|
removeHorizontalTranslation(deltaMovement: Vector2): void;
|
||||||
invertResult(): void;
|
invertResult(): void;
|
||||||
@@ -4222,20 +4256,30 @@ declare module es {
|
|||||||
}
|
}
|
||||||
declare module es {
|
declare module es {
|
||||||
class RealtimeCollisions {
|
class RealtimeCollisions {
|
||||||
|
/**
|
||||||
|
* 判断移动的圆是否与矩形相交,并返回相撞的时间。
|
||||||
|
* @param s 移动的圆
|
||||||
|
* @param b 矩形
|
||||||
|
* @param movement 移动的向量
|
||||||
|
* @param time 时间
|
||||||
|
* @returns 是否相撞
|
||||||
|
*/
|
||||||
static intersectMovingCircleBox(s: Circle, b: Box, movement: Vector2, time: number): boolean;
|
static intersectMovingCircleBox(s: Circle, b: Box, movement: Vector2, time: number): boolean;
|
||||||
/**
|
/**
|
||||||
* 支持函数,返回索引为n的矩形vert
|
* 返回矩形的第n个角的坐标。
|
||||||
* @param b
|
* @param b 矩形
|
||||||
* @param n
|
* @param n 第n个角的编号
|
||||||
|
* @returns 第n个角的坐标
|
||||||
*/
|
*/
|
||||||
static corner(b: Rectangle, n: number): Vector2;
|
static corner(b: Rectangle, n: number): es.Vector2;
|
||||||
/**
|
/**
|
||||||
* 检查圆是否与方框重叠,并返回point交点
|
* 测试一个圆和一个矩形是否相交,并返回是否相交。
|
||||||
* @param cirlce
|
* @param circle 圆
|
||||||
* @param box
|
* @param box 矩形
|
||||||
* @param point
|
* @param point 离圆心最近的点
|
||||||
|
* @returns 是否相交
|
||||||
*/
|
*/
|
||||||
static testCircleBox(cirlce: Circle, box: Box, point: Vector2): boolean;
|
static testCircleBox(circle: Circle, box: Box, point: Vector2): boolean;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
declare module es {
|
declare module es {
|
||||||
@@ -4255,8 +4299,8 @@ declare module es {
|
|||||||
readonly sectorAngle: number;
|
readonly sectorAngle: number;
|
||||||
constructor(center: Vector2, radius: number, startAngle: number, endAngle: number);
|
constructor(center: Vector2, radius: number, startAngle: number, endAngle: number);
|
||||||
/**
|
/**
|
||||||
* 扇形的圆心和半径计算出扇形的重心
|
* 获取圆弧的质心。
|
||||||
* @returns
|
* @returns 圆弧的质心
|
||||||
*/
|
*/
|
||||||
getCentroid(): Vector2;
|
getCentroid(): Vector2;
|
||||||
/**
|
/**
|
||||||
|
|||||||
+169
-135
@@ -7990,7 +7990,7 @@ var es;
|
|||||||
Matrix2D.prototype.mutiplyTranslation = function (x, y) {
|
Matrix2D.prototype.mutiplyTranslation = function (x, y) {
|
||||||
var trans = new Matrix2D();
|
var trans = new Matrix2D();
|
||||||
Matrix2D.createTranslation(x, y, trans);
|
Matrix2D.createTranslation(x, y, trans);
|
||||||
return es.MatrixHelper.mutiply(this, trans);
|
return es.MatrixHelper.multiply(this, trans);
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* 比较当前实例是否等于指定的Matrix2D
|
* 比较当前实例是否等于指定的Matrix2D
|
||||||
@@ -8032,57 +8032,64 @@ var es;
|
|||||||
function MatrixHelper() {
|
function MatrixHelper() {
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 创建一个新的Matrix2D,其中包含两个矩阵的和
|
* 该静态方法用于计算两个 Matrix2D 对象的和。
|
||||||
* @param matrix1
|
* @param {Matrix2D} matrix1 - 加数矩阵。
|
||||||
* @param matrix2
|
* @param {Matrix2D} matrix2 - 加数矩阵。
|
||||||
|
* @returns {Matrix2D} - 计算结果的 Matrix2D 对象。
|
||||||
*/
|
*/
|
||||||
MatrixHelper.add = function (matrix1, matrix2) {
|
MatrixHelper.add = function (matrix1, matrix2) {
|
||||||
var result = es.Matrix2D.identity;
|
// 创建一个新的 Matrix2D 对象以存储计算结果。
|
||||||
|
var result = new es.Matrix2D();
|
||||||
|
// 计算两个矩阵的和。
|
||||||
result.m11 = matrix1.m11 + matrix2.m11;
|
result.m11 = matrix1.m11 + matrix2.m11;
|
||||||
result.m12 = matrix1.m12 + matrix2.m12;
|
result.m12 = matrix1.m12 + matrix2.m12;
|
||||||
result.m21 = matrix1.m21 + matrix2.m21;
|
result.m21 = matrix1.m21 + matrix2.m21;
|
||||||
result.m22 = matrix1.m22 + matrix2.m22;
|
result.m22 = matrix1.m22 + matrix2.m22;
|
||||||
result.m31 = matrix1.m31 + matrix2.m31;
|
result.m31 = matrix1.m31 + matrix2.m31;
|
||||||
result.m32 = matrix1.m32 + matrix2.m32;
|
result.m32 = matrix1.m32 + matrix2.m32;
|
||||||
|
// 返回计算结果的 Matrix2D 对象。
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* 将一个Matrix2D的元素除以另一个矩阵的元素
|
* 该静态方法用于计算两个 Matrix2D 对象的商。
|
||||||
* @param matrix1
|
* @param {Matrix2D} matrix1 - 被除数矩阵。
|
||||||
* @param matrix2
|
* @param {Matrix2D} matrix2 - 除数矩阵。
|
||||||
|
* @returns {Matrix2D} - 计算结果的 Matrix2D 对象。
|
||||||
*/
|
*/
|
||||||
MatrixHelper.divide = function (matrix1, matrix2) {
|
MatrixHelper.divide = function (matrix1, matrix2) {
|
||||||
var result = es.Matrix2D.identity;
|
// 创建一个新的 Matrix2D 对象以存储计算结果。
|
||||||
|
var result = new es.Matrix2D();
|
||||||
|
// 计算两个矩阵的商。
|
||||||
result.m11 = matrix1.m11 / matrix2.m11;
|
result.m11 = matrix1.m11 / matrix2.m11;
|
||||||
result.m12 = matrix1.m12 / matrix2.m12;
|
result.m12 = matrix1.m12 / matrix2.m12;
|
||||||
result.m21 = matrix1.m21 / matrix2.m21;
|
result.m21 = matrix1.m21 / matrix2.m21;
|
||||||
result.m22 = matrix1.m22 / matrix2.m22;
|
result.m22 = matrix1.m22 / matrix2.m22;
|
||||||
result.m31 = matrix1.m31 / matrix2.m31;
|
result.m31 = matrix1.m31 / matrix2.m31;
|
||||||
result.m32 = matrix1.m32 / matrix2.m32;
|
result.m32 = matrix1.m32 / matrix2.m32;
|
||||||
|
// 返回计算结果的 Matrix2D 对象。
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* 创建一个新的Matrix2D,包含两个矩阵的乘法
|
* 该静态方法用于计算两个 Matrix2D 对象或一个 Matrix2D 对象和一个数字的乘积。
|
||||||
* @param matrix1
|
* @param {Matrix2D} matrix1 - 第一个矩阵。
|
||||||
* @param matrix2
|
* @param {Matrix2D | number} matrix2 - 第二个矩阵或一个数字。
|
||||||
|
* @returns {Matrix2D} - 计算结果的 Matrix2D 对象。
|
||||||
*/
|
*/
|
||||||
MatrixHelper.mutiply = function (matrix1, matrix2) {
|
MatrixHelper.multiply = function (matrix1, matrix2) {
|
||||||
var result = es.Matrix2D.identity;
|
// 创建一个新的 Matrix2D 对象以存储计算结果。
|
||||||
|
var result = new es.Matrix2D();
|
||||||
|
// 根据第二个参数的类型执行不同的计算。
|
||||||
if (matrix2 instanceof es.Matrix2D) {
|
if (matrix2 instanceof es.Matrix2D) {
|
||||||
var m11 = (matrix1.m11 * matrix2.m11) + (matrix1.m12 * matrix2.m21);
|
// 执行矩阵乘法。
|
||||||
var m12 = (matrix2.m11 * matrix2.m12) + (matrix1.m12 * matrix2.m22);
|
result.m11 = matrix1.m11 * matrix2.m11 + matrix1.m12 * matrix2.m21;
|
||||||
var m21 = (matrix1.m21 * matrix2.m11) + (matrix1.m22 * matrix2.m21);
|
result.m12 = matrix1.m11 * matrix2.m12 + matrix1.m12 * matrix2.m22;
|
||||||
var m22 = (matrix1.m21 * matrix2.m12) + (matrix1.m22 * matrix2.m22);
|
result.m21 = matrix1.m21 * matrix2.m11 + matrix1.m22 * matrix2.m21;
|
||||||
var m31 = (matrix1.m31 * matrix2.m11) + (matrix1.m32 * matrix2.m21) + matrix2.m31;
|
result.m22 = matrix1.m21 * matrix2.m12 + matrix1.m22 * matrix2.m22;
|
||||||
var m32 = (matrix1.m31 * matrix2.m12) + (matrix1.m32 * matrix2.m22) + matrix2.m32;
|
result.m31 = matrix1.m31 * matrix2.m11 + matrix1.m32 * matrix2.m21 + matrix2.m31;
|
||||||
result.m11 = m11;
|
result.m32 = matrix1.m31 * matrix2.m12 + matrix1.m32 * matrix2.m22 + matrix2.m32;
|
||||||
result.m12 = m12;
|
|
||||||
result.m21 = m21;
|
|
||||||
result.m22 = m22;
|
|
||||||
result.m31 = m31;
|
|
||||||
result.m32 = m32;
|
|
||||||
}
|
}
|
||||||
else if (typeof matrix2 == "number") {
|
else {
|
||||||
|
// 执行矩阵和标量的乘法。
|
||||||
result.m11 = matrix1.m11 * matrix2;
|
result.m11 = matrix1.m11 * matrix2;
|
||||||
result.m12 = matrix1.m12 * matrix2;
|
result.m12 = matrix1.m12 * matrix2;
|
||||||
result.m21 = matrix1.m21 * matrix2;
|
result.m21 = matrix1.m21 * matrix2;
|
||||||
@@ -8090,21 +8097,26 @@ var es;
|
|||||||
result.m31 = matrix1.m31 * matrix2;
|
result.m31 = matrix1.m31 * matrix2;
|
||||||
result.m32 = matrix1.m32 * matrix2;
|
result.m32 = matrix1.m32 * matrix2;
|
||||||
}
|
}
|
||||||
|
// 返回计算结果的 Matrix2D 对象。
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* 创建一个新的Matrix2D,包含一个矩阵与另一个矩阵的减法。
|
* 该静态方法用于计算两个 Matrix2D 对象的差。
|
||||||
* @param matrix1
|
* @param {Matrix2D} matrix1 - 第一个矩阵。
|
||||||
* @param matrix2
|
* @param {Matrix2D} matrix2 - 第二个矩阵。
|
||||||
|
* @returns {Matrix2D} - 计算结果的 Matrix2D 对象。
|
||||||
*/
|
*/
|
||||||
MatrixHelper.subtract = function (matrix1, matrix2) {
|
MatrixHelper.subtract = function (matrix1, matrix2) {
|
||||||
var result = es.Matrix2D.identity;
|
// 创建一个新的 Matrix2D 对象以存储计算结果。
|
||||||
|
var result = new es.Matrix2D();
|
||||||
|
// 计算两个矩阵的差。
|
||||||
result.m11 = matrix1.m11 - matrix2.m11;
|
result.m11 = matrix1.m11 - matrix2.m11;
|
||||||
result.m12 = matrix1.m12 - matrix2.m12;
|
result.m12 = matrix1.m12 - matrix2.m12;
|
||||||
result.m21 = matrix1.m21 - matrix2.m21;
|
result.m21 = matrix1.m21 - matrix2.m21;
|
||||||
result.m22 = matrix1.m22 - matrix2.m22;
|
result.m22 = matrix1.m22 - matrix2.m22;
|
||||||
result.m31 = matrix1.m31 - matrix2.m31;
|
result.m31 = matrix1.m31 - matrix2.m31;
|
||||||
result.m32 = matrix1.m32 - matrix2.m32;
|
result.m32 = matrix1.m32 - matrix2.m32;
|
||||||
|
// 返回计算结果的 Matrix2D 对象。
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
return MatrixHelper;
|
return MatrixHelper;
|
||||||
@@ -8514,6 +8526,7 @@ var es;
|
|||||||
Rectangle.prototype.offset = function (offsetX, offsetY) {
|
Rectangle.prototype.offset = function (offsetX, offsetY) {
|
||||||
this.x += offsetX;
|
this.x += offsetX;
|
||||||
this.y += offsetY;
|
this.y += offsetY;
|
||||||
|
return this;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* 创建一个完全包含两个其他矩形的新矩形
|
* 创建一个完全包含两个其他矩形的新矩形
|
||||||
@@ -8666,30 +8679,32 @@ var es;
|
|||||||
var es;
|
var es;
|
||||||
(function (es) {
|
(function (es) {
|
||||||
/**
|
/**
|
||||||
* 它存储值,直到累计的总数大于1。一旦超过1,该值将在调用update时添加到amount中
|
* 该类用于存储具有亚像素分辨率的浮点数。
|
||||||
* 一般用法如下:
|
|
||||||
*
|
|
||||||
* let deltaMove = this.velocity * es.Time.deltaTime;
|
|
||||||
* deltaMove.x = this._x.update(deltaMove.x);
|
|
||||||
* deltaMove.y = this._y.update(deltaMove.y);
|
|
||||||
*/
|
*/
|
||||||
var SubpixelFloat = /** @class */ (function () {
|
var SubpixelFloat = /** @class */ (function () {
|
||||||
function SubpixelFloat() {
|
function SubpixelFloat() {
|
||||||
|
/**
|
||||||
|
* 存储 SubpixelFloat 值的浮点余数。
|
||||||
|
*/
|
||||||
this.remainder = 0;
|
this.remainder = 0;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 以amount递增余数,将值截断,存储新的余数并将amount设置为当前值
|
* 通过将给定数量的像素添加到余数中来更新 SubpixelFloat 值。
|
||||||
* @param amount
|
* 返回更新后的整数部分,余数表示当前值中包含的亚像素部分。
|
||||||
|
* @param {number} amount - 要添加到余数中的像素数。
|
||||||
|
* @returns {number} 更新后的整数部分。
|
||||||
*/
|
*/
|
||||||
SubpixelFloat.prototype.update = function (amount) {
|
SubpixelFloat.prototype.update = function (amount) {
|
||||||
|
// 将给定的像素数量添加到余数中
|
||||||
this.remainder += amount;
|
this.remainder += amount;
|
||||||
|
// 检查余数是否超过一个像素的大小
|
||||||
var motion = Math.trunc(this.remainder);
|
var motion = Math.trunc(this.remainder);
|
||||||
this.remainder -= motion;
|
this.remainder -= motion;
|
||||||
amount = motion;
|
// 返回整数部分作为更新后的值
|
||||||
return amount;
|
return motion;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* 将余数重置为0
|
* 将 SubpixelFloat 值重置为零。
|
||||||
*/
|
*/
|
||||||
SubpixelFloat.prototype.reset = function () {
|
SubpixelFloat.prototype.reset = function () {
|
||||||
this.remainder = 0;
|
this.remainder = 0;
|
||||||
@@ -8700,21 +8715,31 @@ var es;
|
|||||||
})(es || (es = {}));
|
})(es || (es = {}));
|
||||||
var es;
|
var es;
|
||||||
(function (es) {
|
(function (es) {
|
||||||
|
/**
|
||||||
|
* 该类用于存储具有亚像素分辨率的二维向量。
|
||||||
|
*/
|
||||||
var SubpixelVector2 = /** @class */ (function () {
|
var SubpixelVector2 = /** @class */ (function () {
|
||||||
function SubpixelVector2() {
|
function SubpixelVector2() {
|
||||||
|
/**
|
||||||
|
* 用于存储 x 坐标的 SubpixelFloat 对象。
|
||||||
|
*/
|
||||||
this._x = new es.SubpixelFloat();
|
this._x = new es.SubpixelFloat();
|
||||||
|
/**
|
||||||
|
* 用于存储 y 坐标的 SubpixelFloat 对象。
|
||||||
|
*/
|
||||||
this._y = new es.SubpixelFloat();
|
this._y = new es.SubpixelFloat();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 以数量递增s/y余数,将值截断为整数,存储新的余数并将amount设置为当前值
|
* 通过将给定数量的像素添加到余数中来更新 SubpixelVector2 值。
|
||||||
* @param amount
|
* @param {Vector2} amount - 要添加到余数中的像素向量。
|
||||||
*/
|
*/
|
||||||
SubpixelVector2.prototype.update = function (amount) {
|
SubpixelVector2.prototype.update = function (amount) {
|
||||||
|
// 更新 x 和 y 坐标
|
||||||
amount.x = this._x.update(amount.x);
|
amount.x = this._x.update(amount.x);
|
||||||
amount.y = this._y.update(amount.y);
|
amount.y = this._y.update(amount.y);
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* 将余数重置为0
|
* 将 SubpixelVector2 值的余数重置为零。
|
||||||
*/
|
*/
|
||||||
SubpixelVector2.prototype.reset = function () {
|
SubpixelVector2.prototype.reset = function () {
|
||||||
this._x.reset();
|
this._x.reset();
|
||||||
@@ -9950,47 +9975,37 @@ var es;
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
Polygon.prototype.recalculateBounds = function (collider) {
|
Polygon.prototype.recalculateBounds = function (collider) {
|
||||||
var _this = this;
|
|
||||||
// 如果我们没有旋转或不关心TRS我们使用localOffset作为中心,我们会从那开始
|
|
||||||
this.center = collider.localOffset;
|
this.center = collider.localOffset;
|
||||||
if (collider.shouldColliderScaleAndRotateWithTransform) {
|
if (collider.shouldColliderScaleAndRotateWithTransform) {
|
||||||
var hasUnitScale = true;
|
var hasUnitScale = true;
|
||||||
var tempMat = new es.Matrix2D();
|
var tempMat = new es.Matrix2D();
|
||||||
var combinedMatrix_1 = new es.Matrix2D();
|
var combinedMatrix_1 = new es.Matrix2D();
|
||||||
es.Matrix2D.createTranslation(this._polygonCenter.x * -1, this._polygonCenter.y * -1, combinedMatrix_1);
|
es.Matrix2D.createTranslation(-this._polygonCenter.x, -this._polygonCenter.y, combinedMatrix_1);
|
||||||
if (!collider.entity.transform.scale.equals(es.Vector2.one)) {
|
var scale = collider.entity.transform.scale;
|
||||||
es.Matrix2D.createScale(collider.entity.scale.x, collider.entity.scale.y, tempMat);
|
if (!scale.equals(es.Vector2.one)) {
|
||||||
|
es.Matrix2D.createScale(scale.x, scale.y, tempMat);
|
||||||
es.Matrix2D.multiply(combinedMatrix_1, tempMat, combinedMatrix_1);
|
es.Matrix2D.multiply(combinedMatrix_1, tempMat, combinedMatrix_1);
|
||||||
hasUnitScale = false;
|
hasUnitScale = false;
|
||||||
// 缩放偏移量并将其设置为中心。如果我们有旋转,它会在下面重置
|
var scaledOffset = collider.localOffset.multiply(scale);
|
||||||
var scaledOffset = new es.Vector2(collider.localOffset.x * collider.entity.scale.x, collider.localOffset.y * collider.entity.scale.y);
|
|
||||||
this.center = scaledOffset;
|
this.center = scaledOffset;
|
||||||
}
|
}
|
||||||
if (collider.entity.transform.rotation != 0) {
|
var rotation = collider.entity.transform.rotationDegrees;
|
||||||
es.Matrix2D.createRotation(es.MathHelper.Deg2Rad * collider.entity.rotation, tempMat);
|
if (rotation !== 0) {
|
||||||
|
var offsetLength = hasUnitScale ? collider._localOffsetLength : collider.localOffset.multiply(scale).magnitude();
|
||||||
|
var offsetAngle = Math.atan2(collider.localOffset.y * scale.y, collider.localOffset.x * scale.x) * es.MathHelper.Rad2Deg;
|
||||||
|
this.center = es.MathHelper.pointOnCircle(es.Vector2.zero, offsetLength, rotation + offsetAngle);
|
||||||
|
es.Matrix2D.createRotation(es.MathHelper.Deg2Rad * rotation, tempMat);
|
||||||
es.Matrix2D.multiply(combinedMatrix_1, tempMat, combinedMatrix_1);
|
es.Matrix2D.multiply(combinedMatrix_1, tempMat, combinedMatrix_1);
|
||||||
// 为了处理偏移原点的旋转我们只需要将圆心在(0,0)附近移动
|
|
||||||
// 我们的偏移使角度为0我们还需要处理这里的比例所以我们先对偏移进行缩放以得到合适的长度。
|
|
||||||
var offsetAngle = Math.atan2(collider.localOffset.y * collider.entity.transform.scale.y, collider.localOffset.x * collider.entity.transform.scale.x) * es.MathHelper.Rad2Deg;
|
|
||||||
var offsetLength = hasUnitScale ? collider._localOffsetLength :
|
|
||||||
collider.localOffset.multiply(collider.entity.transform.scale).magnitude();
|
|
||||||
this.center = es.MathHelper.pointOnCircle(es.Vector2.zero, offsetLength, collider.entity.transform.rotationDegrees + offsetAngle);
|
|
||||||
}
|
}
|
||||||
es.Matrix2D.createTranslation(this._polygonCenter.x, this._polygonCenter.y, tempMat);
|
es.Matrix2D.createTranslation(this._polygonCenter.x + collider.transform.position.x + this.center.x, this._polygonCenter.y + collider.transform.position.y + this.center.y, tempMat);
|
||||||
es.Matrix2D.multiply(combinedMatrix_1, tempMat, combinedMatrix_1);
|
es.Matrix2D.multiply(combinedMatrix_1, tempMat, combinedMatrix_1);
|
||||||
// 最后变换原始点
|
this.points = this._originalPoints.map(function (p) { return p.transform(combinedMatrix_1); });
|
||||||
this.points = [];
|
this.isUnrotated = rotation === 0;
|
||||||
this._originalPoints.forEach(function (p) {
|
|
||||||
_this.points.push(p.transform(combinedMatrix_1));
|
|
||||||
});
|
|
||||||
this.isUnrotated = collider.entity.transform.rotation == 0;
|
|
||||||
// 如果旋转的话,我们只需要重建边的法线
|
|
||||||
if (collider._isRotationDirty)
|
if (collider._isRotationDirty)
|
||||||
this._areEdgeNormalsDirty = true;
|
this._areEdgeNormalsDirty = true;
|
||||||
}
|
}
|
||||||
this.position = collider.transform.position.add(this.center);
|
this.position = collider.transform.position.add(this.center);
|
||||||
this.bounds = es.Rectangle.rectEncompassingPoints(this.points);
|
this.bounds = es.Rectangle.rectEncompassingPoints(this.points).offset(this.position.x, this.position.y);
|
||||||
this.bounds.location = this.bounds.location.add(this.position);
|
|
||||||
};
|
};
|
||||||
Polygon.prototype.overlaps = function (other) {
|
Polygon.prototype.overlaps = function (other) {
|
||||||
var result = new es.Out();
|
var result = new es.Out();
|
||||||
@@ -10132,25 +10147,26 @@ var es;
|
|||||||
return _super.prototype.pointCollidesWithShape.call(this, point, result);
|
return _super.prototype.pointCollidesWithShape.call(this, point, result);
|
||||||
};
|
};
|
||||||
Box.prototype.getFurthestPoint = function (normal) {
|
Box.prototype.getFurthestPoint = function (normal) {
|
||||||
var furthestPoint = new es.Vector2(this.width / 2, this.height / 2);
|
var halfWidth = this.width / 2;
|
||||||
|
var halfHeight = this.height / 2;
|
||||||
|
var furthestPoint = new es.Vector2(halfWidth, halfHeight);
|
||||||
var dotProduct = furthestPoint.dot(normal);
|
var dotProduct = furthestPoint.dot(normal);
|
||||||
var tempPoint = new es.Vector2(-this.width / 2, this.height / 2);
|
var tempPoint = new es.Vector2(-halfWidth, halfHeight);
|
||||||
var tempDotProduct = tempPoint.dot(normal);
|
var tempDotProduct = tempPoint.dot(normal);
|
||||||
if (tempDotProduct > dotProduct) {
|
if (tempDotProduct > dotProduct) {
|
||||||
furthestPoint.copyFrom(tempPoint);
|
furthestPoint.copyFrom(tempPoint);
|
||||||
dotProduct = tempDotProduct;
|
dotProduct = tempDotProduct;
|
||||||
}
|
}
|
||||||
tempPoint.setTo(-this.width / 2, -this.height / 2);
|
tempPoint.setTo(-halfWidth, -halfHeight);
|
||||||
tempDotProduct = tempPoint.dot(normal);
|
tempDotProduct = tempPoint.dot(normal);
|
||||||
if (tempDotProduct > dotProduct) {
|
if (tempDotProduct > dotProduct) {
|
||||||
furthestPoint.copyFrom(tempPoint);
|
furthestPoint.copyFrom(tempPoint);
|
||||||
dotProduct = tempDotProduct;
|
dotProduct = tempDotProduct;
|
||||||
}
|
}
|
||||||
tempPoint.setTo(this.width / 2, -this.height / 2);
|
tempPoint.setTo(halfWidth, -halfHeight);
|
||||||
tempDotProduct = tempPoint.dot(normal);
|
tempDotProduct = tempPoint.dot(normal);
|
||||||
if (tempDotProduct > dotProduct) {
|
if (tempDotProduct > dotProduct) {
|
||||||
furthestPoint.copyFrom(tempPoint);
|
furthestPoint.copyFrom(tempPoint);
|
||||||
dotProduct = tempDotProduct;
|
|
||||||
}
|
}
|
||||||
return furthestPoint;
|
return furthestPoint;
|
||||||
};
|
};
|
||||||
@@ -10268,15 +10284,17 @@ var es;
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* 改变最小平移向量,如果没有相同方向上的运动,它将移除平移的x分量。
|
* 从移动向量中移除水平方向的位移,以确保形状只沿垂直方向运动。如果移动向量包含水平移动,则通过计算垂直位移来修复响应距离。
|
||||||
* @param deltaMovement
|
* @param deltaMovement - 移动向量
|
||||||
*/
|
*/
|
||||||
CollisionResult.prototype.removeHorizontalTranslation = function (deltaMovement) {
|
CollisionResult.prototype.removeHorizontalTranslation = function (deltaMovement) {
|
||||||
// 检查是否需要横向移动,如果需要,移除并固定响应
|
// 如果运动方向和法线方向不在同一方向或者移动量为0且法线方向不为0,则需要修复
|
||||||
if (Math.sign(this.normal.x) !== Math.sign(deltaMovement.x) || (deltaMovement.x === 0 && this.normal.x !== 0)) {
|
if (Math.sign(this.normal.x) !== Math.sign(deltaMovement.x) || (deltaMovement.x === 0 && this.normal.x !== 0)) {
|
||||||
|
// 获取响应距离
|
||||||
var responseDistance = this.minimumTranslationVector.magnitude();
|
var responseDistance = this.minimumTranslationVector.magnitude();
|
||||||
|
// 计算需要修复的位移
|
||||||
var fix = responseDistance / this.normal.y;
|
var fix = responseDistance / this.normal.y;
|
||||||
// 检查一些边界情况。因为我们除以法线 使得x == 1和一个非常小的y这将导致一个巨大的固定值
|
// 如果法线方向不是完全水平或垂直,并且修复距离小于移动向量的3倍,则修复距离
|
||||||
if (Math.abs(this.normal.x) != 1 && Math.abs(fix) < Math.abs(deltaMovement.y * 3)) {
|
if (Math.abs(this.normal.x) != 1 && Math.abs(fix) < Math.abs(deltaMovement.y * 3)) {
|
||||||
this.minimumTranslationVector = new es.Vector2(0, -fix);
|
this.minimumTranslationVector = new es.Vector2(0, -fix);
|
||||||
}
|
}
|
||||||
@@ -10385,27 +10403,35 @@ var es;
|
|||||||
var RealtimeCollisions = /** @class */ (function () {
|
var RealtimeCollisions = /** @class */ (function () {
|
||||||
function RealtimeCollisions() {
|
function RealtimeCollisions() {
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 判断移动的圆是否与矩形相交,并返回相撞的时间。
|
||||||
|
* @param s 移动的圆
|
||||||
|
* @param b 矩形
|
||||||
|
* @param movement 移动的向量
|
||||||
|
* @param time 时间
|
||||||
|
* @returns 是否相撞
|
||||||
|
*/
|
||||||
RealtimeCollisions.intersectMovingCircleBox = function (s, b, movement, time) {
|
RealtimeCollisions.intersectMovingCircleBox = function (s, b, movement, time) {
|
||||||
// 计算将b按球面半径r扩大后的AABB
|
// 计算将b按球面半径r扩大后的AABB
|
||||||
var e = b.bounds;
|
var e = b.bounds;
|
||||||
e.inflate(s.radius, s.radius);
|
e.inflate(s.radius, s.radius);
|
||||||
// 将射线与展开的矩形e相交,如果射线错过了e,则以无交点退出,否则得到交点p和时间t作为结果。
|
// 将射线与展开的矩形e相交,如果射线错过了e,则以无交点退出,否则得到交点p和时间t作为结果。
|
||||||
var ray = new es.Ray2D(s.position.sub(movement), s.position);
|
var ray = new es.Ray2D(s.position.sub(movement), s.position); // 创建射线,将移动后的圆心作为起点
|
||||||
var res = e.rayIntersects(ray);
|
var res = e.rayIntersects(ray); // 判断射线与展开的矩形是否相交
|
||||||
if (!res.intersected && res.distance > 1)
|
if (!res.intersected && res.distance > 1)
|
||||||
return false;
|
return false; // 如果没有相交且距离大于1,则无法相撞
|
||||||
// 求交点
|
// 求交点
|
||||||
var point = ray.start.add(ray.direction.scale(time));
|
var point = ray.start.add(ray.direction.scale(time));
|
||||||
// 计算交点p位于b的哪个最小面和最大面之外。注意,u和v不能有相同的位集,它们之间必须至少有一个位集。
|
// 计算交点p位于b的哪个最小面和最大面之外。注意,u和v不能有相同的位集,它们之间必须至少有一个位集。
|
||||||
var u, v = 0;
|
var u, v = 0;
|
||||||
if (point.x < b.bounds.left)
|
if (point.x < b.bounds.left)
|
||||||
u |= 1;
|
u |= 1; // 如果交点在最小的x面的左边,将第一位设为1
|
||||||
if (point.x > b.bounds.right)
|
if (point.x > b.bounds.right)
|
||||||
v |= 1;
|
v |= 1; // 如果交点在最大的x面的右边,将第一位设为1
|
||||||
if (point.y < b.bounds.top)
|
if (point.y < b.bounds.top)
|
||||||
u |= 2;
|
u |= 2; // 如果交点在最小的y面的上面,将第二位设为1
|
||||||
if (point.y > b.bounds.bottom)
|
if (point.y > b.bounds.bottom)
|
||||||
v |= 2;
|
v |= 2; // 如果交点在最大的y面的下面,将第二位设为1
|
||||||
// 'or'将所有的比特集合在一起,形成一个比特掩码(注意u + v == u | v)
|
// 'or'将所有的比特集合在一起,形成一个比特掩码(注意u + v == u | v)
|
||||||
var m = u + v;
|
var m = u + v;
|
||||||
// 如果这3个比特都被设置,那么该点就在顶点区域内。
|
// 如果这3个比特都被设置,那么该点就在顶点区域内。
|
||||||
@@ -10422,29 +10448,31 @@ var es;
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* 支持函数,返回索引为n的矩形vert
|
* 返回矩形的第n个角的坐标。
|
||||||
* @param b
|
* @param b 矩形
|
||||||
* @param n
|
* @param n 第n个角的编号
|
||||||
|
* @returns 第n个角的坐标
|
||||||
*/
|
*/
|
||||||
RealtimeCollisions.corner = function (b, n) {
|
RealtimeCollisions.corner = function (b, n) {
|
||||||
var p = es.Vector2.zero;
|
var p = es.Vector2.zero;
|
||||||
p.x = (n & 1) == 0 ? b.right : b.left;
|
p.x = (n & 1) === 0 ? b.right : b.left;
|
||||||
p.y = (n & 1) == 0 ? b.bottom : b.top;
|
p.y = (n & 1) === 0 ? b.bottom : b.top;
|
||||||
return p;
|
return p;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* 检查圆是否与方框重叠,并返回point交点
|
* 测试一个圆和一个矩形是否相交,并返回是否相交。
|
||||||
* @param cirlce
|
* @param circle 圆
|
||||||
* @param box
|
* @param box 矩形
|
||||||
* @param point
|
* @param point 离圆心最近的点
|
||||||
|
* @returns 是否相交
|
||||||
*/
|
*/
|
||||||
RealtimeCollisions.testCircleBox = function (cirlce, box, point) {
|
RealtimeCollisions.testCircleBox = function (circle, box, point) {
|
||||||
// 找出离球心最近的点
|
// 找出离圆心最近的点
|
||||||
point = box.bounds.getClosestPointOnRectangleToPoint(cirlce.position);
|
point = box.bounds.getClosestPointOnRectangleToPoint(circle.position);
|
||||||
// 圆和方块相交,如果圆心到点的距离小于圆的半径,则圆和方块相交
|
// 如果圆心到点的距离小于等于圆的半径,则圆和方块相交
|
||||||
var v = point.sub(cirlce.position);
|
var v = point.sub(circle.position);
|
||||||
var dist = v.dot(v);
|
var dist = v.dot(v);
|
||||||
return dist <= cirlce.radius * cirlce.radius;
|
return dist <= circle.radius * circle.radius;
|
||||||
};
|
};
|
||||||
return RealtimeCollisions;
|
return RealtimeCollisions;
|
||||||
}());
|
}());
|
||||||
@@ -10480,12 +10508,14 @@ var es;
|
|||||||
configurable: true
|
configurable: true
|
||||||
});
|
});
|
||||||
/**
|
/**
|
||||||
* 扇形的圆心和半径计算出扇形的重心
|
* 获取圆弧的质心。
|
||||||
* @returns
|
* @returns 圆弧的质心
|
||||||
*/
|
*/
|
||||||
Sector.prototype.getCentroid = function () {
|
Sector.prototype.getCentroid = function () {
|
||||||
|
// 计算圆弧的质心坐标
|
||||||
var x = (Math.cos(this.startAngle) + Math.cos(this.endAngle)) * this.radius / 3;
|
var x = (Math.cos(this.startAngle) + Math.cos(this.endAngle)) * this.radius / 3;
|
||||||
var y = (Math.sin(this.startAngle) + Math.sin(this.endAngle)) * this.radius / 3;
|
var y = (Math.sin(this.startAngle) + Math.sin(this.endAngle)) * this.radius / 3;
|
||||||
|
// 返回质心坐标
|
||||||
return new es.Vector2(x + this.center.x, y + this.center.y);
|
return new es.Vector2(x + this.center.x, y + this.center.y);
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
@@ -10531,53 +10561,57 @@ var es;
|
|||||||
throw new Error("overlaps of Polygon to " + other + " are not supported");
|
throw new Error("overlaps of Polygon to " + other + " are not supported");
|
||||||
};
|
};
|
||||||
Sector.prototype.collidesWithLine = function (start, end, hit) {
|
Sector.prototype.collidesWithLine = function (start, end, hit) {
|
||||||
var toStart = start.sub(this.center);
|
var toStart = start.sub(this.center); // 线段起点到圆心的向量
|
||||||
var toEnd = end.sub(this.center);
|
var toEnd = end.sub(this.center); // 线段终点到圆心的向量
|
||||||
var angleStart = toStart.getAngle();
|
var angleStart = toStart.getAngle(); // 起点向量与 x 轴正方向的夹角
|
||||||
var angleEnd = toEnd.getAngle();
|
var angleEnd = toEnd.getAngle(); // 终点向量与 x 轴正方向的夹角
|
||||||
var angleDiff = angleEnd - angleStart;
|
var angleDiff = angleEnd - angleStart; // 终点角度减去起点角度得到角度差
|
||||||
|
// 将角度差限制在 -PI 到 PI 之间,方便判断是否跨越了 0 度
|
||||||
if (angleDiff > Math.PI) {
|
if (angleDiff > Math.PI) {
|
||||||
angleDiff -= 2 * Math.PI;
|
angleDiff -= 2 * Math.PI;
|
||||||
}
|
}
|
||||||
else if (angleDiff < -Math.PI) {
|
else if (angleDiff < -Math.PI) {
|
||||||
angleDiff += 2 * Math.PI;
|
angleDiff += 2 * Math.PI;
|
||||||
}
|
}
|
||||||
|
// 如果角度差在圆弧的起始角度和结束角度之间,则有可能发生相交
|
||||||
if (angleDiff >= this.startAngle && angleDiff <= this.endAngle) {
|
if (angleDiff >= this.startAngle && angleDiff <= this.endAngle) {
|
||||||
var r = toStart.getLength();
|
var r = toStart.getLength(); // 圆心到线段起点的距离
|
||||||
var t = this.startAngle - angleStart;
|
var t = this.startAngle - angleStart; // 起点角度到圆弧起始角度的角度差
|
||||||
var x = r * Math.cos(t);
|
var x = r * Math.cos(t); // 圆弧上与线段相交的点的 x 坐标
|
||||||
var y = r * Math.sin(t);
|
var y = r * Math.sin(t); // 圆弧上与线段相交的点的 y 坐标
|
||||||
var intersection = new es.Vector2(x, y);
|
var intersection = new es.Vector2(x, y); // 相交点的二维坐标
|
||||||
|
// 判断相交点是否在线段上
|
||||||
if (intersection.isBetween(start, end)) {
|
if (intersection.isBetween(start, end)) {
|
||||||
var distance = intersection.sub(start).getLength();
|
var distance = intersection.sub(start).getLength(); // 相交点到线段起点的距离
|
||||||
var fraction = distance / start.getDistance(end);
|
var fraction = distance / start.getDistance(end); // 相交点处于线段的分数
|
||||||
var normal = intersection.sub(this.center).normalize();
|
var normal = intersection.sub(this.center).normalize(); // 相交点处圆弧的法向量
|
||||||
var point = intersection.add(this.center);
|
var point = intersection.add(this.center); // 相交点的全局坐标
|
||||||
|
// 将相交信息存储到 hit 参数中
|
||||||
var raycastHit = new es.RaycastHit();
|
var raycastHit = new es.RaycastHit();
|
||||||
raycastHit.setValues(fraction, distance, point, normal);
|
raycastHit.setValues(fraction, distance, point, normal);
|
||||||
hit.value = raycastHit;
|
hit.value = raycastHit;
|
||||||
return true;
|
return true; // 返回 true 表示相交
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false; // 返回 false 表示不相交
|
||||||
};
|
};
|
||||||
Sector.prototype.containsPoint = function (point) {
|
Sector.prototype.containsPoint = function (point) {
|
||||||
var toPoint = point.sub(this.center);
|
var toPoint = point.sub(this.center); // 点到圆心的向量
|
||||||
var distanceSquared = toPoint.lengthSquared();
|
var distanceSquared = toPoint.lengthSquared(); // 点到圆心距离的平方
|
||||||
if (distanceSquared > this.radiusSquared) {
|
if (distanceSquared > this.radiusSquared) { // 如果点到圆心的距离平方大于圆形区域半径平方,则该点不在圆形区域内
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var angle = toPoint.getAngle();
|
var angle = toPoint.getAngle(); // 点到圆心的向量与 x 轴正方向的夹角
|
||||||
var startAngle = this.startAngle;
|
var startAngle = this.startAngle; // 圆弧起始角度
|
||||||
var endAngle = startAngle + this.angle;
|
var endAngle = startAngle + this.angle; // 圆弧终止角度
|
||||||
var angleDiff = angle - startAngle;
|
var angleDiff = angle - startAngle; // 计算点到圆弧起始角度的角度差
|
||||||
if (angleDiff < 0) {
|
if (angleDiff < 0) { // 如果角度差小于 0,则说明点在圆弧角度的另一侧,需要加上 2 * PI
|
||||||
angleDiff += Math.PI * 2;
|
angleDiff += Math.PI * 2;
|
||||||
}
|
}
|
||||||
if (angleDiff > this.angle) {
|
if (angleDiff > this.angle) { // 如果角度差大于圆弧角度,则该点不在圆弧范围内
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true; // 点在圆形区域内
|
||||||
};
|
};
|
||||||
Sector.prototype.pointCollidesWithShape = function (point, result) {
|
Sector.prototype.pointCollidesWithShape = function (point, result) {
|
||||||
if (!this.containsPoint(point)) {
|
if (!this.containsPoint(point)) {
|
||||||
@@ -10607,16 +10641,16 @@ var es;
|
|||||||
this.angleStep = (this.endAngle - this.startAngle) / (this.numberOfPoints - 1);
|
this.angleStep = (this.endAngle - this.startAngle) / (this.numberOfPoints - 1);
|
||||||
};
|
};
|
||||||
Sector.prototype.getFurthestPoint = function (normal) {
|
Sector.prototype.getFurthestPoint = function (normal) {
|
||||||
var maxProjection = -Number.MAX_VALUE;
|
var maxProjection = -Number.MAX_VALUE; // 最大投影值
|
||||||
var furthestPoint = new es.Vector2();
|
var furthestPoint = new es.Vector2(); // 最远点
|
||||||
for (var i = 0; i < this.numberOfPoints; i++) {
|
for (var i = 0; i < this.numberOfPoints; i++) { // 遍历多边形的所有顶点
|
||||||
var projection = this.points[i].dot(normal);
|
var projection = this.points[i].dot(normal); // 计算当前顶点到法线的投影
|
||||||
if (projection > maxProjection) {
|
if (projection > maxProjection) { // 如果当前投影值大于最大投影值,则更新最大投影值和最远点
|
||||||
maxProjection = projection;
|
maxProjection = projection;
|
||||||
furthestPoint.copyFrom(this.points[i]);
|
furthestPoint.copyFrom(this.points[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return furthestPoint;
|
return furthestPoint; // 返回最远点
|
||||||
};
|
};
|
||||||
return Sector;
|
return Sector;
|
||||||
}(es.Shape));
|
}(es.Shape));
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -311,7 +311,7 @@ module es {
|
|||||||
public mutiplyTranslation(x: number, y: number) {
|
public mutiplyTranslation(x: number, y: number) {
|
||||||
let trans = new Matrix2D();
|
let trans = new Matrix2D();
|
||||||
Matrix2D.createTranslation(x, y, trans);
|
Matrix2D.createTranslation(x, y, trans);
|
||||||
return MatrixHelper.mutiply(this, trans);
|
return MatrixHelper.multiply(this, trans);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,32 +1,38 @@
|
|||||||
module es {
|
module es {
|
||||||
export class MatrixHelper {
|
export class MatrixHelper {
|
||||||
/**
|
/**
|
||||||
* 创建一个新的Matrix2D,其中包含两个矩阵的和
|
* 该静态方法用于计算两个 Matrix2D 对象的和。
|
||||||
* @param matrix1
|
* @param {Matrix2D} matrix1 - 加数矩阵。
|
||||||
* @param matrix2
|
* @param {Matrix2D} matrix2 - 加数矩阵。
|
||||||
|
* @returns {Matrix2D} - 计算结果的 Matrix2D 对象。
|
||||||
*/
|
*/
|
||||||
public static add(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D {
|
public static add(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D {
|
||||||
let result = Matrix2D.identity;
|
// 创建一个新的 Matrix2D 对象以存储计算结果。
|
||||||
|
const result = new Matrix2D();
|
||||||
|
|
||||||
|
// 计算两个矩阵的和。
|
||||||
result.m11 = matrix1.m11 + matrix2.m11;
|
result.m11 = matrix1.m11 + matrix2.m11;
|
||||||
result.m12 = matrix1.m12 + matrix2.m12;
|
result.m12 = matrix1.m12 + matrix2.m12;
|
||||||
|
|
||||||
result.m21 = matrix1.m21 + matrix2.m21;
|
result.m21 = matrix1.m21 + matrix2.m21;
|
||||||
result.m22 = matrix1.m22 + matrix2.m22;
|
result.m22 = matrix1.m22 + matrix2.m22;
|
||||||
|
|
||||||
result.m31 = matrix1.m31 + matrix2.m31;
|
result.m31 = matrix1.m31 + matrix2.m31;
|
||||||
result.m32 = matrix1.m32 + matrix2.m32;
|
result.m32 = matrix1.m32 + matrix2.m32;
|
||||||
|
|
||||||
|
// 返回计算结果的 Matrix2D 对象。
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将一个Matrix2D的元素除以另一个矩阵的元素
|
* 该静态方法用于计算两个 Matrix2D 对象的商。
|
||||||
* @param matrix1
|
* @param {Matrix2D} matrix1 - 被除数矩阵。
|
||||||
* @param matrix2
|
* @param {Matrix2D} matrix2 - 除数矩阵。
|
||||||
|
* @returns {Matrix2D} - 计算结果的 Matrix2D 对象。
|
||||||
*/
|
*/
|
||||||
public static divide(matrix1: Matrix2D, matrix2: Matrix2D) {
|
public static divide(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D {
|
||||||
let result = Matrix2D.identity;
|
// 创建一个新的 Matrix2D 对象以存储计算结果。
|
||||||
|
const result = new Matrix2D();
|
||||||
|
|
||||||
|
// 计算两个矩阵的商。
|
||||||
result.m11 = matrix1.m11 / matrix2.m11;
|
result.m11 = matrix1.m11 / matrix2.m11;
|
||||||
result.m12 = matrix1.m12 / matrix2.m12;
|
result.m12 = matrix1.m12 / matrix2.m12;
|
||||||
result.m21 = matrix1.m21 / matrix2.m21;
|
result.m21 = matrix1.m21 / matrix2.m21;
|
||||||
@@ -34,65 +40,62 @@ module es {
|
|||||||
result.m31 = matrix1.m31 / matrix2.m31;
|
result.m31 = matrix1.m31 / matrix2.m31;
|
||||||
result.m32 = matrix1.m32 / matrix2.m32;
|
result.m32 = matrix1.m32 / matrix2.m32;
|
||||||
|
|
||||||
|
// 返回计算结果的 Matrix2D 对象。
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建一个新的Matrix2D,包含两个矩阵的乘法
|
* 该静态方法用于计算两个 Matrix2D 对象或一个 Matrix2D 对象和一个数字的乘积。
|
||||||
* @param matrix1
|
* @param {Matrix2D} matrix1 - 第一个矩阵。
|
||||||
* @param matrix2
|
* @param {Matrix2D | number} matrix2 - 第二个矩阵或一个数字。
|
||||||
|
* @returns {Matrix2D} - 计算结果的 Matrix2D 对象。
|
||||||
*/
|
*/
|
||||||
public static mutiply(matrix1: Matrix2D, matrix2: Matrix2D | number) {
|
public static multiply(matrix1: Matrix2D, matrix2: Matrix2D | number): Matrix2D {
|
||||||
let result = Matrix2D.identity;
|
// 创建一个新的 Matrix2D 对象以存储计算结果。
|
||||||
|
const result = new Matrix2D();
|
||||||
|
|
||||||
|
// 根据第二个参数的类型执行不同的计算。
|
||||||
if (matrix2 instanceof Matrix2D) {
|
if (matrix2 instanceof Matrix2D) {
|
||||||
let m11 = (matrix1.m11 * matrix2.m11) + (matrix1.m12 * matrix2.m21);
|
// 执行矩阵乘法。
|
||||||
let m12 = (matrix2.m11 * matrix2.m12) + (matrix1.m12 * matrix2.m22);
|
result.m11 = matrix1.m11 * matrix2.m11 + matrix1.m12 * matrix2.m21;
|
||||||
|
result.m12 = matrix1.m11 * matrix2.m12 + matrix1.m12 * matrix2.m22;
|
||||||
let m21 = (matrix1.m21 * matrix2.m11) + (matrix1.m22 * matrix2.m21);
|
result.m21 = matrix1.m21 * matrix2.m11 + matrix1.m22 * matrix2.m21;
|
||||||
let m22 = (matrix1.m21 * matrix2.m12) + (matrix1.m22 * matrix2.m22);
|
result.m22 = matrix1.m21 * matrix2.m12 + matrix1.m22 * matrix2.m22;
|
||||||
|
result.m31 = matrix1.m31 * matrix2.m11 + matrix1.m32 * matrix2.m21 + matrix2.m31;
|
||||||
let m31 = (matrix1.m31 * matrix2.m11) + (matrix1.m32 * matrix2.m21) + matrix2.m31;
|
result.m32 = matrix1.m31 * matrix2.m12 + matrix1.m32 * matrix2.m22 + matrix2.m32;
|
||||||
let m32 = (matrix1.m31 * matrix2.m12) + (matrix1.m32 * matrix2.m22) + matrix2.m32;
|
} else {
|
||||||
|
// 执行矩阵和标量的乘法。
|
||||||
result.m11 = m11;
|
|
||||||
result.m12 = m12;
|
|
||||||
|
|
||||||
result.m21 = m21;
|
|
||||||
result.m22 = m22;
|
|
||||||
|
|
||||||
result.m31 = m31;
|
|
||||||
result.m32 = m32;
|
|
||||||
} else if (typeof matrix2 == "number"){
|
|
||||||
result.m11 = matrix1.m11 * matrix2;
|
result.m11 = matrix1.m11 * matrix2;
|
||||||
result.m12 = matrix1.m12 * matrix2;
|
result.m12 = matrix1.m12 * matrix2;
|
||||||
|
|
||||||
result.m21 = matrix1.m21 * matrix2;
|
result.m21 = matrix1.m21 * matrix2;
|
||||||
result.m22 = matrix1.m22 * matrix2;
|
result.m22 = matrix1.m22 * matrix2;
|
||||||
|
|
||||||
result.m31 = matrix1.m31 * matrix2;
|
result.m31 = matrix1.m31 * matrix2;
|
||||||
result.m32 = matrix1.m32 * matrix2;
|
result.m32 = matrix1.m32 * matrix2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 返回计算结果的 Matrix2D 对象。
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建一个新的Matrix2D,包含一个矩阵与另一个矩阵的减法。
|
* 该静态方法用于计算两个 Matrix2D 对象的差。
|
||||||
* @param matrix1
|
* @param {Matrix2D} matrix1 - 第一个矩阵。
|
||||||
* @param matrix2
|
* @param {Matrix2D} matrix2 - 第二个矩阵。
|
||||||
|
* @returns {Matrix2D} - 计算结果的 Matrix2D 对象。
|
||||||
*/
|
*/
|
||||||
public static subtract(matrix1: Matrix2D, matrix2: Matrix2D) {
|
public static subtract(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D {
|
||||||
let result = Matrix2D.identity;
|
// 创建一个新的 Matrix2D 对象以存储计算结果。
|
||||||
|
const result = new Matrix2D();
|
||||||
|
|
||||||
|
// 计算两个矩阵的差。
|
||||||
result.m11 = matrix1.m11 - matrix2.m11;
|
result.m11 = matrix1.m11 - matrix2.m11;
|
||||||
result.m12 = matrix1.m12 - matrix2.m12;
|
result.m12 = matrix1.m12 - matrix2.m12;
|
||||||
|
|
||||||
result.m21 = matrix1.m21 - matrix2.m21;
|
result.m21 = matrix1.m21 - matrix2.m21;
|
||||||
result.m22 = matrix1.m22 - matrix2.m22;
|
result.m22 = matrix1.m22 - matrix2.m22;
|
||||||
|
|
||||||
result.m31 = matrix1.m31 - matrix2.m31;
|
result.m31 = matrix1.m31 - matrix2.m31;
|
||||||
result.m32 = matrix1.m32 - matrix2.m32;
|
result.m32 = matrix1.m32 - matrix2.m32;
|
||||||
|
|
||||||
|
// 返回计算结果的 Matrix2D 对象。
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -390,6 +390,7 @@ module es {
|
|||||||
public offset(offsetX: number, offsetY: number) {
|
public offset(offsetX: number, offsetY: number) {
|
||||||
this.x += offsetX;
|
this.x += offsetX;
|
||||||
this.y += offsetY;
|
this.y += offsetY;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,31 +1,35 @@
|
|||||||
module es {
|
module es {
|
||||||
/**
|
/**
|
||||||
* 它存储值,直到累计的总数大于1。一旦超过1,该值将在调用update时添加到amount中
|
* 该类用于存储具有亚像素分辨率的浮点数。
|
||||||
* 一般用法如下:
|
|
||||||
*
|
|
||||||
* let deltaMove = this.velocity * es.Time.deltaTime;
|
|
||||||
* deltaMove.x = this._x.update(deltaMove.x);
|
|
||||||
* deltaMove.y = this._y.update(deltaMove.y);
|
|
||||||
*/
|
*/
|
||||||
export class SubpixelFloat {
|
export class SubpixelFloat {
|
||||||
|
/**
|
||||||
|
* 存储 SubpixelFloat 值的浮点余数。
|
||||||
|
*/
|
||||||
public remainder: number = 0;
|
public remainder: number = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 以amount递增余数,将值截断,存储新的余数并将amount设置为当前值
|
* 通过将给定数量的像素添加到余数中来更新 SubpixelFloat 值。
|
||||||
* @param amount
|
* 返回更新后的整数部分,余数表示当前值中包含的亚像素部分。
|
||||||
|
* @param {number} amount - 要添加到余数中的像素数。
|
||||||
|
* @returns {number} 更新后的整数部分。
|
||||||
*/
|
*/
|
||||||
public update(amount: number){
|
public update(amount: number): number {
|
||||||
|
// 将给定的像素数量添加到余数中
|
||||||
this.remainder += amount;
|
this.remainder += amount;
|
||||||
|
|
||||||
|
// 检查余数是否超过一个像素的大小
|
||||||
let motion = Math.trunc(this.remainder);
|
let motion = Math.trunc(this.remainder);
|
||||||
this.remainder -= motion;
|
this.remainder -= motion;
|
||||||
amount = motion;
|
|
||||||
return amount;
|
// 返回整数部分作为更新后的值
|
||||||
|
return motion;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将余数重置为0
|
* 将 SubpixelFloat 值重置为零。
|
||||||
*/
|
*/
|
||||||
public reset(){
|
public reset(): void {
|
||||||
this.remainder = 0;
|
this.remainder = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,32 @@
|
|||||||
module es {
|
module es {
|
||||||
|
/**
|
||||||
|
* 该类用于存储具有亚像素分辨率的二维向量。
|
||||||
|
*/
|
||||||
export class SubpixelVector2 {
|
export class SubpixelVector2 {
|
||||||
|
/**
|
||||||
|
* 用于存储 x 坐标的 SubpixelFloat 对象。
|
||||||
|
*/
|
||||||
public _x: SubpixelFloat = new SubpixelFloat();
|
public _x: SubpixelFloat = new SubpixelFloat();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于存储 y 坐标的 SubpixelFloat 对象。
|
||||||
|
*/
|
||||||
public _y: SubpixelFloat = new SubpixelFloat();
|
public _y: SubpixelFloat = new SubpixelFloat();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 以数量递增s/y余数,将值截断为整数,存储新的余数并将amount设置为当前值
|
* 通过将给定数量的像素添加到余数中来更新 SubpixelVector2 值。
|
||||||
* @param amount
|
* @param {Vector2} amount - 要添加到余数中的像素向量。
|
||||||
*/
|
*/
|
||||||
public update(amount: Vector2) {
|
public update(amount: Vector2): void {
|
||||||
|
// 更新 x 和 y 坐标
|
||||||
amount.x = this._x.update(amount.x);
|
amount.x = this._x.update(amount.x);
|
||||||
amount.y = this._y.update(amount.y);
|
amount.y = this._y.update(amount.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将余数重置为0
|
* 将 SubpixelVector2 值的余数重置为零。
|
||||||
*/
|
*/
|
||||||
public reset(){
|
public reset(): void {
|
||||||
this._x.reset();
|
this._x.reset();
|
||||||
this._y.reset();
|
this._y.reset();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,14 +55,14 @@ module es {
|
|||||||
|
|
||||||
public getEdges(): Array<Line> {
|
public getEdges(): Array<Line> {
|
||||||
const edges = [];
|
const edges = [];
|
||||||
|
|
||||||
for (let i = 0; i < this.points.length; i++) {
|
for (let i = 0; i < this.points.length; i++) {
|
||||||
const j = (i + 1) % this.points.length;
|
const j = (i + 1) % this.points.length;
|
||||||
edges.push(new Line(this.points[i], this.points[j]));
|
edges.push(new Line(this.points[i], this.points[j]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return edges;
|
return edges;
|
||||||
}
|
}
|
||||||
|
|
||||||
public overlaps(other: Shape) {
|
public overlaps(other: Shape) {
|
||||||
// 特殊情况,这一个高性能方式实现,其他情况则使用polygon方法检测
|
// 特殊情况,这一个高性能方式实现,其他情况则使用polygon方法检测
|
||||||
@@ -103,31 +103,34 @@ module es {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getFurthestPoint(normal: Vector2): Vector2 {
|
public getFurthestPoint(normal: Vector2): Vector2 {
|
||||||
let furthestPoint = new Vector2(this.width / 2, this.height / 2);
|
const halfWidth = this.width / 2;
|
||||||
|
const halfHeight = this.height / 2;
|
||||||
|
|
||||||
|
let furthestPoint = new Vector2(halfWidth, halfHeight);
|
||||||
let dotProduct = furthestPoint.dot(normal);
|
let dotProduct = furthestPoint.dot(normal);
|
||||||
|
|
||||||
let tempPoint = new Vector2(-this.width / 2, this.height / 2);
|
let tempPoint = new Vector2(-halfWidth, halfHeight);
|
||||||
let tempDotProduct = tempPoint.dot(normal);
|
let tempDotProduct = tempPoint.dot(normal);
|
||||||
if (tempDotProduct > dotProduct) {
|
if (tempDotProduct > dotProduct) {
|
||||||
furthestPoint.copyFrom(tempPoint);
|
furthestPoint.copyFrom(tempPoint);
|
||||||
dotProduct = tempDotProduct;
|
dotProduct = tempDotProduct;
|
||||||
}
|
}
|
||||||
|
|
||||||
tempPoint.setTo(-this.width / 2, -this.height / 2);
|
tempPoint.setTo(-halfWidth, -halfHeight);
|
||||||
tempDotProduct = tempPoint.dot(normal);
|
tempDotProduct = tempPoint.dot(normal);
|
||||||
if (tempDotProduct > dotProduct) {
|
if (tempDotProduct > dotProduct) {
|
||||||
furthestPoint.copyFrom(tempPoint);
|
furthestPoint.copyFrom(tempPoint);
|
||||||
dotProduct = tempDotProduct;
|
dotProduct = tempDotProduct;
|
||||||
}
|
}
|
||||||
|
|
||||||
tempPoint.setTo(this.width / 2, -this.height / 2);
|
tempPoint.setTo(halfWidth, -halfHeight);
|
||||||
tempDotProduct = tempPoint.dot(normal);
|
tempDotProduct = tempPoint.dot(normal);
|
||||||
if (tempDotProduct > dotProduct) {
|
if (tempDotProduct > dotProduct) {
|
||||||
furthestPoint.copyFrom(tempPoint);
|
furthestPoint.copyFrom(tempPoint);
|
||||||
dotProduct = tempDotProduct;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return furthestPoint;
|
return furthestPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -35,24 +35,26 @@ module es {
|
|||||||
);
|
);
|
||||||
if (this.point) {
|
if (this.point) {
|
||||||
if (!cr.point) {
|
if (!cr.point) {
|
||||||
cr.point = new Vector2(0, 0);
|
cr.point = new Vector2(0, 0);
|
||||||
}
|
}
|
||||||
cr.point.setTo(this.point.x, this.point.y);
|
cr.point.setTo(this.point.x, this.point.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 改变最小平移向量,如果没有相同方向上的运动,它将移除平移的x分量。
|
* 从移动向量中移除水平方向的位移,以确保形状只沿垂直方向运动。如果移动向量包含水平移动,则通过计算垂直位移来修复响应距离。
|
||||||
* @param deltaMovement
|
* @param deltaMovement - 移动向量
|
||||||
*/
|
*/
|
||||||
public removeHorizontalTranslation(deltaMovement: Vector2){
|
public removeHorizontalTranslation(deltaMovement: Vector2) {
|
||||||
// 检查是否需要横向移动,如果需要,移除并固定响应
|
// 如果运动方向和法线方向不在同一方向或者移动量为0且法线方向不为0,则需要修复
|
||||||
if (Math.sign(this.normal.x) !== Math.sign(deltaMovement.x) || (deltaMovement.x === 0 && this.normal.x !== 0)){
|
if (Math.sign(this.normal.x) !== Math.sign(deltaMovement.x) || (deltaMovement.x === 0 && this.normal.x !== 0)) {
|
||||||
|
// 获取响应距离
|
||||||
const responseDistance = this.minimumTranslationVector.magnitude();
|
const responseDistance = this.minimumTranslationVector.magnitude();
|
||||||
|
// 计算需要修复的位移
|
||||||
const fix = responseDistance / this.normal.y;
|
const fix = responseDistance / this.normal.y;
|
||||||
|
|
||||||
// 检查一些边界情况。因为我们除以法线 使得x == 1和一个非常小的y这将导致一个巨大的固定值
|
// 如果法线方向不是完全水平或垂直,并且修复距离小于移动向量的3倍,则修复距离
|
||||||
if (Math.abs(this.normal.x) != 1 && Math.abs(fix) < Math.abs(deltaMovement.y * 3)){
|
if (Math.abs(this.normal.x) != 1 && Math.abs(fix) < Math.abs(deltaMovement.y * 3)) {
|
||||||
this.minimumTranslationVector = new Vector2(0, -fix);
|
this.minimumTranslationVector = new Vector2(0, -fix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -63,7 +65,7 @@ module es {
|
|||||||
this.normal = this.normal.negate();
|
this.normal = this.normal.negate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public toString(){
|
public toString() {
|
||||||
return `[CollisionResult] normal: ${this.normal}, minimumTranslationVector: ${this.minimumTranslationVector}`;
|
return `[CollisionResult] normal: ${this.normal}, minimumTranslationVector: ${this.minimumTranslationVector}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ module es {
|
|||||||
|
|
||||||
public create(vertCount: number, radius: number) {
|
public create(vertCount: number, radius: number) {
|
||||||
Polygon.buildSymmetricalPolygon(vertCount, radius);
|
Polygon.buildSymmetricalPolygon(vertCount, radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
public _edgeNormals: Vector2[];
|
public _edgeNormals: Vector2[];
|
||||||
|
|
||||||
@@ -167,7 +167,11 @@ module es {
|
|||||||
* @param distanceSquared
|
* @param distanceSquared
|
||||||
* @param edgeNormal
|
* @param edgeNormal
|
||||||
*/
|
*/
|
||||||
public static getClosestPointOnPolygonToPoint(points: Vector2[], point: Vector2): { distanceSquared: number; edgeNormal: Vector2; closestPoint: Vector2 } {
|
public static getClosestPointOnPolygonToPoint(points: Vector2[], point: Vector2): {
|
||||||
|
distanceSquared: number;
|
||||||
|
edgeNormal: Vector2;
|
||||||
|
closestPoint: Vector2
|
||||||
|
} {
|
||||||
const res = {
|
const res = {
|
||||||
distanceSquared: Number.MAX_VALUE,
|
distanceSquared: Number.MAX_VALUE,
|
||||||
edgeNormal: Vector2.zero,
|
edgeNormal: Vector2.zero,
|
||||||
@@ -215,75 +219,44 @@ module es {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public recalculateBounds(collider: Collider) {
|
public recalculateBounds(collider: Collider) {
|
||||||
// 如果我们没有旋转或不关心TRS我们使用localOffset作为中心,我们会从那开始
|
|
||||||
this.center = collider.localOffset;
|
this.center = collider.localOffset;
|
||||||
|
|
||||||
if (collider.shouldColliderScaleAndRotateWithTransform) {
|
if (collider.shouldColliderScaleAndRotateWithTransform) {
|
||||||
let hasUnitScale = true;
|
let hasUnitScale = true;
|
||||||
const tempMat: Matrix2D = new Matrix2D();
|
const tempMat = new Matrix2D();
|
||||||
const combinedMatrix: Matrix2D = new Matrix2D();
|
const combinedMatrix = new Matrix2D();
|
||||||
Matrix2D.createTranslation(
|
|
||||||
this._polygonCenter.x * -1,
|
|
||||||
this._polygonCenter.y * -1,
|
|
||||||
combinedMatrix
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!collider.entity.transform.scale.equals(Vector2.one)) {
|
Matrix2D.createTranslation(-this._polygonCenter.x, -this._polygonCenter.y, combinedMatrix);
|
||||||
Matrix2D.createScale(
|
|
||||||
collider.entity.scale.x,
|
const scale = collider.entity.transform.scale;
|
||||||
collider.entity.scale.y,
|
if (!scale.equals(Vector2.one)) {
|
||||||
tempMat
|
Matrix2D.createScale(scale.x, scale.y, tempMat);
|
||||||
);
|
|
||||||
Matrix2D.multiply(combinedMatrix, tempMat, combinedMatrix);
|
Matrix2D.multiply(combinedMatrix, tempMat, combinedMatrix);
|
||||||
hasUnitScale = false;
|
hasUnitScale = false;
|
||||||
|
|
||||||
// 缩放偏移量并将其设置为中心。如果我们有旋转,它会在下面重置
|
const scaledOffset = collider.localOffset.multiply(scale);
|
||||||
const scaledOffset = new Vector2(
|
|
||||||
collider.localOffset.x * collider.entity.scale.x,
|
|
||||||
collider.localOffset.y * collider.entity.scale.y
|
|
||||||
);
|
|
||||||
this.center = scaledOffset;
|
this.center = scaledOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (collider.entity.transform.rotation != 0) {
|
const rotation = collider.entity.transform.rotationDegrees;
|
||||||
Matrix2D.createRotation(
|
if (rotation !== 0) {
|
||||||
MathHelper.Deg2Rad * collider.entity.rotation,
|
const offsetLength = hasUnitScale ? collider._localOffsetLength : collider.localOffset.multiply(scale).magnitude();
|
||||||
tempMat
|
const offsetAngle = Math.atan2(collider.localOffset.y * scale.y, collider.localOffset.x * scale.x) * MathHelper.Rad2Deg;
|
||||||
);
|
this.center = MathHelper.pointOnCircle(Vector2.zero, offsetLength, rotation + offsetAngle);
|
||||||
|
Matrix2D.createRotation(MathHelper.Deg2Rad * rotation, tempMat);
|
||||||
Matrix2D.multiply(combinedMatrix, tempMat, combinedMatrix);
|
Matrix2D.multiply(combinedMatrix, tempMat, combinedMatrix);
|
||||||
|
|
||||||
// 为了处理偏移原点的旋转我们只需要将圆心在(0,0)附近移动
|
|
||||||
// 我们的偏移使角度为0我们还需要处理这里的比例所以我们先对偏移进行缩放以得到合适的长度。
|
|
||||||
const offsetAngle = Math.atan2(collider.localOffset.y * collider.entity.transform.scale.y, collider.localOffset.x * collider.entity.transform.scale.x) * MathHelper.Rad2Deg;
|
|
||||||
const offsetLength = hasUnitScale ? collider._localOffsetLength :
|
|
||||||
collider.localOffset.multiply(collider.entity.transform.scale).magnitude();
|
|
||||||
this.center = MathHelper.pointOnCircle(Vector2.zero, offsetLength,
|
|
||||||
collider.entity.transform.rotationDegrees + offsetAngle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix2D.createTranslation(
|
Matrix2D.createTranslation(this._polygonCenter.x + collider.transform.position.x + this.center.x, this._polygonCenter.y + collider.transform.position.y + this.center.y, tempMat);
|
||||||
this._polygonCenter.x,
|
|
||||||
this._polygonCenter.y,
|
|
||||||
tempMat
|
|
||||||
);
|
|
||||||
Matrix2D.multiply(combinedMatrix, tempMat, combinedMatrix);
|
Matrix2D.multiply(combinedMatrix, tempMat, combinedMatrix);
|
||||||
|
|
||||||
// 最后变换原始点
|
this.points = this._originalPoints.map(p => p.transform(combinedMatrix));
|
||||||
this.points = [];
|
this.isUnrotated = rotation === 0;
|
||||||
this._originalPoints.forEach(p => {
|
if (collider._isRotationDirty) this._areEdgeNormalsDirty = true;
|
||||||
this.points.push(p.transform(combinedMatrix));
|
|
||||||
});
|
|
||||||
|
|
||||||
this.isUnrotated = collider.entity.transform.rotation == 0;
|
|
||||||
|
|
||||||
// 如果旋转的话,我们只需要重建边的法线
|
|
||||||
if (collider._isRotationDirty)
|
|
||||||
this._areEdgeNormalsDirty = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.position = collider.transform.position.add(this.center);
|
this.position = collider.transform.position.add(this.center);
|
||||||
this.bounds = Rectangle.rectEncompassingPoints(this.points);
|
this.bounds = Rectangle.rectEncompassingPoints(this.points).offset(this.position.x, this.position.y);
|
||||||
this.bounds.location = this.bounds.location.add(this.position);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public overlaps(other: Shape) {
|
public overlaps(other: Shape) {
|
||||||
|
|||||||
@@ -1,15 +1,23 @@
|
|||||||
module es {
|
module es {
|
||||||
export class RealtimeCollisions {
|
export class RealtimeCollisions {
|
||||||
|
/**
|
||||||
|
* 判断移动的圆是否与矩形相交,并返回相撞的时间。
|
||||||
|
* @param s 移动的圆
|
||||||
|
* @param b 矩形
|
||||||
|
* @param movement 移动的向量
|
||||||
|
* @param time 时间
|
||||||
|
* @returns 是否相撞
|
||||||
|
*/
|
||||||
public static intersectMovingCircleBox(s: Circle, b: Box, movement: Vector2, time: number): boolean {
|
public static intersectMovingCircleBox(s: Circle, b: Box, movement: Vector2, time: number): boolean {
|
||||||
// 计算将b按球面半径r扩大后的AABB
|
// 计算将b按球面半径r扩大后的AABB
|
||||||
const e = b.bounds;
|
const e = b.bounds;
|
||||||
e.inflate(s.radius, s.radius);
|
e.inflate(s.radius, s.radius);
|
||||||
|
|
||||||
// 将射线与展开的矩形e相交,如果射线错过了e,则以无交点退出,否则得到交点p和时间t作为结果。
|
// 将射线与展开的矩形e相交,如果射线错过了e,则以无交点退出,否则得到交点p和时间t作为结果。
|
||||||
const ray = new Ray2D(s.position.sub(movement), s.position);
|
const ray = new Ray2D(s.position.sub(movement), s.position); // 创建射线,将移动后的圆心作为起点
|
||||||
const res = e.rayIntersects(ray);
|
const res = e.rayIntersects(ray); // 判断射线与展开的矩形是否相交
|
||||||
if (!res.intersected && res.distance > 1)
|
if (!res.intersected && res.distance > 1)
|
||||||
return false;
|
return false; // 如果没有相交且距离大于1,则无法相撞
|
||||||
|
|
||||||
// 求交点
|
// 求交点
|
||||||
const point = ray.start.add(ray.direction.scale(time));
|
const point = ray.start.add(ray.direction.scale(time));
|
||||||
@@ -17,25 +25,25 @@ module es {
|
|||||||
// 计算交点p位于b的哪个最小面和最大面之外。注意,u和v不能有相同的位集,它们之间必须至少有一个位集。
|
// 计算交点p位于b的哪个最小面和最大面之外。注意,u和v不能有相同的位集,它们之间必须至少有一个位集。
|
||||||
let u: number, v: number = 0;
|
let u: number, v: number = 0;
|
||||||
if (point.x < b.bounds.left)
|
if (point.x < b.bounds.left)
|
||||||
u |= 1;
|
u |= 1; // 如果交点在最小的x面的左边,将第一位设为1
|
||||||
if (point.x > b.bounds.right)
|
if (point.x > b.bounds.right)
|
||||||
v |= 1;
|
v |= 1; // 如果交点在最大的x面的右边,将第一位设为1
|
||||||
if (point.y < b.bounds.top)
|
if (point.y < b.bounds.top)
|
||||||
u |= 2;
|
u |= 2; // 如果交点在最小的y面的上面,将第二位设为1
|
||||||
if (point.y > b.bounds.bottom)
|
if (point.y > b.bounds.bottom)
|
||||||
v |= 2;
|
v |= 2; // 如果交点在最大的y面的下面,将第二位设为1
|
||||||
|
|
||||||
// 'or'将所有的比特集合在一起,形成一个比特掩码(注意u + v == u | v)
|
// 'or'将所有的比特集合在一起,形成一个比特掩码(注意u + v == u | v)
|
||||||
const m = u + v;
|
const m = u + v;
|
||||||
|
|
||||||
// 如果这3个比特都被设置,那么该点就在顶点区域内。
|
// 如果这3个比特都被设置,那么该点就在顶点区域内。
|
||||||
if (m == 3){
|
if (m == 3) {
|
||||||
// 如果有一条或多条命中,则必须在两条边的顶点相交,并返回最佳时间。
|
// 如果有一条或多条命中,则必须在两条边的顶点相交,并返回最佳时间。
|
||||||
console.log(`m == 3. corner ${Time.frameCount}`);
|
console.log(`m == 3. corner ${Time.frameCount}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果在m中只设置了一个位,那么该点就在一个面的区域。
|
// 如果在m中只设置了一个位,那么该点就在一个面的区域。
|
||||||
if ((m & (m - 1)) == 0){
|
if ((m & (m - 1)) == 0) {
|
||||||
// 从扩大的矩形交点开始的时间就是正确的时间
|
// 从扩大的矩形交点开始的时间就是正确的时间
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -44,33 +52,36 @@ module es {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支持函数,返回索引为n的矩形vert
|
* 返回矩形的第n个角的坐标。
|
||||||
* @param b
|
* @param b 矩形
|
||||||
* @param n
|
* @param n 第n个角的编号
|
||||||
|
* @returns 第n个角的坐标
|
||||||
*/
|
*/
|
||||||
public static corner(b: Rectangle, n: number){
|
public static corner(b: Rectangle, n: number): es.Vector2 {
|
||||||
let p = es.Vector2.zero;
|
let p = es.Vector2.zero;
|
||||||
p.x = (n & 1) == 0 ? b.right : b.left;
|
p.x = (n & 1) === 0 ? b.right : b.left;
|
||||||
p.y = (n & 1) == 0 ? b.bottom : b.top;
|
p.y = (n & 1) === 0 ? b.bottom : b.top;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查圆是否与方框重叠,并返回point交点
|
* 测试一个圆和一个矩形是否相交,并返回是否相交。
|
||||||
* @param cirlce
|
* @param circle 圆
|
||||||
* @param box
|
* @param box 矩形
|
||||||
* @param point
|
* @param point 离圆心最近的点
|
||||||
|
* @returns 是否相交
|
||||||
*/
|
*/
|
||||||
public static testCircleBox(cirlce: Circle, box: Box, point: Vector2) {
|
public static testCircleBox(circle: Circle, box: Box, point: Vector2): boolean {
|
||||||
// 找出离球心最近的点
|
// 找出离圆心最近的点
|
||||||
point = box.bounds.getClosestPointOnRectangleToPoint(cirlce.position);
|
point = box.bounds.getClosestPointOnRectangleToPoint(circle.position);
|
||||||
|
|
||||||
// 圆和方块相交,如果圆心到点的距离小于圆的半径,则圆和方块相交
|
// 如果圆心到点的距离小于等于圆的半径,则圆和方块相交
|
||||||
const v = point.sub(cirlce.position);
|
const v = point.sub(circle.position);
|
||||||
const dist = v.dot(v);
|
const dist = v.dot(v);
|
||||||
|
|
||||||
return dist <= cirlce.radius * cirlce.radius;
|
return dist <= circle.radius * circle.radius;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -32,18 +32,20 @@ module es {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 扇形的圆心和半径计算出扇形的重心
|
* 获取圆弧的质心。
|
||||||
* @returns
|
* @returns 圆弧的质心
|
||||||
*/
|
*/
|
||||||
public getCentroid(): Vector2 {
|
public getCentroid(): Vector2 {
|
||||||
|
// 计算圆弧的质心坐标
|
||||||
const x = (Math.cos(this.startAngle) + Math.cos(this.endAngle)) * this.radius / 3;
|
const x = (Math.cos(this.startAngle) + Math.cos(this.endAngle)) * this.radius / 3;
|
||||||
const y = (Math.sin(this.startAngle) + Math.sin(this.endAngle)) * this.radius / 3;
|
const y = (Math.sin(this.startAngle) + Math.sin(this.endAngle)) * this.radius / 3;
|
||||||
|
// 返回质心坐标
|
||||||
return new Vector2(x + this.center.x, y + this.center.y);
|
return new Vector2(x + this.center.x, y + this.center.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算向量角度
|
* 计算向量角度
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
public getAngle(): number {
|
public getAngle(): number {
|
||||||
return this.startAngle;
|
return this.startAngle;
|
||||||
@@ -82,7 +84,7 @@ module es {
|
|||||||
if (other instanceof Box) {
|
if (other instanceof Box) {
|
||||||
return ShapeCollisionSector.sectorToBox(this, other, collisionResult);
|
return ShapeCollisionSector.sectorToBox(this, other, collisionResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (other instanceof Polygon) {
|
if (other instanceof Polygon) {
|
||||||
return ShapeCollisionSector.sectorToPolygon(this, other, collisionResult);
|
return ShapeCollisionSector.sectorToPolygon(this, other, collisionResult);
|
||||||
}
|
}
|
||||||
@@ -95,63 +97,67 @@ module es {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public collidesWithLine(start: Vector2, end: Vector2, hit: Out<RaycastHit>): boolean {
|
public collidesWithLine(start: Vector2, end: Vector2, hit: Out<RaycastHit>): boolean {
|
||||||
const toStart = start.sub(this.center);
|
const toStart = start.sub(this.center); // 线段起点到圆心的向量
|
||||||
const toEnd = end.sub(this.center);
|
const toEnd = end.sub(this.center); // 线段终点到圆心的向量
|
||||||
const angleStart = toStart.getAngle();
|
const angleStart = toStart.getAngle(); // 起点向量与 x 轴正方向的夹角
|
||||||
const angleEnd = toEnd.getAngle();
|
const angleEnd = toEnd.getAngle(); // 终点向量与 x 轴正方向的夹角
|
||||||
let angleDiff = angleEnd - angleStart;
|
let angleDiff = angleEnd - angleStart; // 终点角度减去起点角度得到角度差
|
||||||
|
|
||||||
|
// 将角度差限制在 -PI 到 PI 之间,方便判断是否跨越了 0 度
|
||||||
if (angleDiff > Math.PI) {
|
if (angleDiff > Math.PI) {
|
||||||
angleDiff -= 2 * Math.PI;
|
angleDiff -= 2 * Math.PI;
|
||||||
} else if (angleDiff < -Math.PI) {
|
} else if (angleDiff < -Math.PI) {
|
||||||
angleDiff += 2 * Math.PI;
|
angleDiff += 2 * Math.PI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果角度差在圆弧的起始角度和结束角度之间,则有可能发生相交
|
||||||
if (angleDiff >= this.startAngle && angleDiff <= this.endAngle) {
|
if (angleDiff >= this.startAngle && angleDiff <= this.endAngle) {
|
||||||
const r = toStart.getLength();
|
const r = toStart.getLength(); // 圆心到线段起点的距离
|
||||||
const t = this.startAngle - angleStart;
|
const t = this.startAngle - angleStart; // 起点角度到圆弧起始角度的角度差
|
||||||
const x = r * Math.cos(t);
|
const x = r * Math.cos(t); // 圆弧上与线段相交的点的 x 坐标
|
||||||
const y = r * Math.sin(t);
|
const y = r * Math.sin(t); // 圆弧上与线段相交的点的 y 坐标
|
||||||
const intersection = new Vector2(x, y);
|
const intersection = new Vector2(x, y); // 相交点的二维坐标
|
||||||
|
|
||||||
|
// 判断相交点是否在线段上
|
||||||
if (intersection.isBetween(start, end)) {
|
if (intersection.isBetween(start, end)) {
|
||||||
const distance = intersection.sub(start).getLength();
|
const distance = intersection.sub(start).getLength(); // 相交点到线段起点的距离
|
||||||
const fraction = distance / start.getDistance(end);
|
const fraction = distance / start.getDistance(end); // 相交点处于线段的分数
|
||||||
const normal = intersection.sub(this.center).normalize();
|
const normal = intersection.sub(this.center).normalize(); // 相交点处圆弧的法向量
|
||||||
const point = intersection.add(this.center);
|
const point = intersection.add(this.center); // 相交点的全局坐标
|
||||||
|
|
||||||
|
// 将相交信息存储到 hit 参数中
|
||||||
const raycastHit = new RaycastHit();
|
const raycastHit = new RaycastHit();
|
||||||
raycastHit.setValues(fraction, distance, point, normal);
|
raycastHit.setValues(fraction, distance, point, normal);
|
||||||
hit.value = raycastHit;
|
hit.value = raycastHit;
|
||||||
|
|
||||||
return true;
|
return true; // 返回 true 表示相交
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false; // 返回 false 表示不相交
|
||||||
}
|
}
|
||||||
|
|
||||||
public containsPoint(point: Vector2) {
|
public containsPoint(point: Vector2): boolean {
|
||||||
const toPoint = point.sub(this.center);
|
const toPoint = point.sub(this.center); // 点到圆心的向量
|
||||||
const distanceSquared = toPoint.lengthSquared();
|
const distanceSquared = toPoint.lengthSquared(); // 点到圆心距离的平方
|
||||||
|
|
||||||
if (distanceSquared > this.radiusSquared) {
|
if (distanceSquared > this.radiusSquared) { // 如果点到圆心的距离平方大于圆形区域半径平方,则该点不在圆形区域内
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const angle = toPoint.getAngle();
|
const angle = toPoint.getAngle(); // 点到圆心的向量与 x 轴正方向的夹角
|
||||||
const startAngle = this.startAngle;
|
const startAngle = this.startAngle; // 圆弧起始角度
|
||||||
const endAngle = startAngle + this.angle;
|
const endAngle = startAngle + this.angle; // 圆弧终止角度
|
||||||
|
|
||||||
let angleDiff = angle - startAngle;
|
let angleDiff = angle - startAngle; // 计算点到圆弧起始角度的角度差
|
||||||
if (angleDiff < 0) {
|
if (angleDiff < 0) { // 如果角度差小于 0,则说明点在圆弧角度的另一侧,需要加上 2 * PI
|
||||||
angleDiff += Math.PI * 2;
|
angleDiff += Math.PI * 2;
|
||||||
}
|
}
|
||||||
if (angleDiff > this.angle) {
|
if (angleDiff > this.angle) { // 如果角度差大于圆弧角度,则该点不在圆弧范围内
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true; // 点在圆形区域内
|
||||||
}
|
}
|
||||||
|
|
||||||
public pointCollidesWithShape(point: Vector2, result: Out<CollisionResult>): boolean {
|
public pointCollidesWithShape(point: Vector2, result: Out<CollisionResult>): boolean {
|
||||||
@@ -182,24 +188,23 @@ module es {
|
|||||||
}
|
}
|
||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
private calculateProperties() {
|
private calculateProperties() {
|
||||||
this.numberOfPoints = Math.max(10, Math.floor(this.radius * 0.1));
|
this.numberOfPoints = Math.max(10, Math.floor(this.radius * 0.1));
|
||||||
this.angleStep = (this.endAngle - this.startAngle) / (this.numberOfPoints - 1);
|
this.angleStep = (this.endAngle - this.startAngle) / (this.numberOfPoints - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getFurthestPoint(normal: Vector2): Vector2 {
|
public getFurthestPoint(normal: Vector2): Vector2 {
|
||||||
let maxProjection = -Number.MAX_VALUE;
|
let maxProjection = -Number.MAX_VALUE; // 最大投影值
|
||||||
let furthestPoint = new Vector2();
|
let furthestPoint = new Vector2(); // 最远点
|
||||||
for (let i = 0; i < this.numberOfPoints; i++) {
|
for (let i = 0; i < this.numberOfPoints; i++) { // 遍历多边形的所有顶点
|
||||||
let projection = this.points[i].dot(normal);
|
let projection = this.points[i].dot(normal); // 计算当前顶点到法线的投影
|
||||||
if (projection > maxProjection) {
|
if (projection > maxProjection) { // 如果当前投影值大于最大投影值,则更新最大投影值和最远点
|
||||||
maxProjection = projection;
|
maxProjection = projection;
|
||||||
furthestPoint.copyFrom(this.points[i]);
|
furthestPoint.copyFrom(this.points[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return furthestPoint;
|
return furthestPoint; // 返回最远点
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,30 +1,51 @@
|
|||||||
module es {
|
module es {
|
||||||
export abstract class Shape {
|
export abstract class Shape {
|
||||||
/**
|
public position: Vector2; // 形状的位置,表示形状在 2D 空间中的位置。
|
||||||
* 有一个单独的位置字段可以让我们改变形状的位置来进行碰撞检查,而不是改变entity.position。
|
public center: Vector2; // 形状的中心,表示形状的重心或几何中心。
|
||||||
* 触发碰撞器/边界/散列更新的位置。
|
public bounds: Rectangle; // 形状的边界矩形,表示形状所占用的矩形区域。
|
||||||
* 内部字段
|
|
||||||
*/
|
|
||||||
public position: Vector2;
|
|
||||||
/**
|
|
||||||
* 这不是中心。这个值不一定是物体的中心。对撞机更准确。
|
|
||||||
* 应用任何转换旋转的localOffset
|
|
||||||
* 内部字段
|
|
||||||
*/
|
|
||||||
public center: Vector2;
|
|
||||||
/** 缓存的形状边界 内部字段 */
|
|
||||||
public bounds: Rectangle;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据形状的碰撞器重新计算形状的边界。
|
||||||
|
* @param {Collider} collider - 用于重新计算形状边界的碰撞器。
|
||||||
|
*/
|
||||||
public abstract recalculateBounds(collider: Collider);
|
public abstract recalculateBounds(collider: Collider);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确定形状是否与另一个形状重叠。
|
||||||
|
* @param {Shape} other - 要检查重叠的形状。
|
||||||
|
* @returns {boolean} 如果形状重叠,则为 true;否则为 false。
|
||||||
|
*/
|
||||||
public abstract overlaps(other: Shape): boolean;
|
public abstract overlaps(other: Shape): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确定形状是否与另一个形状碰撞。
|
||||||
|
* @param {Shape} other - 要检查碰撞的形状。
|
||||||
|
* @param {Out<CollisionResult>} collisionResult - 如果形状碰撞,则要填充的碰撞结果对象。
|
||||||
|
* @returns {boolean} 如果形状碰撞,则为 true;否则为 false。
|
||||||
|
*/
|
||||||
public abstract collidesWithShape(other: Shape, collisionResult: Out<CollisionResult>): boolean;
|
public abstract collidesWithShape(other: Shape, collisionResult: Out<CollisionResult>): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确定形状是否与线段相交。
|
||||||
|
* @param {Vector2} start - 线段的起点。
|
||||||
|
* @param {Vector2} end - 线段的终点。
|
||||||
|
* @param {Out<RaycastHit>} hit - 如果形状与线段相交,则要填充的射线命中结果对象。
|
||||||
|
* @returns {boolean} 如果形状与线段相交,则为 true;否则为 false。
|
||||||
|
*/
|
||||||
public abstract collidesWithLine(start: Vector2, end: Vector2, hit: Out<RaycastHit>): boolean;
|
public abstract collidesWithLine(start: Vector2, end: Vector2, hit: Out<RaycastHit>): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确定形状是否包含一个点。
|
||||||
|
* @param {Vector2} point - 要检查包含的点。
|
||||||
|
*/
|
||||||
public abstract containsPoint(point: Vector2);
|
public abstract containsPoint(point: Vector2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确定一个点是否与形状相交。
|
||||||
|
* @param {Vector2} point - 要检查与形状相交的点。
|
||||||
|
* @param {Out<CollisionResult>} result - 如果点与形状相交,则要填充的碰撞结果对象。
|
||||||
|
* @returns {boolean} 如果点与形状相交,则为 true;否则为 false。
|
||||||
|
*/
|
||||||
public abstract pointCollidesWithShape(point: Vector2, result: Out<CollisionResult>): boolean;
|
public abstract pointCollidesWithShape(point: Vector2, result: Out<CollisionResult>): boolean;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user