新增arcadeRigidbody组件, 可以用于简单的,街机风格的物理学

This commit is contained in:
yhh
2020-12-07 11:48:42 +08:00
parent 2a0d4ef4dd
commit bddae046a0
12 changed files with 835 additions and 82 deletions

View File

@@ -1,27 +1,12 @@
module es {
/**
* 用于包装事件的一个小类
*/
export class FuncPack {
/** 函数 */
public func: Function;
/** 上下文 */
public context: any;
constructor(func: Function, context: any) {
this.func = func;
this.context = context;
}
}
/**
* 用于事件管理
*/
export class Emitter<T> {
private _messageTable: Map<T, FuncPack[]>;
private _messageTable: Map<T, Function[]>;
constructor() {
this._messageTable = new Map<T, FuncPack[]>();
this._messageTable = new Map<T, Function[]>();
}
/**
@@ -31,15 +16,17 @@ module es {
* @param context 监听上下文
*/
public addObserver(eventType: T, handler: Function, context: any) {
let list: FuncPack[] = this._messageTable.get(eventType);
handler.bind(context);
let list: Function[] = this._messageTable.get(eventType);
if (!list) {
list = [];
this._messageTable.set(eventType, list);
}
if (list.findIndex(funcPack => funcPack.func == handler) != -1)
if (new linq.List(list).contains(handler))
console.warn("您试图添加相同的观察者两次");
list.push(new FuncPack(handler, context));
list.push(handler);
}
/**
@@ -49,9 +36,7 @@ module es {
*/
public removeObserver(eventType: T, handler: Function) {
let messageData = this._messageTable.get(eventType);
let index = messageData.findIndex(data => data.func == handler);
if (index != -1)
new linq.List(messageData).removeAt(index);
new linq.List(messageData).remove(handler);
}
/**
@@ -60,10 +45,10 @@ module es {
* @param data 事件数据
*/
public emit(eventType: T, data?: any) {
let list: FuncPack[] = this._messageTable.get(eventType);
let list: Function[] = this._messageTable.get(eventType);
if (list) {
for (let i = list.length - 1; i >= 0; i--)
list[i].func.call(list[i].context, data);
list[i](data);
}
}
}

View File

@@ -13,7 +13,7 @@ module es {
reset();
/**
*
* 返回投向T的上下文作为方便
*/
getContext<T>(): T;
}

View File

@@ -1,4 +1,7 @@
module es {
/**
* 私有类隐藏ITimer的实现
*/
export class Timer implements ITimer{
public context: any;
public _timeInSeconds: number = 0;

View File

@@ -1,10 +1,10 @@
module es {
/**
* 三角剖分
* 简单的剪耳三角测量器最终的三角形将出现在triangleIndices列表中。
*/
export class Triangulator {
/**
* 最后一次三角调用中使用的点列表的三角列表项的索引
* 次三角函数调用中使用的点列表的三角列表条目索引
*/
public triangleIndices: number[] = [];
@@ -12,15 +12,19 @@ module es {
private _triNext: number[] = new Array<number>(12);
public static testPointTriangle(point: Vector2, a: Vector2, b: Vector2, c: Vector2): boolean {
// 如果点在AB的右边那么外边的三角形是
if (Vector2Ext.cross(Vector2.subtract(point, a), Vector2.subtract(b, a)) < 0)
return false;
// 如果点在BC的右边则在三角形的外侧
if (Vector2Ext.cross(Vector2.subtract(point, b), Vector2.subtract(c, b)) < 0)
return false;
// 如果点在ca的右边则在三角形的外面
if (Vector2Ext.cross(Vector2.subtract(point, c), Vector2.subtract(a, c)) < 0)
return false;
// 点在三角形上
return true;
}
@@ -44,8 +48,9 @@ module es {
// 继续移除所有的三角形,直到只剩下一个三角形
while (count > 3 && iterations < 500) {
iterations++;
let isEar = true;
let a = points[this._triPrev[index]];
let b = points[index];
let c = points[this._triNext[index]];
@@ -94,11 +99,11 @@ module es {
if (this._triNext.length < count) {
this._triNext.reverse();
this._triNext = new Array<number>(Math.max(this._triNext.length * 2, count));
this._triNext.length = Math.max(this._triNext.length * 2, count);
}
if (this._triPrev.length < count) {
this._triPrev.reverse();
this._triPrev = new Array<number>(Math.max(this._triPrev.length * 2, count));
this._triPrev.length = Math.max(this._triPrev.length * 2, count);
}
for (let i = 0; i < count; i++) {

View File

@@ -24,7 +24,7 @@ module es {
}
/**
* 返回传入向量垂直的向量
* 返回垂直于传入向量的向量
* @param first
* @param second
*/
@@ -32,6 +32,45 @@ module es {
return new Vector2(-1 * (second.y - first.y), second.x - first.x);
}
/**
* 返回两个向量之间的角度,单位为度
* @param from
* @param to
*/
public static angle(from: Vector2, to: Vector2) {
this.normalize(from);
this.normalize(to);
return Math.acos(MathHelper.clamp(Vector2.dot(from, to), -1, 1)) * MathHelper.Rad2Deg;
}
/**
* 给定两条直线(ab和cd),求交点
* @param a
* @param b
* @param c
* @param d
* @param intersection
*/
public static getRayIntersection(a: Vector2, b: Vector2, c: Vector2, d: Vector2, intersection: Vector2 = new Vector2()) {
let dy1 = b.y - a.y;
let dx1 = b.x - a.x;
let dy2 = d.y - c.y;
let dx2 = d.x - c.x;
if (dy1 * dx2 == dy2 * dx1) {
intersection.x = Number.NaN;
intersection.y = Number.NaN;
return false;
}
let x = ((c.y - a.y) * dx1 * dx2 + dy1 * dx2 * a.x - dy2 * dx1 * c.x) / (dy1 * dx2 - dy2 * dx1);
let y = a.y + (dy1 / dx1) * (x - a.x);
intersection.x = x;
intersection.y = y;
return true;
}
/**
* Vector2的临时解决方案
* 标准化把向量弄乱了
@@ -66,7 +105,13 @@ module es {
}
}
public static transformR(position: Vector2, matrix: Matrix2D, result: Vector2) {
/**
* 创建一个新的Vector2该Vector2包含了通过指定的Matrix进行的二维向量变换
* @param position
* @param matrix
* @param result
*/
public static transformR(position: Vector2, matrix: Matrix2D, result: Vector2 = new Vector2()) {
let x = (position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m31;
let y = (position.x * matrix.m12) + (position.y * matrix.m22) + matrix.m32;
result.x = x;