This commit is contained in:
yhh
2020-07-31 19:33:04 +08:00
parent 40fe7a57db
commit bc6626865e
6 changed files with 136 additions and 17 deletions

View File

@@ -7,7 +7,7 @@ module es {
* 删除执行顺序
* - onRemovedFromEntity
*/
export abstract class Component {
export abstract class Component extends egret.HashObject {
/**
* 此组件附加的实体
*/

View File

@@ -3,55 +3,55 @@ declare interface Array<T> {
* 获取满足表达式的数组元素索引
* @param predicate 表达式
*/
findIndex(predicate: Function): number;
findIndex(predicate: (c: T)=>boolean): number;
/**
* 是否存在满足表达式的数组元素
* @param predicate 表达式
*/
any(predicate: Function): boolean;
any(predicate: (c: T) => boolean): boolean;
/**
* 获取满足表达式的第一个或默认数组元素
* @param predicate 表达式
*/
firstOrDefault(predicate: Function): T;
firstOrDefault(predicate: (c: T)=>boolean): T;
/**
* 获取满足表达式的第一个数组元素
* @param predicate 表达式
*/
find(predicate: Function): T;
find(predicate: (c: T) => boolean): T;
/**
* 筛选满足表达式的数组元素
* @param predicate 表达式
*/
where(predicate: Function): Array<T>;
where(predicate: (c: T) => boolean): Array<T>;
/**
* 获取满足表达式的数组元素的计数
* @param predicate 表达式
*/
count(predicate: Function): number;
count(predicate: (c: T) => boolean): number;
/**
* 获取满足表达式的数组元素的数组
* @param predicate 表达式
*/
findAll(predicate: Function): Array<T>;
findAll(predicate: (c: T) => boolean): Array<T>;
/**
* 是否有获取满足表达式的数组元素
* @param value 值
*/
contains(value): boolean;
contains(value: T): boolean;
/**
* 移除满足表达式的数组元素
* @param predicate 表达式
*/
removeAll(predicate: Function): void;
removeAll(predicate: (c: T) => boolean): void;
/**
* 移除数组元素
@@ -63,14 +63,14 @@ declare interface Array<T> {
* 移除特定索引数组元素
* @param index 索引
*/
removeAt(index): void;
removeAt(index: number): void;
/**
* 移除范围数组元素
* @param index 开始索引
* @param count 删除的个数
*/
removeRange(index, count): void;
removeRange(index: number, count: number): void;
/**
* 获取通过选择器转换的数组
@@ -102,7 +102,7 @@ declare interface Array<T> {
* 求和
* @param selector 选择器
*/
sum(selector);
sum(selector: Function): number;
}
Array.prototype.findIndex = function (predicate) {
@@ -189,6 +189,11 @@ Array.prototype.findAll = function (predicate) {
Array.prototype.contains = function (value) {
function contains(array, value) {
for (let i = 0, len = array.length; i < len; i++) {
if (array[i] instanceof egret.HashObject && value instanceof egret.HashObject){
if ((array[i] as egret.HashObject).hashCode == (value as egret.HashObject).hashCode)
return true;
}
if (array[i] == value) {
return true;
}

View File

@@ -81,6 +81,51 @@ module es {
this.top < value.bottom;
}
public rayIntersects(ray: Ray2D): number{
let distance = 0;
let maxValue = Number.MAX_VALUE;
if (Math.abs(ray.direction.x) < 1E-06){
if ((ray.start.x < this.x) || (ray.start.x > this.x + this.width))
return distance;
}else{
let num11 = 1 / ray.direction.x;
let num8 = (this.x - ray.start.x) * num11;
let num7 = (this.x + this.width - ray.start.x) * num11;
if (num8 > num7){
let num14 = num8;
num8 = num7;
num7 = num14;
}
distance = Math.max(num8, distance);
maxValue = Math.min(num7, maxValue);
if (distance > maxValue)
return distance;
}
if (Math.abs(ray.direction.y) < 1E-06){
if ((ray.start.y < this.y) || (ray.start.y > this.y + this.height))
return distance;
}else{
let num10 = 1 / ray.direction.y;
let num6 = (this.y - ray.start.y) * num10;
let num5 = (this.y + this.height - ray.start.y) * num10;
if (num6 > num5){
let num13 = num6;
num6 = num5;
num5 = num13;
}
distance = Math.max(num6, distance);
maxValue = Math.max(num5, maxValue);
if (distance > maxValue)
return distance;
}
return distance;
}
/**
* 获取所提供的矩形是否在此矩形的边界内
* @param value

View File

@@ -5,6 +5,10 @@ module es {
/** 接受layerMask的所有方法的默认值 */
public static readonly allLayers: number = -1;
private static _spatialHash: SpatialHash;
/**
* raycast是否检测配置为触发器的碰撞器
*/
public static raycastsHitTriggers: boolean = false;
public static reset() {
this._spatialHash = new SpatialHash(this.spatialHashCellSize);

View File

@@ -0,0 +1,16 @@
module es {
/**
* 不是真正的射线(射线只有开始和方向),作为一条线和射线。
*/
export class Ray2D {
public start: Vector2;
public end: Vector2;
public direction: Vector2;
constructor(position: Vector2, end: Vector2){
this.start = position;
this.end = end;
this.direction = Vector2.subtract(this.end, this.start);
}
}
}

View File

@@ -52,8 +52,8 @@ module es {
for (let x = p1.x; x <= p2.x; x++) {
for (let y = p1.y; y <= p2.y; y++) {
// 如果没有单元格,我们需要创建它
let c = this.cellAtPosition(x, y, true);
if (c.indexOf(collider) == -1)
let c: Collider[] = this.cellAtPosition(x, y, true);
if (!c.firstOrDefault(c => c.hashCode == collider.hashCode))
c.push(collider);
}
}
@@ -134,7 +134,7 @@ module es {
continue;
if (bounds.intersects(collider.bounds)) {
if (this._tempHashSet.indexOf(collider) == -1)
if (!this._tempHashSet.firstOrDefault(c => c.hashCode == collider.hashCode))
this._tempHashSet.push(collider);
}
}
@@ -202,7 +202,7 @@ module es {
* @param y
* @param createCellIfEmpty
*/
private cellAtPosition(x: number, y: number, createCellIfEmpty: boolean = false) {
private cellAtPosition(x: number, y: number, createCellIfEmpty: boolean = false): Collider[] {
let cell: Collider[] = this._cellDict.tryGetValue(x, y);
if (!cell) {
if (createCellIfEmpty) {
@@ -262,6 +262,55 @@ module es {
}
export class RaycastResultParser {
public hitCounter: number;
public static compareRaycastHits = (a: RaycastHit, b: RaycastHit) => {
return a.distance - b.distance;
};
public _hits: RaycastHit[];
public _tempHit: RaycastHit;
public _checkedColliders: Collider[] = [];
public _cellHits: RaycastHit[] = [];
public _ray: Ray2D;
public _layerMask: number;
public start(ray: Ray2D, hits: RaycastHit[], layerMask: number){
this._ray = ray;
this._hits = hits;
this._layerMask = layerMask;
this.hitCounter = 0;
}
/**
* 如果hits数组被填充返回true。单元格不能为空!
* @param cellX
* @param cellY
* @param cell
*/
public checkRayIntersection(cellX: number, cellY: number, cell: Collider[]): boolean{
let fraction: number;
for (let i = 0; i < cell.length; i ++) {
let potential = cell[i];
// 管理我们已经处理过的碰撞器
if (this._checkedColliders.contains(potential))
continue;
this._checkedColliders.push(potential);
// 只有当我们被设置为这样做时才会点击触发器
if (potential.isTrigger && !Physics.raycastsHitTriggers)
continue;
// 确保碰撞器在图层蒙版上
if (!Flags.isFlagSet(this._layerMask, potential.physicsLayer))
continue;
// TODO: rayIntersects的性能够吗?需要测试它。Collisions.rectToLine可能更快
// TODO: 如果边界检查返回更多数据我们就不需要为BoxCollider检查做任何事情
// 在做形状测试之前先做一个边界检查
let colliderBounds = potential.bounds;
if (colliderBounds.)
}
}
}
}