新增Physics.linecast/linecastAll方法
This commit is contained in:
@@ -228,6 +228,7 @@ module es {
|
||||
this.addEventListener(egret.Event.ENTER_FRAME, this.update, this);
|
||||
|
||||
Input.initialize();
|
||||
KeyboardUtils.init();
|
||||
this.initialize();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,5 +93,18 @@ module es {
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* 由上移量向上移。start可以小于或大于end。例如:开始是2,结束是10,移位是4,结果是6
|
||||
* @param start
|
||||
* @param end
|
||||
* @param shift
|
||||
*/
|
||||
public static approach(start: number, end: number, shift: number): number {
|
||||
if (start < end)
|
||||
return Math.min(start + shift, end);
|
||||
|
||||
return Math.max(start - shift, end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
///<reference path="./RaycastHit.ts" />
|
||||
module es {
|
||||
export class Physics {
|
||||
/** 调用reset并创建一个新的SpatialHash时使用的单元格大小 */
|
||||
@@ -13,6 +14,12 @@ module es {
|
||||
* 在碰撞器中开始的射线/直线是否强制转换检测到那些碰撞器
|
||||
*/
|
||||
public static raycastsStartInColliders = false;
|
||||
/**
|
||||
* 我们保留它以避免在每次raycast发生时分配它
|
||||
*/
|
||||
public static _hitArray: RaycastHit[] = [
|
||||
new RaycastHit()
|
||||
];
|
||||
|
||||
public static reset() {
|
||||
this._spatialHash = new SpatialHash(this.spatialHashCellSize);
|
||||
@@ -85,6 +92,34 @@ module es {
|
||||
this._spatialHash.register(collider);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回与layerMask匹配的碰撞器的第一次命中
|
||||
* @param start
|
||||
* @param end
|
||||
* @param layerMask
|
||||
*/
|
||||
public static linecast(start: Vector2, end: Vector2, layerMask: number = Physics.allLayers): RaycastHit{
|
||||
this._hitArray[0].reset();
|
||||
this.linecastAll(start, end, this._hitArray, layerMask);
|
||||
return this._hitArray[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过空间散列强制执行一行,并用该行命中的任何碰撞器填充hits数组
|
||||
* @param start
|
||||
* @param end
|
||||
* @param hits
|
||||
* @param layerMask
|
||||
*/
|
||||
public static linecastAll(start: Vector2, end: Vector2, hits: RaycastHit[], layerMask: number = Physics.allLayers){
|
||||
if (hits.length == 0){
|
||||
console.warn("传入了一个空的hits数组。没有点击会被返回");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return this._spatialHash.linecast(start, end, hits, layerMask);
|
||||
}
|
||||
|
||||
/**
|
||||
* debug绘制空间散列的内容
|
||||
* @param secondsToDisplay
|
||||
|
||||
@@ -30,7 +30,7 @@ module es {
|
||||
*/
|
||||
public centroid: Vector2;
|
||||
|
||||
constructor(collider: Collider, fraction: number, distance: number, point: Vector2, normal: Vector2){
|
||||
constructor(collider?: Collider, fraction?: number, distance?: number, point?: Vector2, normal?: Vector2){
|
||||
this.collider = collider;
|
||||
this.fraction = fraction;
|
||||
this.distance = distance;
|
||||
|
||||
@@ -144,6 +144,73 @@ module es {
|
||||
return this._tempHashSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过空间散列强制执行一行,并用该行命中的任何碰撞器填充hits数组。
|
||||
* @param start
|
||||
* @param end
|
||||
* @param hits
|
||||
* @param layerMask
|
||||
*/
|
||||
public linecast(start: Vector2, end: Vector2, hits: RaycastHit[], layerMask: number){
|
||||
let ray = new Ray2D(start, end);
|
||||
this._raycastParser.start(ray, hits, layerMask);
|
||||
|
||||
// 在与网格相同的空间中获取起始/结束位置
|
||||
let currentCell = this.cellCoords(start.x, start.y);
|
||||
let lastCell = this.cellCoords(end.x, end.y);
|
||||
|
||||
let stepX = Math.sign(ray.direction.x);
|
||||
let stepY = Math.sign(ray.direction.y);
|
||||
|
||||
// 我们要确保,如果我们在同一行或同一行,我们不会步进不必要的方向
|
||||
if (currentCell.x == lastCell.x) stepX = 0;
|
||||
if (currentCell.y == lastCell.y) stepY = 0;
|
||||
|
||||
// 计算单元边界。当这一步是正的,下一个单元格在这一步之后意味着我们加1。
|
||||
// 如果为负,则单元格在此之前,这种情况下不添加边界
|
||||
let xStep = stepX < 0 ? 0 : stepX;
|
||||
let yStep = stepY < 0 ? 0 : stepY;
|
||||
let nextBoundaryX = (currentCell.x + xStep) * this._cellSize;
|
||||
let nextBoundaryY = (currentCell.y + yStep) * this._cellSize;
|
||||
|
||||
// 确定射线穿过第一个垂直体素边界时的t值。y/horizontal。
|
||||
// 这两个值的最小值将表明我们可以沿着射线走多少,而仍然保持在当前体素中,对于接近vertical/horizontal的射线来说可能是无限的
|
||||
let tMaxX = ray.direction.x != 0 ? (nextBoundaryX - ray.start.x) / ray.direction.x : Number.MAX_VALUE;
|
||||
let tMaxY = ray.direction.y != 0 ? (nextBoundaryY - ray.start.y) / ray.direction.y : Number.MAX_VALUE;
|
||||
|
||||
let tDeltaX = ray.direction.x != 0 ? this._cellSize / (ray.direction.x * stepX) : Number.MAX_VALUE;
|
||||
let tDeltaY = ray.direction.y != 0 ? this._cellSize / (ray.direction.y * stepY) : Number.MAX_VALUE;
|
||||
|
||||
// 开始遍历并返回交叉单元格。
|
||||
let cell = this.cellAtPosition(currentCell.x, currentCell.y);
|
||||
|
||||
if (cell && this._raycastParser.checkRayIntersection(currentCell.x, currentCell.y, cell)){
|
||||
this._raycastParser.reset();
|
||||
return this._raycastParser.hitCounter;
|
||||
}
|
||||
|
||||
while (currentCell.x != lastCell.x || currentCell.y != lastCell.y){
|
||||
if (tMaxX < tMaxY){
|
||||
currentCell.x = MathHelper.approach(currentCell.x, lastCell.x, Math.abs(stepX));
|
||||
|
||||
tMaxX += tDeltaX;
|
||||
}else{
|
||||
currentCell.y = MathHelper.approach(currentCell.y, lastCell.y, Math.abs(stepY));
|
||||
|
||||
tMaxY += tDeltaY;
|
||||
}
|
||||
|
||||
cell = this.cellAtPosition(currentCell.x, currentCell.y);
|
||||
if (cell && this._raycastParser.checkRayIntersection(currentCell.x, currentCell.y, cell)){
|
||||
this._raycastParser.reset();
|
||||
return this._raycastParser.hitCounter;
|
||||
}
|
||||
}
|
||||
|
||||
this._raycastParser.reset();
|
||||
return this._raycastParser.hitCounter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取位于指定圆内的所有碰撞器
|
||||
* @param circleCenter
|
||||
@@ -268,7 +335,7 @@ module es {
|
||||
};
|
||||
|
||||
public _hits: RaycastHit[];
|
||||
public _tempHit: RaycastHit;
|
||||
public _tempHit: RaycastHit = new RaycastHit();
|
||||
public _checkedColliders: Collider[] = [];
|
||||
public _cellHits: RaycastHit[] = [];
|
||||
public _ray: Ray2D;
|
||||
|
||||
@@ -84,10 +84,10 @@ class KeyboardUtils {
|
||||
private static keyUpDict: Object;
|
||||
|
||||
public static init(): void {
|
||||
this.keyDownDict = {};
|
||||
this.keyUpDict = {};
|
||||
document.addEventListener("keydown", this.onKeyDonwHander);
|
||||
document.addEventListener("keyup", this.onKeyUpHander);
|
||||
KeyboardUtils.keyDownDict = {};
|
||||
KeyboardUtils.keyUpDict = {};
|
||||
document.addEventListener("keydown", KeyboardUtils.onKeyDonwHander);
|
||||
document.addEventListener("keyup", KeyboardUtils.onKeyUpHander);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,16 +115,16 @@ class KeyboardUtils {
|
||||
* 销毁方法
|
||||
*/
|
||||
public static destroy(): void {
|
||||
this.keyDownDict = null;
|
||||
this.keyUpDict = null;
|
||||
KeyboardUtils.keyDownDict = null;
|
||||
KeyboardUtils.keyUpDict = null;
|
||||
document.removeEventListener("keydown", this.onKeyDonwHander);
|
||||
document.removeEventListener("keyup", this.onKeyUpHander);
|
||||
}
|
||||
|
||||
private static onKeyDonwHander(event: KeyboardEvent): void {
|
||||
if (!this.keyDownDict) return;
|
||||
var key: string = this.keyCodeToString(event.keyCode);
|
||||
var o: Object = this.keyDownDict[key];
|
||||
if (!KeyboardUtils.keyDownDict) return;
|
||||
var key: string = KeyboardUtils.keyCodeToString(event.keyCode);
|
||||
var o: Object = KeyboardUtils.keyDownDict[key];
|
||||
if (o) {
|
||||
var fun: Function = o["fun"];
|
||||
var thisObj: any = o["thisObj"];
|
||||
@@ -134,9 +134,9 @@ class KeyboardUtils {
|
||||
}
|
||||
|
||||
private static onKeyUpHander(event: KeyboardEvent): void {
|
||||
if (!this.keyUpDict) return;
|
||||
var key: string = this.keyCodeToString(event.keyCode);
|
||||
var o: Object = this.keyUpDict[key];
|
||||
if (!KeyboardUtils.keyUpDict) return;
|
||||
var key: string = KeyboardUtils.keyCodeToString(event.keyCode);
|
||||
var o: Object = KeyboardUtils.keyUpDict[key];
|
||||
if (o) {
|
||||
var fun: Function = o["fun"];
|
||||
var thisObj: any = o["thisObj"];
|
||||
|
||||
Reference in New Issue
Block a user