reformat code
This commit is contained in:
@@ -10,7 +10,7 @@ module es {
|
||||
* @param start
|
||||
* @param goal
|
||||
*/
|
||||
public static search<T>(graph: IAstarGraph<T>, start: T, goal: T){
|
||||
public static search<T>(graph: IAstarGraph<T>, start: T, goal: T) {
|
||||
let foundPath = false;
|
||||
let cameFrom = new Map<T, T>();
|
||||
cameFrom.set(start, start);
|
||||
@@ -21,17 +21,17 @@ module es {
|
||||
|
||||
costSoFar.set(start, 0);
|
||||
|
||||
while (frontier.count > 0){
|
||||
while (frontier.count > 0) {
|
||||
let current = frontier.dequeue();
|
||||
|
||||
if (JSON.stringify(current.data) == JSON.stringify(goal)){
|
||||
if (JSON.stringify(current.data) == JSON.stringify(goal)) {
|
||||
foundPath = true;
|
||||
break;
|
||||
}
|
||||
|
||||
graph.getNeighbors(current.data).forEach(next => {
|
||||
let newCost = costSoFar.get(current.data) + graph.cost(current.data, next);
|
||||
if (!this.hasKey(costSoFar, next) || newCost < costSoFar.get(next)){
|
||||
if (!this.hasKey(costSoFar, next) || newCost < costSoFar.get(next)) {
|
||||
costSoFar.set(next, newCost);
|
||||
let priority = newCost + graph.heuristic(next, goal);
|
||||
frontier.enqueue(new AStarNode<T>(next), priority);
|
||||
@@ -43,7 +43,28 @@ module es {
|
||||
return foundPath ? this.recontructPath(cameFrom, start, goal) : null;
|
||||
}
|
||||
|
||||
private static hasKey<T>(map: Map<T, number>, compareKey: T){
|
||||
/**
|
||||
* 从cameFrom字典重新构造路径
|
||||
* @param cameFrom
|
||||
* @param start
|
||||
* @param goal
|
||||
*/
|
||||
public static recontructPath<T>(cameFrom: Map<T, T>, start: T, goal: T): T[] {
|
||||
let path = [];
|
||||
let current = goal;
|
||||
path.push(goal);
|
||||
|
||||
while (current != start) {
|
||||
current = this.getKey(cameFrom, current);
|
||||
path.push(current);
|
||||
}
|
||||
|
||||
path.reverse();
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
private static hasKey<T>(map: Map<T, number>, compareKey: T) {
|
||||
let iterator = map.keys();
|
||||
let r: IteratorResult<T>;
|
||||
while (r = iterator.next() , !r.done) {
|
||||
@@ -54,7 +75,7 @@ module es {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static getKey<T>(map: Map<T, T>, compareKey: T){
|
||||
private static getKey<T>(map: Map<T, T>, compareKey: T) {
|
||||
let iterator = map.keys();
|
||||
let valueIterator = map.values();
|
||||
let r: IteratorResult<T>;
|
||||
@@ -66,27 +87,6 @@ module es {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从cameFrom字典重新构造路径
|
||||
* @param cameFrom
|
||||
* @param start
|
||||
* @param goal
|
||||
*/
|
||||
public static recontructPath<T>(cameFrom: Map<T, T>, start: T, goal: T): T[]{
|
||||
let path = [];
|
||||
let current = goal;
|
||||
path.push(goal);
|
||||
|
||||
while (current != start){
|
||||
current = this.getKey(cameFrom, current);
|
||||
path.push(current);
|
||||
}
|
||||
|
||||
path.reverse();
|
||||
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,7 +95,7 @@ module es {
|
||||
export class AStarNode<T> extends PriorityQueueNode {
|
||||
public data: T;
|
||||
|
||||
constructor(data: T){
|
||||
constructor(data: T) {
|
||||
super();
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ module es {
|
||||
private _height;
|
||||
private _neighbors: Vector2[] = new Array(4);
|
||||
|
||||
constructor(width: number, height: number){
|
||||
constructor(width: number, height: number) {
|
||||
this._width = width;
|
||||
this._height = height;
|
||||
}
|
||||
@@ -46,7 +46,7 @@ module es {
|
||||
* @param start
|
||||
* @param goal
|
||||
*/
|
||||
public search(start: Vector2, goal: Vector2){
|
||||
public search(start: Vector2, goal: Vector2) {
|
||||
return AStarPathfinder.search(this, start, goal);
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ module es {
|
||||
}
|
||||
|
||||
public cost(from: Vector2, to: Vector2): number {
|
||||
return this.weightedNodes.find((p)=> JSON.stringify(p) == JSON.stringify(to)) ? this.weightedNodeWeight : this.defaultWeight;
|
||||
return this.weightedNodes.find((p) => JSON.stringify(p) == JSON.stringify(to)) ? this.weightedNodeWeight : this.defaultWeight;
|
||||
}
|
||||
|
||||
public heuristic(node: Vector2, goal: Vector2) {
|
||||
|
||||
@@ -8,12 +8,14 @@ module es {
|
||||
* @param node
|
||||
*/
|
||||
getNeighbors(node: T): Array<T>;
|
||||
|
||||
/**
|
||||
* 计算从从from到to的成本
|
||||
* @param from
|
||||
* @param to
|
||||
*/
|
||||
cost(from: T, to: T): number;
|
||||
|
||||
/**
|
||||
* 计算从node到to的启发式。参见WeightedGridGraph了解常用的Manhatten方法。
|
||||
* @param node
|
||||
|
||||
@@ -19,15 +19,6 @@ module es {
|
||||
this._numNodesEverEnqueued = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从队列中删除每个节点。
|
||||
* O(n)复杂度 所有尽可能少调用该方法
|
||||
*/
|
||||
public clear() {
|
||||
this._nodes.splice(1, this._numNodes);
|
||||
this._numNodes = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回队列中的节点数。
|
||||
* O(1)复杂度
|
||||
@@ -44,18 +35,27 @@ module es {
|
||||
return this._nodes.length - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从队列中删除每个节点。
|
||||
* O(n)复杂度 所有尽可能少调用该方法
|
||||
*/
|
||||
public clear() {
|
||||
this._nodes.splice(1, this._numNodes);
|
||||
this._numNodes = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回(在O(1)中)给定节点是否在队列中
|
||||
* O (1)复杂度
|
||||
* @param node
|
||||
*/
|
||||
public contains(node: T): boolean {
|
||||
if (!node){
|
||||
if (!node) {
|
||||
console.error("node cannot be null");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (node.queueIndex < 0 || node.queueIndex >= this._nodes.length){
|
||||
if (node.queueIndex < 0 || node.queueIndex >= this._nodes.length) {
|
||||
console.error("node.QueueIndex has been corrupted. Did you change it manually? Or add this node to another queue?");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ module es {
|
||||
* 计算路径给定的IUnweightedGraph和开始/目标位置
|
||||
*/
|
||||
export class BreadthFirstPathfinder {
|
||||
public static search<T>(graph: IUnweightedGraph<T>, start: T, goal: T): T[]{
|
||||
public static search<T>(graph: IUnweightedGraph<T>, start: T, goal: T): T[] {
|
||||
let foundPath = false;
|
||||
let frontier = [];
|
||||
frontier.unshift(start);
|
||||
@@ -11,15 +11,15 @@ module es {
|
||||
let cameFrom = new Map<T, T>();
|
||||
cameFrom.set(start, start);
|
||||
|
||||
while (frontier.length > 0){
|
||||
while (frontier.length > 0) {
|
||||
let current = frontier.shift();
|
||||
if (JSON.stringify(current) == JSON.stringify(goal)){
|
||||
if (JSON.stringify(current) == JSON.stringify(goal)) {
|
||||
foundPath = true;
|
||||
break;
|
||||
}
|
||||
|
||||
graph.getNeighbors(current).forEach(next => {
|
||||
if (!this.hasKey(cameFrom, next)){
|
||||
if (!this.hasKey(cameFrom, next)) {
|
||||
frontier.unshift(next);
|
||||
cameFrom.set(next, current);
|
||||
}
|
||||
@@ -29,7 +29,7 @@ module es {
|
||||
return foundPath ? AStarPathfinder.recontructPath(cameFrom, start, goal) : null;
|
||||
}
|
||||
|
||||
private static hasKey<T>(map: Map<T, T>, compareKey: T){
|
||||
private static hasKey<T>(map: Map<T, T>, compareKey: T) {
|
||||
let iterator = map.keys();
|
||||
let r: IteratorResult<T>;
|
||||
while (r = iterator.next() , !r.done) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module es {
|
||||
export interface IUnweightedGraph<T>{
|
||||
export interface IUnweightedGraph<T> {
|
||||
/**
|
||||
* getNeighbors方法应该返回从传入的节点可以到达的任何相邻节点。
|
||||
* @param node
|
||||
|
||||
@@ -6,12 +6,12 @@ module es {
|
||||
export class UnweightedGraph<T> implements IUnweightedGraph<T> {
|
||||
public edges: Map<T, T[]> = new Map<T, T[]>();
|
||||
|
||||
public addEdgesForNode(node: T, edges: T[]){
|
||||
public addEdgesForNode(node: T, edges: T[]) {
|
||||
this.edges.set(node, edges);
|
||||
return this;
|
||||
}
|
||||
|
||||
public getNeighbors(node: T){
|
||||
public getNeighbors(node: T) {
|
||||
return this.edges.get(node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module es {
|
||||
export interface IWeightedGraph<T>{
|
||||
export interface IWeightedGraph<T> {
|
||||
/**
|
||||
*
|
||||
* @param node
|
||||
|
||||
@@ -32,13 +32,13 @@ module es {
|
||||
private _dirs: Vector2[];
|
||||
private _neighbors: Vector2[] = new Array(4);
|
||||
|
||||
constructor(width: number, height: number, allowDiagonalSearch: boolean = false){
|
||||
constructor(width: number, height: number, allowDiagonalSearch: boolean = false) {
|
||||
this._width = width;
|
||||
this._height = height;
|
||||
this._dirs = allowDiagonalSearch ? WeightedGridGraph.COMPASS_DIRS : WeightedGridGraph.CARDINAL_DIRS;
|
||||
}
|
||||
|
||||
public isNodeInBounds(node: Vector2){
|
||||
public isNodeInBounds(node: Vector2) {
|
||||
return 0 <= node.x && node.x < this._width && 0 <= node.y && node.y < this._height;
|
||||
}
|
||||
|
||||
@@ -46,11 +46,11 @@ module es {
|
||||
return !this.walls.firstOrDefault(wall => JSON.stringify(wall) == JSON.stringify(node));
|
||||
}
|
||||
|
||||
public search(start: Vector2, goal: Vector2){
|
||||
public search(start: Vector2, goal: Vector2) {
|
||||
return WeightedPathfinder.search(this, start, goal);
|
||||
}
|
||||
|
||||
public getNeighbors(node: Vector2): Vector2[]{
|
||||
public getNeighbors(node: Vector2): Vector2[] {
|
||||
this._neighbors.length = 0;
|
||||
|
||||
this._dirs.forEach(dir => {
|
||||
@@ -62,7 +62,7 @@ module es {
|
||||
return this._neighbors;
|
||||
}
|
||||
|
||||
public cost(from: Vector2, to: Vector2): number{
|
||||
public cost(from: Vector2, to: Vector2): number {
|
||||
return this.weightedNodes.find(t => JSON.stringify(t) == JSON.stringify(to)) ? this.weightedNodeWeight : this.defaultWeight;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,14 +2,14 @@ module es {
|
||||
export class WeightedNode<T> extends PriorityQueueNode {
|
||||
public data: T;
|
||||
|
||||
constructor(data: T){
|
||||
constructor(data: T) {
|
||||
super();
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
||||
export class WeightedPathfinder {
|
||||
public static search<T>(graph: IWeightedGraph<T>, start: T, goal: T){
|
||||
public static search<T>(graph: IWeightedGraph<T>, start: T, goal: T) {
|
||||
let foundPath = false;
|
||||
|
||||
let cameFrom = new Map<T, T>();
|
||||
@@ -21,17 +21,17 @@ module es {
|
||||
|
||||
costSoFar.set(start, 0);
|
||||
|
||||
while (frontier.count > 0){
|
||||
while (frontier.count > 0) {
|
||||
let current = frontier.dequeue();
|
||||
|
||||
if (JSON.stringify(current.data) == JSON.stringify(goal)){
|
||||
if (JSON.stringify(current.data) == JSON.stringify(goal)) {
|
||||
foundPath = true;
|
||||
break;
|
||||
}
|
||||
|
||||
graph.getNeighbors(current.data).forEach(next => {
|
||||
let newCost = costSoFar.get(current.data) + graph.cost(current.data, next);
|
||||
if (!this.hasKey(costSoFar, next) || newCost < costSoFar.get(next)){
|
||||
if (!this.hasKey(costSoFar, next) || newCost < costSoFar.get(next)) {
|
||||
costSoFar.set(next, newCost);
|
||||
let priprity = newCost;
|
||||
frontier.enqueue(new WeightedNode<T>(next), priprity);
|
||||
@@ -43,7 +43,22 @@ module es {
|
||||
return foundPath ? this.recontructPath(cameFrom, start, goal) : null;
|
||||
}
|
||||
|
||||
private static hasKey<T>(map: Map<T, number>, compareKey: T){
|
||||
public static recontructPath<T>(cameFrom: Map<T, T>, start: T, goal: T): T[] {
|
||||
let path = [];
|
||||
let current = goal;
|
||||
path.push(goal);
|
||||
|
||||
while (current != start) {
|
||||
current = this.getKey(cameFrom, current);
|
||||
path.push(current);
|
||||
}
|
||||
|
||||
path.reverse();
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
private static hasKey<T>(map: Map<T, number>, compareKey: T) {
|
||||
let iterator = map.keys();
|
||||
let r: IteratorResult<T>;
|
||||
while (r = iterator.next() , !r.done) {
|
||||
@@ -54,7 +69,7 @@ module es {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static getKey<T>(map: Map<T, T>, compareKey: T){
|
||||
private static getKey<T>(map: Map<T, T>, compareKey: T) {
|
||||
let iterator = map.keys();
|
||||
let valueIterator = map.values();
|
||||
let r: IteratorResult<T>;
|
||||
@@ -66,20 +81,5 @@ module es {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static recontructPath<T>(cameFrom: Map<T, T>, start: T, goal: T): T[]{
|
||||
let path = [];
|
||||
let current = goal;
|
||||
path.push(goal);
|
||||
|
||||
while (current != start){
|
||||
current = this.getKey(cameFrom, current);
|
||||
path.push(current);
|
||||
}
|
||||
|
||||
path.reverse();
|
||||
|
||||
return path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,18 +2,18 @@ module es {
|
||||
export class Debug {
|
||||
private static _debugDrawItems: DebugDrawItem[] = [];
|
||||
|
||||
public static drawHollowRect(rectanle: Rectangle, color: number, duration = 0){
|
||||
public static drawHollowRect(rectanle: Rectangle, color: number, duration = 0) {
|
||||
this._debugDrawItems.push(new DebugDrawItem(rectanle, color, duration));
|
||||
}
|
||||
|
||||
public static render(){
|
||||
if (this._debugDrawItems.length > 0){
|
||||
public static render() {
|
||||
if (this._debugDrawItems.length > 0) {
|
||||
let debugShape = new egret.Shape();
|
||||
if (Core.scene){
|
||||
if (Core.scene) {
|
||||
Core.scene.addChild(debugShape);
|
||||
}
|
||||
|
||||
for (let i = this._debugDrawItems.length - 1; i >= 0; i --){
|
||||
for (let i = this._debugDrawItems.length - 1; i >= 0; i--) {
|
||||
let item = this._debugDrawItems[i];
|
||||
if (item.draw(debugShape))
|
||||
this._debugDrawItems.removeAt(i);
|
||||
|
||||
@@ -18,15 +18,15 @@ module es {
|
||||
public y: number;
|
||||
public size: number;
|
||||
|
||||
constructor(rectangle: Rectangle, color: number, duration: number){
|
||||
constructor(rectangle: Rectangle, color: number, duration: number) {
|
||||
this.rectangle = rectangle;
|
||||
this.color = color;
|
||||
this.duration = duration;
|
||||
this.drawType = DebugDrawType.hollowRectangle;
|
||||
}
|
||||
|
||||
public draw(shape: egret.Shape): boolean{
|
||||
switch (this.drawType){
|
||||
public draw(shape: egret.Shape): boolean {
|
||||
switch (this.drawType) {
|
||||
case DebugDrawType.line:
|
||||
DrawUtils.drawLine(shape, this.start, this.end, this.color);
|
||||
break;
|
||||
|
||||
@@ -12,6 +12,10 @@ module es {
|
||||
* 此组件附加的实体
|
||||
*/
|
||||
public entity: Entity;
|
||||
/**
|
||||
* 更新该组件的时间间隔。这与实体的更新间隔无关。
|
||||
*/
|
||||
public updateInterval: number = 1;
|
||||
|
||||
/**
|
||||
* 快速访问 this.entity.transform
|
||||
@@ -20,6 +24,8 @@ module es {
|
||||
return this.entity.transform;
|
||||
}
|
||||
|
||||
private _enabled: boolean = true;
|
||||
|
||||
/**
|
||||
* 如果组件和实体都已启用,则为。当启用该组件时,将调用该组件的生命周期方法。状态的改变会导致调用onEnabled/onDisable。
|
||||
*/
|
||||
@@ -35,6 +41,8 @@ module es {
|
||||
this.setEnabled(value);
|
||||
}
|
||||
|
||||
private _updateOrder = 0;
|
||||
|
||||
/** 更新此实体上组件的顺序 */
|
||||
public get updateOrder() {
|
||||
return this._updateOrder;
|
||||
@@ -45,14 +53,6 @@ module es {
|
||||
this.setUpdateOrder(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新该组件的时间间隔。这与实体的更新间隔无关。
|
||||
*/
|
||||
public updateInterval: number = 1;
|
||||
|
||||
private _enabled: boolean = true;
|
||||
private _updateOrder = 0;
|
||||
|
||||
/**
|
||||
* 当此组件已分配其实体,但尚未添加到实体的活动组件列表时调用。有用的东西,如物理组件,需要访问转换来修改碰撞体的属性。
|
||||
*/
|
||||
|
||||
@@ -12,6 +12,46 @@ module es {
|
||||
}
|
||||
|
||||
export class Camera extends Component {
|
||||
public _inset: CameraInset = new CameraInset();
|
||||
public _areMatrixedDirty: boolean = true;
|
||||
public _areBoundsDirty: boolean = true;
|
||||
public _isProjectionMatrixDirty = true;
|
||||
/**
|
||||
* 如果相机模式为cameraWindow 则会进行缓动移动
|
||||
* 该值为移动速度
|
||||
*/
|
||||
public followLerp = 0.1;
|
||||
/**
|
||||
* 在cameraWindow模式下,宽度/高度被用做边界框,允许在不移动相机的情况下移动
|
||||
* 在lockOn模式下,只使用deadZone的x/y值 你可以通过直接setCenteredDeadzone重写它来自定义deadZone
|
||||
*/
|
||||
public deadzone: Rectangle = new Rectangle();
|
||||
/**
|
||||
* 相机聚焦于屏幕中心的偏移
|
||||
*/
|
||||
public focusOffset: Vector2 = Vector2.zero;
|
||||
/**
|
||||
* 如果为true 相机位置则不会超出地图矩形(0, 0, mapwidth, mapheight)
|
||||
*/
|
||||
public mapLockEnabled: boolean = false;
|
||||
/**
|
||||
* 當前地圖映射的寬度和高度
|
||||
*/
|
||||
public mapSize: Vector2 = Vector2.zero;
|
||||
public _targetEntity: Entity;
|
||||
public _targetCollider: Collider;
|
||||
public _desiredPositionDelta: Vector2 = new Vector2();
|
||||
public _cameraStyle: CameraStyle;
|
||||
public _worldSpaceDeadZone: Rectangle = new Rectangle();
|
||||
|
||||
constructor(targetEntity: Entity = null, cameraStyle: CameraStyle = CameraStyle.lockOn) {
|
||||
super();
|
||||
|
||||
this._targetEntity = targetEntity;
|
||||
this._cameraStyle = cameraStyle;
|
||||
this.setZoom(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对entity.transform.position的快速访问
|
||||
*/
|
||||
@@ -42,6 +82,8 @@ module es {
|
||||
this.entity.transform.rotation = value;
|
||||
}
|
||||
|
||||
public _zoom;
|
||||
|
||||
/**
|
||||
* 缩放值应该在-1和1之间、然后将该值从minimumZoom转换为maximumZoom。
|
||||
* 允许你设置适当的最小/最大值,然后使用更直观的-1到1的映射来更改缩放
|
||||
@@ -65,6 +107,8 @@ module es {
|
||||
this.setZoom(value);
|
||||
}
|
||||
|
||||
public _minimumZoom = 0.3;
|
||||
|
||||
/**
|
||||
* 相机变焦可以达到的最小非缩放值(0-number.max)。默认为0.3
|
||||
*/
|
||||
@@ -80,6 +124,8 @@ module es {
|
||||
this.setMinimumZoom(value);
|
||||
}
|
||||
|
||||
public _maximumZoom = 3;
|
||||
|
||||
/**
|
||||
* 相机变焦可以达到的最大非缩放值(0-number.max)。默认为3
|
||||
*/
|
||||
@@ -95,20 +141,22 @@ module es {
|
||||
this.setMaximumZoom(value);
|
||||
}
|
||||
|
||||
public _bounds: Rectangle = new Rectangle();
|
||||
|
||||
/**
|
||||
* 相机的世界-空间边界
|
||||
*/
|
||||
public get bounds(){
|
||||
public get bounds() {
|
||||
if (this._areMatrixedDirty)
|
||||
this.updateMatrixes();
|
||||
|
||||
if (this._areBoundsDirty){
|
||||
if (this._areBoundsDirty) {
|
||||
// 旋转或非旋转的边界都需要左上角和右下角
|
||||
let topLeft = this.screenToWorldPoint(new Vector2(this._inset.left, this._inset.top));
|
||||
let bottomRight = this.screenToWorldPoint(new Vector2(Core.graphicsDevice.viewport.width - this._inset.right,
|
||||
Core.graphicsDevice.viewport.height - this._inset.bottom));
|
||||
|
||||
if (this.entity.transform.rotation != 0){
|
||||
if (this.entity.transform.rotation != 0) {
|
||||
// 特别注意旋转的边界。我们需要找到绝对的最小/最大值并从中创建边界
|
||||
let topRight = this.screenToWorldPoint(new Vector2(Core.graphicsDevice.viewport.width - this._inset.right,
|
||||
this._inset.top));
|
||||
@@ -135,6 +183,8 @@ module es {
|
||||
return this._bounds;
|
||||
}
|
||||
|
||||
public _transformMatrix: Matrix2D = new Matrix2D().identity();
|
||||
|
||||
/**
|
||||
* 用于从世界坐标转换到屏幕
|
||||
*/
|
||||
@@ -144,6 +194,8 @@ module es {
|
||||
return this._transformMatrix;
|
||||
}
|
||||
|
||||
public _inverseTransformMatrix: Matrix2D = new Matrix2D().identity();
|
||||
|
||||
/**
|
||||
* 用于从屏幕坐标到世界的转换
|
||||
*/
|
||||
@@ -153,6 +205,8 @@ module es {
|
||||
return this._inverseTransformMatrix;
|
||||
}
|
||||
|
||||
public _origin: Vector2 = Vector2.zero;
|
||||
|
||||
public get origin() {
|
||||
return this._origin;
|
||||
}
|
||||
@@ -164,56 +218,6 @@ module es {
|
||||
}
|
||||
}
|
||||
|
||||
public _zoom;
|
||||
public _minimumZoom = 0.3;
|
||||
public _maximumZoom = 3;
|
||||
public _bounds: Rectangle = new Rectangle();
|
||||
public _inset: CameraInset = new CameraInset();
|
||||
public _transformMatrix: Matrix2D = new Matrix2D().identity();
|
||||
public _inverseTransformMatrix: Matrix2D = new Matrix2D().identity();
|
||||
public _origin: Vector2 = Vector2.zero;
|
||||
|
||||
public _areMatrixedDirty: boolean = true;
|
||||
public _areBoundsDirty: boolean = true;
|
||||
public _isProjectionMatrixDirty = true;
|
||||
|
||||
/**
|
||||
* 如果相机模式为cameraWindow 则会进行缓动移动
|
||||
* 该值为移动速度
|
||||
*/
|
||||
public followLerp = 0.1;
|
||||
/**
|
||||
* 在cameraWindow模式下,宽度/高度被用做边界框,允许在不移动相机的情况下移动
|
||||
* 在lockOn模式下,只使用deadZone的x/y值 你可以通过直接setCenteredDeadzone重写它来自定义deadZone
|
||||
*/
|
||||
public deadzone: Rectangle = new Rectangle();
|
||||
/**
|
||||
* 相机聚焦于屏幕中心的偏移
|
||||
*/
|
||||
public focusOffset: Vector2 = Vector2.zero;
|
||||
/**
|
||||
* 如果为true 相机位置则不会超出地图矩形(0, 0, mapwidth, mapheight)
|
||||
*/
|
||||
public mapLockEnabled: boolean = false;
|
||||
/**
|
||||
* 當前地圖映射的寬度和高度
|
||||
*/
|
||||
public mapSize: Vector2 = Vector2.zero;
|
||||
|
||||
public _targetEntity: Entity;
|
||||
public _targetCollider: Collider;
|
||||
public _desiredPositionDelta: Vector2 = new Vector2();
|
||||
public _cameraStyle: CameraStyle;
|
||||
public _worldSpaceDeadZone: Rectangle = new Rectangle();
|
||||
|
||||
constructor(targetEntity: Entity = null, cameraStyle: CameraStyle = CameraStyle.lockOn) {
|
||||
super();
|
||||
|
||||
this._targetEntity = targetEntity;
|
||||
this._cameraStyle = cameraStyle;
|
||||
this.setZoom(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当场景渲染目标的大小发生变化时,我们会更新相机的原点并调整它的位置以保持它原来的位置
|
||||
* @param newWidth
|
||||
@@ -226,33 +230,6 @@ module es {
|
||||
this.entity.transform.position = Vector2.add(this.entity.transform.position, Vector2.subtract(this._origin, oldOrigin));
|
||||
}
|
||||
|
||||
protected updateMatrixes(){
|
||||
if (!this._areMatrixedDirty)
|
||||
return;
|
||||
|
||||
let tempMat: Matrix2D;
|
||||
this._transformMatrix = Matrix2D.create().translate(-this.entity.transform.position.x, -this.entity.transform.position.y);
|
||||
|
||||
if (this._zoom != 1){
|
||||
tempMat = Matrix2D.create().scale(this._zoom, this._zoom);
|
||||
this._transformMatrix = this._transformMatrix.multiply(tempMat);
|
||||
}
|
||||
|
||||
if (this.entity.transform.rotation != 0){
|
||||
tempMat = Matrix2D.create().rotate(this.entity.transform.rotation);
|
||||
this._transformMatrix = this._transformMatrix.multiply(tempMat);
|
||||
}
|
||||
|
||||
tempMat = Matrix2D.create().translate(this._origin.x, this._origin.y);
|
||||
this._transformMatrix =this._transformMatrix.multiply(tempMat);
|
||||
|
||||
this._inverseTransformMatrix = this._transformMatrix.invert();
|
||||
|
||||
// 无论何时矩阵改变边界都是无效的
|
||||
this._areBoundsDirty = true;
|
||||
this._areMatrixedDirty = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置用于从视口边缘插入摄像机边界的量
|
||||
* @param left
|
||||
@@ -357,7 +334,7 @@ module es {
|
||||
* 将一个点从世界坐标转换到屏幕
|
||||
* @param worldPosition
|
||||
*/
|
||||
public worldToScreenPoint(worldPosition: Vector2): Vector2{
|
||||
public worldToScreenPoint(worldPosition: Vector2): Vector2 {
|
||||
this.updateMatrixes();
|
||||
worldPosition = Vector2.transform(worldPosition, this._transformMatrix);
|
||||
return worldPosition;
|
||||
@@ -367,7 +344,7 @@ module es {
|
||||
* 将点从屏幕坐标转换为世界坐标
|
||||
* @param screenPosition
|
||||
*/
|
||||
public screenToWorldPoint(screenPosition: Vector2): Vector2{
|
||||
public screenToWorldPoint(screenPosition: Vector2): Vector2 {
|
||||
this.updateMatrixes();
|
||||
screenPosition = Vector2.transform(screenPosition, this._inverseTransformMatrix);
|
||||
return screenPosition;
|
||||
@@ -376,7 +353,7 @@ module es {
|
||||
/**
|
||||
* 返回鼠标在世界空间中的位置
|
||||
*/
|
||||
public mouseToWorldPoint(): Vector2{
|
||||
public mouseToWorldPoint(): Vector2 {
|
||||
return this.screenToWorldPoint(Input.touchPosition);
|
||||
}
|
||||
|
||||
@@ -476,5 +453,32 @@ module es {
|
||||
public setCenteredDeadzone(width: number, height: number) {
|
||||
this.deadzone = new Rectangle((this.bounds.width - width) / 2, (this.bounds.height - height) / 2, width, height);
|
||||
}
|
||||
|
||||
protected updateMatrixes() {
|
||||
if (!this._areMatrixedDirty)
|
||||
return;
|
||||
|
||||
let tempMat: Matrix2D;
|
||||
this._transformMatrix = Matrix2D.create().translate(-this.entity.transform.position.x, -this.entity.transform.position.y);
|
||||
|
||||
if (this._zoom != 1) {
|
||||
tempMat = Matrix2D.create().scale(this._zoom, this._zoom);
|
||||
this._transformMatrix = this._transformMatrix.multiply(tempMat);
|
||||
}
|
||||
|
||||
if (this.entity.transform.rotation != 0) {
|
||||
tempMat = Matrix2D.create().rotate(this.entity.transform.rotation);
|
||||
this._transformMatrix = this._transformMatrix.multiply(tempMat);
|
||||
}
|
||||
|
||||
tempMat = Matrix2D.create().translate(this._origin.x, this._origin.y);
|
||||
this._transformMatrix = this._transformMatrix.multiply(tempMat);
|
||||
|
||||
this._inverseTransformMatrix = this._transformMatrix.invert();
|
||||
|
||||
// 无论何时矩阵改变边界都是无效的
|
||||
this._areBoundsDirty = true;
|
||||
this._areMatrixedDirty = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
module es {
|
||||
export class ComponentPool<T extends PooledComponent>{
|
||||
export class ComponentPool<T extends PooledComponent> {
|
||||
private _cache: T[];
|
||||
private _type: any;
|
||||
|
||||
constructor(typeClass: any){
|
||||
constructor(typeClass: any) {
|
||||
this._type = typeClass;
|
||||
this._cache = [];
|
||||
}
|
||||
|
||||
public obtain(): T{
|
||||
public obtain(): T {
|
||||
try {
|
||||
return this._cache.length > 0 ? this._cache.shift() : new this._type();
|
||||
} catch(err){
|
||||
} catch (err) {
|
||||
throw new Error(this._type + err);
|
||||
}
|
||||
}
|
||||
|
||||
public free(component: T){
|
||||
public free(component: T) {
|
||||
component.reset();
|
||||
this._cache.push(component);
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ module es {
|
||||
* 用于比较组件更新排序
|
||||
*/
|
||||
export class IUpdatableComparer {
|
||||
public compare(a: Component, b: Component){
|
||||
return a.updateOrder - b.updateOrder;
|
||||
}
|
||||
public compare(a: Component, b: Component) {
|
||||
return a.updateOrder - b.updateOrder;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,13 +3,13 @@ module es {
|
||||
export class Mesh extends RenderableComponent {
|
||||
private _mesh: egret.Mesh;
|
||||
|
||||
constructor(){
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this._mesh = new egret.Mesh();
|
||||
}
|
||||
|
||||
public setTexture(texture: egret.Texture): Mesh{
|
||||
public setTexture(texture: egret.Texture): Mesh {
|
||||
this._mesh.texture = texture;
|
||||
|
||||
return this;
|
||||
|
||||
@@ -1,26 +1,10 @@
|
||||
///<reference path="./Collider.ts" />
|
||||
module es {
|
||||
export class BoxCollider extends Collider {
|
||||
public get width(){
|
||||
return (this.shape as Box).width;
|
||||
}
|
||||
|
||||
public set width(value: number){
|
||||
this.setWidth(value);
|
||||
}
|
||||
|
||||
public get height(){
|
||||
return (this.shape as Box).height;
|
||||
}
|
||||
|
||||
public set height(value: number){
|
||||
this.setHeight(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 零参数构造函数要求RenderableComponent在实体上,这样碰撞器可以在实体被添加到场景时调整自身的大小。
|
||||
*/
|
||||
constructor(){
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
// 我们在这里插入一个1x1框作为占位符,直到碰撞器在下一阵被添加到实体并可以获得更精确的自动调整大小数据
|
||||
@@ -28,15 +12,31 @@ module es {
|
||||
this._colliderRequiresAutoSizing = true;
|
||||
}
|
||||
|
||||
public get width() {
|
||||
return (this.shape as Box).width;
|
||||
}
|
||||
|
||||
public set width(value: number) {
|
||||
this.setWidth(value);
|
||||
}
|
||||
|
||||
public get height() {
|
||||
return (this.shape as Box).height;
|
||||
}
|
||||
|
||||
public set height(value: number) {
|
||||
this.setHeight(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置BoxCollider的大小
|
||||
* @param width
|
||||
* @param height
|
||||
*/
|
||||
public setSize(width: number, height: number){
|
||||
public setSize(width: number, height: number) {
|
||||
this._colliderRequiresAutoSizing = false;
|
||||
let box = this.shape as Box;
|
||||
if (width != box.width || height != box.height){
|
||||
if (width != box.width || height != box.height) {
|
||||
// 更新框,改变边界,如果我们需要更新物理系统中的边界
|
||||
box.updateBox(width, height);
|
||||
if (this.entity && this._isParentEntityAddedToScene)
|
||||
@@ -50,10 +50,10 @@ module es {
|
||||
* 设置BoxCollider的宽度
|
||||
* @param width
|
||||
*/
|
||||
public setWidth(width: number): BoxCollider{
|
||||
public setWidth(width: number): BoxCollider {
|
||||
this._colliderRequiresAutoSizing = false;
|
||||
let box = this.shape as Box;
|
||||
if (width != box.width){
|
||||
if (width != box.width) {
|
||||
// 更新框,改变边界,如果我们需要更新物理系统中的边界
|
||||
box.updateBox(width, box.height);
|
||||
if (this.entity && this._isParentEntityAddedToScene)
|
||||
@@ -67,10 +67,10 @@ module es {
|
||||
* 设置BoxCollider的高度
|
||||
* @param height
|
||||
*/
|
||||
public setHeight(height: number){
|
||||
public setHeight(height: number) {
|
||||
this._colliderRequiresAutoSizing = false;
|
||||
let box = this.shape as Box;
|
||||
if (height != box.height){
|
||||
if (height != box.height) {
|
||||
// 更新框,改变边界,如果我们需要更新物理系统中的边界
|
||||
box.updateBox(box.width, height);
|
||||
if (this.entity && this._isParentEntityAddedToScene)
|
||||
@@ -78,7 +78,7 @@ module es {
|
||||
}
|
||||
}
|
||||
|
||||
public toString(){
|
||||
public toString() {
|
||||
return `[BoxCollider: bounds: ${this.bounds}]`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
module es {
|
||||
export class CircleCollider extends Collider {
|
||||
public get radius(): number {
|
||||
return (this.shape as Circle).radius;
|
||||
}
|
||||
|
||||
public set radius(value: number) {
|
||||
this.setRadius(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个有半径的圆
|
||||
*
|
||||
@@ -23,6 +15,14 @@ module es {
|
||||
this.shape = new Circle(radius ? radius : 1);
|
||||
}
|
||||
|
||||
public get radius(): number {
|
||||
return (this.shape as Circle).radius;
|
||||
}
|
||||
|
||||
public set radius(value: number) {
|
||||
this.setRadius(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置圆的半径
|
||||
* @param radius
|
||||
|
||||
@@ -4,23 +4,40 @@ module es {
|
||||
* 对撞机的基本形状
|
||||
*/
|
||||
public shape: Shape;
|
||||
|
||||
/**
|
||||
* 将localOffset添加到实体。获取碰撞器几何图形的最终位置。
|
||||
* 允许向一个实体添加多个碰撞器并分别定位,还允许你设置缩放/旋转
|
||||
* 如果这个碰撞器是一个触发器,它将不会引起碰撞,但它仍然会触发事件
|
||||
*/
|
||||
public get localOffset(): Vector2 {
|
||||
return this._localOffset;
|
||||
}
|
||||
|
||||
public isTrigger: boolean;
|
||||
/**
|
||||
* 将localOffset添加到实体。获取碰撞器几何图形的最终位置。
|
||||
* 允许向一个实体添加多个碰撞器并分别定位,还允许你设置缩放/旋转
|
||||
* @param value
|
||||
* 在处理冲突时,physicsLayer可以用作过滤器。Flags类有帮助位掩码的方法
|
||||
*/
|
||||
public set localOffset(value: Vector2) {
|
||||
this.setLocalOffset(value);
|
||||
}
|
||||
public physicsLayer = 1 << 0;
|
||||
/**
|
||||
* 碰撞器在使用移动器移动时应该碰撞的层
|
||||
* 默认为所有层
|
||||
*/
|
||||
public collidesWithLayers = Physics.allLayers;
|
||||
/**
|
||||
* 如果为true,碰撞器将根据附加的变换缩放和旋转
|
||||
*/
|
||||
public shouldColliderScaleAndRotateWithTransform = true;
|
||||
/**
|
||||
* 这个对撞机在物理系统注册时的边界。
|
||||
* 存储这个允许我们始终能够安全地从物理系统中移除对撞机,即使它在试图移除它之前已经被移动了。
|
||||
*/
|
||||
public registeredPhysicsBounds: Rectangle = new Rectangle();
|
||||
public _localOffsetLength: number;
|
||||
public _isPositionDirty: boolean = true;
|
||||
public _isRotationDirty: boolean = true;
|
||||
protected _colliderRequiresAutoSizing;
|
||||
/**
|
||||
* 标记来跟踪我们的实体是否被添加到场景中
|
||||
*/
|
||||
protected _isParentEntityAddedToScene;
|
||||
/**
|
||||
* 标记来记录我们是否注册了物理系统
|
||||
*/
|
||||
protected _isColliderRegistered;
|
||||
|
||||
/**
|
||||
* 镖师碰撞器的绝对位置
|
||||
@@ -39,27 +56,8 @@ module es {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果这个碰撞器是一个触发器,它将不会引起碰撞,但它仍然会触发事件
|
||||
*/
|
||||
public isTrigger: boolean;
|
||||
/**
|
||||
* 在处理冲突时,physicsLayer可以用作过滤器。Flags类有帮助位掩码的方法
|
||||
*/
|
||||
public physicsLayer = 1 << 0;
|
||||
/**
|
||||
* 碰撞器在使用移动器移动时应该碰撞的层
|
||||
* 默认为所有层
|
||||
*/
|
||||
public collidesWithLayers = Physics.allLayers;
|
||||
|
||||
/**
|
||||
* 如果为true,碰撞器将根据附加的变换缩放和旋转
|
||||
*/
|
||||
public shouldColliderScaleAndRotateWithTransform = true;
|
||||
|
||||
public get bounds(): Rectangle {
|
||||
if (this._isPositionDirty || this._isRotationDirty){
|
||||
if (this._isPositionDirty || this._isRotationDirty) {
|
||||
this.shape.recalculateBounds(this);
|
||||
this._isPositionDirty = this._isRotationDirty = false;
|
||||
}
|
||||
@@ -67,26 +65,24 @@ module es {
|
||||
return this.shape.bounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* 这个对撞机在物理系统注册时的边界。
|
||||
* 存储这个允许我们始终能够安全地从物理系统中移除对撞机,即使它在试图移除它之前已经被移动了。
|
||||
*/
|
||||
public registeredPhysicsBounds: Rectangle = new Rectangle();
|
||||
protected _colliderRequiresAutoSizing;
|
||||
protected _localOffset: Vector2 = Vector2.zero;
|
||||
public _localOffsetLength: number;
|
||||
|
||||
/**
|
||||
* 标记来跟踪我们的实体是否被添加到场景中
|
||||
* 将localOffset添加到实体。获取碰撞器几何图形的最终位置。
|
||||
* 允许向一个实体添加多个碰撞器并分别定位,还允许你设置缩放/旋转
|
||||
*/
|
||||
protected _isParentEntityAddedToScene;
|
||||
/**
|
||||
* 标记来记录我们是否注册了物理系统
|
||||
*/
|
||||
protected _isColliderRegistered;
|
||||
public get localOffset(): Vector2 {
|
||||
return this._localOffset;
|
||||
}
|
||||
|
||||
public _isPositionDirty: boolean = true;
|
||||
public _isRotationDirty: boolean = true;
|
||||
/**
|
||||
* 将localOffset添加到实体。获取碰撞器几何图形的最终位置。
|
||||
* 允许向一个实体添加多个碰撞器并分别定位,还允许你设置缩放/旋转
|
||||
* @param value
|
||||
*/
|
||||
public set localOffset(value: Vector2) {
|
||||
this.setLocalOffset(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将localOffset添加到实体。获取碰撞器的最终位置。
|
||||
@@ -229,7 +225,7 @@ module es {
|
||||
return didCollide;
|
||||
}
|
||||
|
||||
public clone(): Component{
|
||||
public clone(): Component {
|
||||
let collider = ObjectUtils.clone<Collider>(this);
|
||||
collider.entity = null;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
module es{
|
||||
module es {
|
||||
/**
|
||||
* 当添加到组件时,每当实体上的冲突器与另一个组件重叠/退出时,将调用这些方法。
|
||||
* ITriggerListener方法将在实现接口的触发器实体上的任何组件上调用。
|
||||
|
||||
@@ -9,7 +9,7 @@ module es {
|
||||
export class Mover extends Component {
|
||||
private _triggerHelper: ColliderTriggerHelper;
|
||||
|
||||
public onAddedToEntity(){
|
||||
public onAddedToEntity() {
|
||||
this._triggerHelper = new ColliderTriggerHelper(this.entity);
|
||||
}
|
||||
|
||||
@@ -18,14 +18,14 @@ module es {
|
||||
* @param motion
|
||||
* @param collisionResult
|
||||
*/
|
||||
public calculateMovement(motion: Vector2, collisionResult: CollisionResult): boolean{
|
||||
if (!this.entity.getComponent(Collider) || !this._triggerHelper){
|
||||
public calculateMovement(motion: Vector2, collisionResult: CollisionResult): boolean {
|
||||
if (!this.entity.getComponent(Collider) || !this._triggerHelper) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 移动所有的非触发碰撞器并获得最近的碰撞
|
||||
let colliders: Collider[] = this.entity.getComponents(Collider);
|
||||
for (let i = 0; i < colliders.length; i ++){
|
||||
for (let i = 0; i < colliders.length; i++) {
|
||||
let collider = colliders[i];
|
||||
|
||||
// 不检测触发器 在我们移动后会重新访问它
|
||||
@@ -38,19 +38,19 @@ module es {
|
||||
bounds.y += motion.y;
|
||||
let neighbors = Physics.boxcastBroadphaseExcludingSelf(collider, bounds, collider.collidesWithLayers);
|
||||
|
||||
for (let j = 0; j < neighbors.length; j ++){
|
||||
for (let j = 0; j < neighbors.length; j++) {
|
||||
let neighbor = neighbors[j];
|
||||
// 不检测触发器
|
||||
if (neighbor.isTrigger)
|
||||
continue;
|
||||
|
||||
let _internalcollisionResult: CollisionResult = new CollisionResult();
|
||||
if (collider.collidesWith(neighbor, motion, _internalcollisionResult)){
|
||||
if (collider.collidesWith(neighbor, motion, _internalcollisionResult)) {
|
||||
// 如果碰撞 则退回之前的移动量
|
||||
motion = motion.subtract(_internalcollisionResult.minimumTranslationVector);
|
||||
|
||||
// 如果我们碰到多个对象,为了简单起见,只取第一个。
|
||||
if (_internalcollisionResult.collider != null){
|
||||
if (_internalcollisionResult.collider != null) {
|
||||
collisionResult = _internalcollisionResult;
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,7 @@ module es {
|
||||
* 将calculatemomovement应用到实体并更新triggerHelper
|
||||
* @param motion
|
||||
*/
|
||||
public applyMovement(motion: Vector2){
|
||||
public applyMovement(motion: Vector2) {
|
||||
// 移动实体到它的新位置,如果我们有一个碰撞,否则移动全部数量。当碰撞发生时,运动被更新
|
||||
this.entity.position = Vector2.add(this.entity.position, motion);
|
||||
|
||||
@@ -80,7 +80,7 @@ module es {
|
||||
* @param motion
|
||||
* @param collisionResult
|
||||
*/
|
||||
public move(motion: Vector2, collisionResult: CollisionResult){
|
||||
public move(motion: Vector2, collisionResult: CollisionResult) {
|
||||
this.calculateMovement(motion, collisionResult);
|
||||
this.applyMovement(motion);
|
||||
return collisionResult.collider != null;
|
||||
|
||||
@@ -7,7 +7,7 @@ module es {
|
||||
private _tempTriggerList: ITriggerListener[] = [];
|
||||
private _collider: Collider;
|
||||
|
||||
public onAddedToEntity(){
|
||||
public onAddedToEntity() {
|
||||
this._collider = this.entity.getComponent<Collider>(Collider);
|
||||
if (!this._collider)
|
||||
console.warn("ProjectileMover has no Collider. ProjectilMover requires a Collider!");
|
||||
@@ -17,7 +17,7 @@ module es {
|
||||
* 移动考虑碰撞的实体
|
||||
* @param motion
|
||||
*/
|
||||
public move(motion: Vector2): boolean{
|
||||
public move(motion: Vector2): boolean {
|
||||
if (!this._collider)
|
||||
return false;
|
||||
|
||||
@@ -28,9 +28,9 @@ module es {
|
||||
|
||||
// 获取任何可能在新位置发生碰撞的东西
|
||||
let neighbors = Physics.boxcastBroadphase(this._collider.bounds, this._collider.collidesWithLayers);
|
||||
for (let i = 0; i < neighbors.length; i ++){
|
||||
for (let i = 0; i < neighbors.length; i++) {
|
||||
let neighbor = neighbors[i];
|
||||
if (this._collider.overlaps(neighbor) && neighbor.enabled){
|
||||
if (this._collider.overlaps(neighbor) && neighbor.enabled) {
|
||||
didCollide = true;
|
||||
this.notifyTriggerListeners(this._collider, neighbor);
|
||||
}
|
||||
@@ -39,17 +39,17 @@ module es {
|
||||
return didCollide;
|
||||
}
|
||||
|
||||
private notifyTriggerListeners(self: Collider, other: Collider){
|
||||
private notifyTriggerListeners(self: Collider, other: Collider) {
|
||||
// 通知我们重叠的碰撞器实体上的任何侦听器
|
||||
other.entity.getComponents("ITriggerListener", this._tempTriggerList);
|
||||
for (let i = 0; i < this._tempTriggerList.length; i ++){
|
||||
for (let i = 0; i < this._tempTriggerList.length; i++) {
|
||||
this._tempTriggerList[i].onTriggerEnter(self, other);
|
||||
}
|
||||
this._tempTriggerList.length = 0;
|
||||
|
||||
// 通知此实体上的任何侦听器
|
||||
this.entity.getComponents("ITriggerListener", this._tempTriggerList);
|
||||
for (let i = 0; i < this._tempTriggerList.length; i ++){
|
||||
for (let i = 0; i < this._tempTriggerList.length; i++) {
|
||||
this._tempTriggerList[i].onTriggerEnter(other, self);
|
||||
}
|
||||
this._tempTriggerList.length = 0;
|
||||
|
||||
@@ -8,6 +8,12 @@ module es {
|
||||
* 用于装载egret显示对象
|
||||
*/
|
||||
public displayObject: egret.DisplayObject = new egret.DisplayObject();
|
||||
/**
|
||||
* 用于着色器处理精灵
|
||||
*/
|
||||
public color: number = 0x000000;
|
||||
protected _areBoundsDirty = true;
|
||||
|
||||
/**
|
||||
* renderableComponent的宽度
|
||||
* 如果你不重写bounds属性则需要实现这个
|
||||
@@ -24,11 +30,43 @@ module es {
|
||||
return this.bounds.height;
|
||||
}
|
||||
|
||||
protected _localOffset: Vector2 = Vector2.zero;
|
||||
|
||||
/**
|
||||
* 从父实体的偏移量。用于向需要特定定位的实体
|
||||
*/
|
||||
public get localOffset(): Vector2 {
|
||||
return this._localOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从父实体的偏移量。用于向需要特定定位的实体
|
||||
* @param value
|
||||
*/
|
||||
public set localOffset(value: Vector2) {
|
||||
this.setLocalOffset(value);
|
||||
}
|
||||
|
||||
protected _renderLayer: number = 0;
|
||||
|
||||
/**
|
||||
* 较低的渲染层在前面,较高的在后面
|
||||
*/
|
||||
public get renderLayer(): number {
|
||||
return this._renderLayer;
|
||||
}
|
||||
|
||||
public set renderLayer(value: number) {
|
||||
|
||||
}
|
||||
|
||||
protected _bounds: Rectangle = new Rectangle();
|
||||
|
||||
/**
|
||||
* 这个物体的AABB, 用于相机剔除
|
||||
*/
|
||||
public get bounds(): Rectangle {
|
||||
if (this._areBoundsDirty){
|
||||
if (this._areBoundsDirty) {
|
||||
this._bounds.calculateBounds(this.entity.transform.position, this._localOffset, Vector2.zero,
|
||||
this.entity.transform.scale, this.entity.transform.rotation, this.width, this.height);
|
||||
this._areBoundsDirty = false;
|
||||
@@ -37,36 +75,7 @@ module es {
|
||||
return this._bounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* 较低的渲染层在前面,较高的在后面
|
||||
*/
|
||||
public get renderLayer(): number{
|
||||
return this._renderLayer;
|
||||
}
|
||||
|
||||
public set renderLayer(value: number){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于着色器处理精灵
|
||||
*/
|
||||
public color: number = 0x000000;
|
||||
|
||||
/**
|
||||
* 从父实体的偏移量。用于向需要特定定位的实体
|
||||
*/
|
||||
public get localOffset(): Vector2{
|
||||
return this._localOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从父实体的偏移量。用于向需要特定定位的实体
|
||||
* @param value
|
||||
*/
|
||||
public set localOffset(value: Vector2){
|
||||
this.setLocalOffset(value);
|
||||
}
|
||||
private _isVisible: boolean;
|
||||
|
||||
/**
|
||||
* 可渲染的可见性。状态的改变会调用onBecameVisible/onBecameInvisible方法
|
||||
@@ -80,7 +89,7 @@ module es {
|
||||
* @param value
|
||||
*/
|
||||
public set isVisible(value: boolean) {
|
||||
if (this._isVisible != value){
|
||||
if (this._isVisible != value) {
|
||||
this._isVisible = value;
|
||||
|
||||
if (this._isVisible)
|
||||
@@ -90,12 +99,6 @@ module es {
|
||||
}
|
||||
}
|
||||
|
||||
protected _localOffset: Vector2 = Vector2.zero;
|
||||
protected _renderLayer: number = 0;
|
||||
protected _bounds: Rectangle = new Rectangle();
|
||||
private _isVisible: boolean;
|
||||
protected _areBoundsDirty = true;
|
||||
|
||||
public onEntityTransformChanged(comp: transform.Component) {
|
||||
this._areBoundsDirty = true;
|
||||
}
|
||||
@@ -106,22 +109,6 @@ module es {
|
||||
*/
|
||||
public abstract render(camera: Camera);
|
||||
|
||||
/**
|
||||
* 当renderableComponent进入相机框架时调用
|
||||
* 如果渲染器不适用isVisibleFromCamera进行剔除检查 这些方法不会被调用
|
||||
*/
|
||||
protected onBecameVisible() {
|
||||
this.displayObject.visible = this.isVisible;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当renderableComponent离开相机框架时调用
|
||||
* 如果渲染器不适用isVisibleFromCamera进行剔除检查 这些方法不会被调用
|
||||
*/
|
||||
protected onBecameInvisible() {
|
||||
this.displayObject.visible = this.isVisible;
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果renderableComponent的边界与camera.bounds相交 返回true
|
||||
* 用于处理isVisible标志的状态开关
|
||||
@@ -137,8 +124,8 @@ module es {
|
||||
* 较低的渲染层在前面,较高的在后面
|
||||
* @param renderLayer
|
||||
*/
|
||||
public setRenderLayer(renderLayer: number): RenderableComponent{
|
||||
if (renderLayer != this._renderLayer){
|
||||
public setRenderLayer(renderLayer: number): RenderableComponent {
|
||||
if (renderLayer != this._renderLayer) {
|
||||
let oldRenderLayer = this._renderLayer;
|
||||
this._renderLayer = renderLayer;
|
||||
|
||||
@@ -154,7 +141,7 @@ module es {
|
||||
* 用于着色器处理精灵
|
||||
* @param color
|
||||
*/
|
||||
public setColor(color: number): RenderableComponent{
|
||||
public setColor(color: number): RenderableComponent {
|
||||
this.color = color;
|
||||
return this;
|
||||
}
|
||||
@@ -163,8 +150,8 @@ module es {
|
||||
* 从父实体的偏移量。用于向需要特定定位的实体
|
||||
* @param offset
|
||||
*/
|
||||
public setLocalOffset(offset: Vector2): RenderableComponent{
|
||||
if (this._localOffset != offset){
|
||||
public setLocalOffset(offset: Vector2): RenderableComponent {
|
||||
if (this._localOffset != offset) {
|
||||
this._localOffset = offset;
|
||||
}
|
||||
|
||||
@@ -174,7 +161,7 @@ module es {
|
||||
/**
|
||||
* 进行状态同步
|
||||
*/
|
||||
public sync(camera: Camera){
|
||||
public sync(camera: Camera) {
|
||||
this.displayObject.x = this.entity.position.x + this.localOffset.x - camera.position.x + camera.origin.x;
|
||||
this.displayObject.y = this.entity.position.y + this.localOffset.y - camera.position.y + camera.origin.y;
|
||||
this.displayObject.scaleX = this.entity.scale.x;
|
||||
@@ -182,8 +169,24 @@ module es {
|
||||
this.displayObject.rotation = this.entity.rotation;
|
||||
}
|
||||
|
||||
public toString(){
|
||||
public toString() {
|
||||
return `[RenderableComponent] renderLayer: ${this.renderLayer}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当renderableComponent进入相机框架时调用
|
||||
* 如果渲染器不适用isVisibleFromCamera进行剔除检查 这些方法不会被调用
|
||||
*/
|
||||
protected onBecameVisible() {
|
||||
this.displayObject.visible = this.isVisible;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当renderableComponent离开相机框架时调用
|
||||
* 如果渲染器不适用isVisibleFromCamera进行剔除检查 这些方法不会被调用
|
||||
*/
|
||||
protected onBecameInvisible() {
|
||||
this.displayObject.visible = this.isVisible;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ module es {
|
||||
private _scrollX = 0;
|
||||
private _scrollY = 0;
|
||||
|
||||
public update(){
|
||||
public update() {
|
||||
this._scrollX += this.scrollSpeedX * Time.deltaTime;
|
||||
this._scrollY += this.scroolSpeedY * Time.deltaTime;
|
||||
this.sourceRect.x = this._scrollX;
|
||||
|
||||
@@ -3,7 +3,7 @@ module es {
|
||||
public readonly sprites: Sprite[];
|
||||
public readonly frameRate: number;
|
||||
|
||||
constructor(sprites: Sprite[], frameRate: number){
|
||||
constructor(sprites: Sprite[], frameRate: number) {
|
||||
this.sprites = sprites;
|
||||
this.frameRate = frameRate;
|
||||
}
|
||||
|
||||
@@ -45,6 +45,12 @@ module es {
|
||||
* 当前动画的精灵数组中当前帧的索引
|
||||
*/
|
||||
public currentFrame: number;
|
||||
public _elapsedTime: number = 0;
|
||||
public _loopMode: LoopMode;
|
||||
|
||||
constructor(sprite?: Sprite) {
|
||||
super(sprite);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查当前动画是否正在运行
|
||||
@@ -53,19 +59,13 @@ module es {
|
||||
return this.animationState == State.running;
|
||||
}
|
||||
|
||||
private _animations: Map<string, SpriteAnimation> = new Map<string, SpriteAnimation>();
|
||||
|
||||
/** 提供对可用动画列表的访问 */
|
||||
public get animations() {
|
||||
return this._animations;
|
||||
}
|
||||
|
||||
private _animations: Map<string, SpriteAnimation> = new Map<string, SpriteAnimation>();
|
||||
public _elapsedTime: number = 0;
|
||||
public _loopMode: LoopMode;
|
||||
|
||||
constructor(sprite?: Sprite) {
|
||||
super(sprite);
|
||||
}
|
||||
|
||||
public update() {
|
||||
if (this.animationState != State.running || !this.currentAnimation) return;
|
||||
|
||||
|
||||
@@ -2,6 +2,14 @@ module es {
|
||||
import Bitmap = egret.Bitmap;
|
||||
|
||||
export class SpriteRenderer extends RenderableComponent {
|
||||
constructor(sprite: Sprite | egret.Texture = null) {
|
||||
super();
|
||||
if (sprite instanceof Sprite)
|
||||
this.setSprite(sprite);
|
||||
else if (sprite instanceof egret.Texture)
|
||||
this.setSprite(new Sprite(sprite));
|
||||
}
|
||||
|
||||
public get bounds() {
|
||||
if (this._areBoundsDirty) {
|
||||
if (this._sprite) {
|
||||
@@ -15,21 +23,6 @@ module es {
|
||||
return this._bounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* 精灵的原点。这是在设置精灵时自动设置的
|
||||
*/
|
||||
public get origin(): Vector2 {
|
||||
return this._origin;
|
||||
}
|
||||
|
||||
/**
|
||||
* 精灵的原点。这是在设置精灵时自动设置的
|
||||
* @param value
|
||||
*/
|
||||
public set origin(value: Vector2) {
|
||||
this.setOrigin(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用归一化方法设置原点
|
||||
* x/y 均为 0-1
|
||||
@@ -49,6 +42,25 @@ module es {
|
||||
value.y * this.height / this.entity.transform.scale.y));
|
||||
}
|
||||
|
||||
protected _origin: Vector2;
|
||||
|
||||
/**
|
||||
* 精灵的原点。这是在设置精灵时自动设置的
|
||||
*/
|
||||
public get origin(): Vector2 {
|
||||
return this._origin;
|
||||
}
|
||||
|
||||
/**
|
||||
* 精灵的原点。这是在设置精灵时自动设置的
|
||||
* @param value
|
||||
*/
|
||||
public set origin(value: Vector2) {
|
||||
this.setOrigin(value);
|
||||
}
|
||||
|
||||
protected _sprite: Sprite;
|
||||
|
||||
/**
|
||||
* 应该由这个精灵显示的精灵
|
||||
* 当设置时,精灵的原点也被设置为精灵的origin
|
||||
@@ -66,17 +78,6 @@ module es {
|
||||
this.setSprite(value);
|
||||
}
|
||||
|
||||
protected _origin: Vector2;
|
||||
protected _sprite: Sprite;
|
||||
|
||||
constructor(sprite: Sprite | egret.Texture = null) {
|
||||
super();
|
||||
if (sprite instanceof Sprite)
|
||||
this.setSprite(sprite);
|
||||
else if (sprite instanceof egret.Texture)
|
||||
this.setSprite(new Sprite(sprite));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置精灵并更新精灵的原点以匹配sprite.origin
|
||||
* @param sprite
|
||||
|
||||
@@ -8,19 +8,6 @@ module es {
|
||||
protected leftTexture: egret.Bitmap;
|
||||
protected rightTexture: egret.Bitmap;
|
||||
|
||||
public get scrollX() {
|
||||
return this.sourceRect.x;
|
||||
}
|
||||
public set scrollX(value: number) {
|
||||
this.sourceRect.x = value;
|
||||
}
|
||||
public get scrollY() {
|
||||
return this.sourceRect.y;
|
||||
}
|
||||
public set scrollY(value: number) {
|
||||
this.sourceRect.y = value;
|
||||
}
|
||||
|
||||
constructor(sprite: Sprite) {
|
||||
super(sprite);
|
||||
|
||||
@@ -33,6 +20,22 @@ module es {
|
||||
this.sourceRect = sprite.sourceRect;
|
||||
}
|
||||
|
||||
public get scrollX() {
|
||||
return this.sourceRect.x;
|
||||
}
|
||||
|
||||
public set scrollX(value: number) {
|
||||
this.sourceRect.x = value;
|
||||
}
|
||||
|
||||
public get scrollY() {
|
||||
return this.sourceRect.y;
|
||||
}
|
||||
|
||||
public set scrollY(value: number) {
|
||||
this.sourceRect.y = value;
|
||||
}
|
||||
|
||||
public render(camera: es.Camera) {
|
||||
if (!this.sprite)
|
||||
return;
|
||||
|
||||
@@ -15,20 +15,10 @@ module es {
|
||||
* 全局内容管理器加载任何应该停留在场景之间的资产
|
||||
*/
|
||||
public static content: ContentManager;
|
||||
|
||||
/**
|
||||
* 提供对单例/游戏实例的访问
|
||||
* @constructor
|
||||
*/
|
||||
public static get Instance(){
|
||||
return this._instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 简化对内部类的全局内容实例的访问
|
||||
*/
|
||||
public static _instance: Core;
|
||||
public _scene: Scene;
|
||||
public _nextScene: Scene;
|
||||
public _sceneTransition: SceneTransition;
|
||||
/**
|
||||
@@ -36,6 +26,26 @@ module es {
|
||||
*/
|
||||
public _globalManagers: GlobalManager[] = [];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
Core._instance = this;
|
||||
Core.emitter = new Emitter<CoreEvents>();
|
||||
Core.content = new ContentManager();
|
||||
|
||||
this.addEventListener(egret.Event.ADDED_TO_STAGE, this.onAddToStage, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 提供对单例/游戏实例的访问
|
||||
* @constructor
|
||||
*/
|
||||
public static get Instance() {
|
||||
return this._instance;
|
||||
}
|
||||
|
||||
public _scene: Scene;
|
||||
|
||||
/**
|
||||
* 当前活动的场景。注意,如果设置了该设置,在更新结束之前场景实际上不会改变
|
||||
*/
|
||||
@@ -50,7 +60,7 @@ module es {
|
||||
* @param value
|
||||
*/
|
||||
public static set scene(value: Scene) {
|
||||
if (!value){
|
||||
if (!value) {
|
||||
console.error("场景不能为空");
|
||||
return;
|
||||
}
|
||||
@@ -65,39 +75,106 @@ module es {
|
||||
}
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
/**
|
||||
* 临时运行SceneTransition,允许一个场景过渡到另一个平滑的自定义效果。
|
||||
* @param sceneTransition
|
||||
*/
|
||||
public static startSceneTransition<T extends SceneTransition>(sceneTransition: T): T {
|
||||
if (this._instance._sceneTransition) {
|
||||
console.warn("在前一个场景完成之前,不能开始一个新的场景转换。");
|
||||
return;
|
||||
}
|
||||
|
||||
Core._instance = this;
|
||||
Core.emitter = new Emitter<CoreEvents>();
|
||||
Core.content = new ContentManager();
|
||||
|
||||
this.addEventListener(egret.Event.ADDED_TO_STAGE, this.onAddToStage, this);
|
||||
this._instance._sceneTransition = sceneTransition;
|
||||
return sceneTransition;
|
||||
}
|
||||
|
||||
private onAddToStage(){
|
||||
Core.graphicsDevice = new GraphicsDevice();
|
||||
|
||||
this.addEventListener(egret.Event.RESIZE, this.onGraphicsDeviceReset, this);
|
||||
this.addEventListener(egret.StageOrientationEvent.ORIENTATION_CHANGE, this.onOrientationChanged, this);
|
||||
this.addEventListener(egret.Event.ENTER_FRAME, this.update, this);
|
||||
|
||||
Input.initialize();
|
||||
this.initialize();
|
||||
/**
|
||||
* 添加一个全局管理器对象,它的更新方法将调用场景前的每一帧。
|
||||
* @param manager
|
||||
*/
|
||||
public static registerGlobalManager(manager: es.GlobalManager) {
|
||||
this._instance._globalManagers.push(manager);
|
||||
manager.enabled = true;
|
||||
}
|
||||
|
||||
public onOrientationChanged(){
|
||||
/**
|
||||
* 删除全局管理器对象
|
||||
* @param manager
|
||||
*/
|
||||
public static unregisterGlobalManager(manager: es.GlobalManager) {
|
||||
this._instance._globalManagers.remove(manager);
|
||||
manager.enabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取类型为T的全局管理器
|
||||
* @param type
|
||||
*/
|
||||
public static getGlobalManager<T extends es.GlobalManager>(type): T {
|
||||
for (let i = 0; i < this._instance._globalManagers.length; i++) {
|
||||
if (this._instance._globalManagers[i] instanceof type)
|
||||
return this._instance._globalManagers[i] as T;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public onOrientationChanged() {
|
||||
Core.emitter.emit(CoreEvents.OrientationChanged);
|
||||
}
|
||||
|
||||
public async draw() {
|
||||
if (this._sceneTransition) {
|
||||
this._sceneTransition.preRender();
|
||||
|
||||
// 如果我们有场景转换的特殊处理。我们要么渲染场景过渡,要么渲染场景
|
||||
if (this._scene && !this._sceneTransition.hasPreviousSceneRender) {
|
||||
this._scene.render();
|
||||
this._scene.postRender();
|
||||
await this._sceneTransition.onBeginTransition();
|
||||
} else if (this._sceneTransition) {
|
||||
if (this._scene && this._sceneTransition.isNewSceneLoaded) {
|
||||
this._scene.render();
|
||||
this._scene.postRender();
|
||||
}
|
||||
|
||||
this._sceneTransition.render();
|
||||
}
|
||||
} else if (this._scene) {
|
||||
this._scene.render();
|
||||
|
||||
Debug.render();
|
||||
|
||||
// 如果我们没有一个活跃的场景转换,就像平常一样渲染
|
||||
this._scene.postRender();
|
||||
}
|
||||
}
|
||||
|
||||
public startDebugUpdate() {
|
||||
TimeRuler.Instance.startFrame();
|
||||
TimeRuler.Instance.beginMark("update", 0x00FF00);
|
||||
}
|
||||
|
||||
public endDebugUpdate() {
|
||||
TimeRuler.Instance.endMark("update");
|
||||
}
|
||||
|
||||
/**
|
||||
* 在一个场景结束后,下一个场景开始之前调用
|
||||
*/
|
||||
public onSceneChanged() {
|
||||
Core.emitter.emit(CoreEvents.SceneChanged);
|
||||
Time.sceneChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 当屏幕大小发生改变时调用
|
||||
*/
|
||||
protected onGraphicsDeviceReset(){
|
||||
protected onGraphicsDeviceReset() {
|
||||
Core.emitter.emit(CoreEvents.GraphicsDeviceReset);
|
||||
}
|
||||
|
||||
protected initialize(){
|
||||
protected initialize() {
|
||||
}
|
||||
|
||||
protected async update() {
|
||||
@@ -139,92 +216,15 @@ module es {
|
||||
await this.draw();
|
||||
}
|
||||
|
||||
public async draw() {
|
||||
if (this._sceneTransition){
|
||||
this._sceneTransition.preRender();
|
||||
private onAddToStage() {
|
||||
Core.graphicsDevice = new GraphicsDevice();
|
||||
|
||||
// 如果我们有场景转换的特殊处理。我们要么渲染场景过渡,要么渲染场景
|
||||
if (this._scene && !this._sceneTransition.hasPreviousSceneRender){
|
||||
this._scene.render();
|
||||
this._scene.postRender();
|
||||
await this._sceneTransition.onBeginTransition();
|
||||
} else if (this._sceneTransition) {
|
||||
if (this._scene && this._sceneTransition.isNewSceneLoaded) {
|
||||
this._scene.render();
|
||||
this._scene.postRender();
|
||||
}
|
||||
this.addEventListener(egret.Event.RESIZE, this.onGraphicsDeviceReset, this);
|
||||
this.addEventListener(egret.StageOrientationEvent.ORIENTATION_CHANGE, this.onOrientationChanged, this);
|
||||
this.addEventListener(egret.Event.ENTER_FRAME, this.update, this);
|
||||
|
||||
this._sceneTransition.render();
|
||||
}
|
||||
} else if (this._scene) {
|
||||
this._scene.render();
|
||||
|
||||
Debug.render();
|
||||
|
||||
// 如果我们没有一个活跃的场景转换,就像平常一样渲染
|
||||
this._scene.postRender();
|
||||
}
|
||||
}
|
||||
|
||||
public startDebugUpdate(){
|
||||
TimeRuler.Instance.startFrame();
|
||||
TimeRuler.Instance.beginMark("update", 0x00FF00);
|
||||
}
|
||||
|
||||
public endDebugUpdate(){
|
||||
TimeRuler.Instance.endMark("update");
|
||||
}
|
||||
|
||||
/**
|
||||
* 在一个场景结束后,下一个场景开始之前调用
|
||||
*/
|
||||
public onSceneChanged(){
|
||||
Core.emitter.emit(CoreEvents.SceneChanged);
|
||||
Time.sceneChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 临时运行SceneTransition,允许一个场景过渡到另一个平滑的自定义效果。
|
||||
* @param sceneTransition
|
||||
*/
|
||||
public static startSceneTransition<T extends SceneTransition>(sceneTransition: T): T {
|
||||
if (this._instance._sceneTransition) {
|
||||
console.warn("在前一个场景完成之前,不能开始一个新的场景转换。");
|
||||
return;
|
||||
}
|
||||
|
||||
this._instance._sceneTransition = sceneTransition;
|
||||
return sceneTransition;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加一个全局管理器对象,它的更新方法将调用场景前的每一帧。
|
||||
* @param manager
|
||||
*/
|
||||
public static registerGlobalManager(manager: es.GlobalManager){
|
||||
this._instance._globalManagers.push(manager);
|
||||
manager.enabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除全局管理器对象
|
||||
* @param manager
|
||||
*/
|
||||
public static unregisterGlobalManager(manager: es.GlobalManager){
|
||||
this._instance._globalManagers.remove(manager);
|
||||
manager.enabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取类型为T的全局管理器
|
||||
* @param type
|
||||
*/
|
||||
public static getGlobalManager<T extends es.GlobalManager>(type): T {
|
||||
for (let i = 0; i < this._instance._globalManagers.length; i ++){
|
||||
if (this._instance._globalManagers[i] instanceof type)
|
||||
return this._instance._globalManagers[i] as T;
|
||||
}
|
||||
return null;
|
||||
Input.initialize();
|
||||
this.initialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module es {
|
||||
export enum CoreEvents{
|
||||
export enum CoreEvents {
|
||||
/**
|
||||
* 在图形设备重置时触发。当这种情况发生时,任何渲染目标或其他内容的VRAM将被擦除,需要重新生成
|
||||
*/
|
||||
|
||||
@@ -22,6 +22,31 @@ module es {
|
||||
* 当前附加到此实体的所有组件的列表
|
||||
*/
|
||||
public readonly components: ComponentList;
|
||||
/**
|
||||
* 指定应该调用这个entity update方法的频率。1表示每一帧,2表示每一帧,以此类推
|
||||
*/
|
||||
public updateInterval: number = 1;
|
||||
public componentBits: BitSet;
|
||||
|
||||
constructor(name: string) {
|
||||
this.components = new ComponentList(this);
|
||||
this.transform = new Transform(this);
|
||||
this.name = name;
|
||||
this.id = Entity._idGenerator++;
|
||||
|
||||
this.componentBits = new BitSet();
|
||||
}
|
||||
|
||||
public _isDestroyed: boolean;
|
||||
|
||||
/**
|
||||
* 如果调用了destroy,那么在下一次处理实体之前这将一直为true
|
||||
*/
|
||||
public get isDestroyed() {
|
||||
return this._isDestroyed;
|
||||
}
|
||||
|
||||
private _tag: number = 0;
|
||||
|
||||
/**
|
||||
* 你可以随意使用。稍后可以使用它来查询场景中具有特定标记的所有实体
|
||||
@@ -38,10 +63,7 @@ module es {
|
||||
this.setTag(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定应该调用这个entity update方法的频率。1表示每一帧,2表示每一帧,以此类推
|
||||
*/
|
||||
public updateInterval: number = 1;
|
||||
private _enabled: boolean = true;
|
||||
|
||||
/**
|
||||
* 启用/禁用实体。当禁用碰撞器从物理系统和组件中移除时,方法将不会被调用
|
||||
@@ -58,6 +80,8 @@ module es {
|
||||
this.setEnabled(value);
|
||||
}
|
||||
|
||||
private _updateOrder: number = 0;
|
||||
|
||||
/**
|
||||
* 更新此实体的顺序。updateOrder还用于对scene.entities上的标签列表进行排序
|
||||
*/
|
||||
@@ -73,20 +97,6 @@ module es {
|
||||
this.setUpdateOrder(value);
|
||||
}
|
||||
|
||||
public _isDestroyed: boolean;
|
||||
/**
|
||||
* 如果调用了destroy,那么在下一次处理实体之前这将一直为true
|
||||
*/
|
||||
public get isDestroyed() {
|
||||
return this._isDestroyed;
|
||||
}
|
||||
|
||||
public componentBits: BitSet;
|
||||
|
||||
private _tag: number = 0;
|
||||
private _enabled: boolean = true;
|
||||
private _updateOrder: number = 0;
|
||||
|
||||
public get parent(): Transform {
|
||||
return this.transform.parent;
|
||||
}
|
||||
@@ -111,7 +121,7 @@ module es {
|
||||
return this.transform.localPosition;
|
||||
}
|
||||
|
||||
public set localPosition(value: Vector2){
|
||||
public set localPosition(value: Vector2) {
|
||||
this.transform.setLocalPosition(value);
|
||||
}
|
||||
|
||||
@@ -127,7 +137,7 @@ module es {
|
||||
return this.transform.rotationDegrees;
|
||||
}
|
||||
|
||||
public set rotationDegrees(value: number){
|
||||
public set rotationDegrees(value: number) {
|
||||
this.transform.setRotationDegrees(value);
|
||||
}
|
||||
|
||||
@@ -135,7 +145,7 @@ module es {
|
||||
return this.transform.localRotation;
|
||||
}
|
||||
|
||||
public set localRotation(value: number){
|
||||
public set localRotation(value: number) {
|
||||
this.transform.setLocalRotation(value);
|
||||
}
|
||||
|
||||
@@ -143,7 +153,7 @@ module es {
|
||||
return this.transform.localRotationDegrees;
|
||||
}
|
||||
|
||||
public set localRotationDegrees(value: number){
|
||||
public set localRotationDegrees(value: number) {
|
||||
this.transform.setLocalRotationDegrees(value);
|
||||
}
|
||||
|
||||
@@ -159,7 +169,7 @@ module es {
|
||||
return this.transform.localScale;
|
||||
}
|
||||
|
||||
public set localScale(value: Vector2){
|
||||
public set localScale(value: Vector2) {
|
||||
this.transform.setLocalScale(value);
|
||||
}
|
||||
|
||||
@@ -175,15 +185,6 @@ module es {
|
||||
return this.transform.worldToLocalTransform;
|
||||
}
|
||||
|
||||
constructor(name: string) {
|
||||
this.components = new ComponentList(this);
|
||||
this.transform = new Transform(this);
|
||||
this.name = name;
|
||||
this.id = Entity._idGenerator++;
|
||||
|
||||
this.componentBits = new BitSet();
|
||||
}
|
||||
|
||||
public onTransformChanged(comp: transform.Component) {
|
||||
// 通知我们的子项改变了位置
|
||||
this.components.onEntityTransformChanged(comp);
|
||||
@@ -293,32 +294,6 @@ module es {
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将实体的属性、组件和碰撞器复制到此实例
|
||||
* @param entity
|
||||
*/
|
||||
protected copyFrom(entity: Entity) {
|
||||
this.tag = entity.tag;
|
||||
this.updateInterval = entity.updateInterval;
|
||||
this.updateOrder = entity.updateOrder;
|
||||
this.enabled = entity.enabled;
|
||||
|
||||
this.transform.scale = entity.transform.scale;
|
||||
this.transform.rotation = entity.transform.rotation;
|
||||
|
||||
for (let i = 0; i < entity.components.count; i++)
|
||||
this.addComponent(entity.components.buffer[i].clone());
|
||||
for (let i = 0; i < entity.components._componentsToAdd.length; i++)
|
||||
this.addComponent(entity.components._componentsToAdd[i].clone());
|
||||
|
||||
for (let i = 0; i < entity.transform.childCount; i++) {
|
||||
let child = entity.transform.getChild(i).entity;
|
||||
let childClone = child.clone();
|
||||
childClone.transform.copyFrom(child.transform);
|
||||
childClone.transform.parent = this.transform;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 在提交了所有挂起的实体更改后,将此实体添加到场景时调用
|
||||
*/
|
||||
@@ -431,5 +406,31 @@ module es {
|
||||
public toString(): string {
|
||||
return `[Entity: name: ${this.name}, tag: ${this.tag}, enabled: ${this.enabled}, depth: ${this.updateOrder}]`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将实体的属性、组件和碰撞器复制到此实例
|
||||
* @param entity
|
||||
*/
|
||||
protected copyFrom(entity: Entity) {
|
||||
this.tag = entity.tag;
|
||||
this.updateInterval = entity.updateInterval;
|
||||
this.updateOrder = entity.updateOrder;
|
||||
this.enabled = entity.enabled;
|
||||
|
||||
this.transform.scale = entity.transform.scale;
|
||||
this.transform.rotation = entity.transform.rotation;
|
||||
|
||||
for (let i = 0; i < entity.components.count; i++)
|
||||
this.addComponent(entity.components.buffer[i].clone());
|
||||
for (let i = 0; i < entity.components._componentsToAdd.length; i++)
|
||||
this.addComponent(entity.components._componentsToAdd[i].clone());
|
||||
|
||||
for (let i = 0; i < entity.transform.childCount; i++) {
|
||||
let child = entity.transform.getChild(i).entity;
|
||||
let childClone = child.clone();
|
||||
childClone.transform.copyFrom(child.transform);
|
||||
childClone.transform.parent = this.transform;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,350 +1,355 @@
|
||||
module es {
|
||||
/** 场景 */
|
||||
export class Scene extends egret.DisplayObjectContainer {
|
||||
/**
|
||||
* 默认场景摄像机
|
||||
*/
|
||||
public camera: Camera;
|
||||
/**
|
||||
* 场景特定内容管理器。使用它来加载仅由这个场景需要的任何资源。如果你有全局/多场景资源,你可以使用SceneManager.content。
|
||||
* contentManager来加载它们,因为Nez不会卸载它们。
|
||||
*/
|
||||
public readonly content: ContentManager;
|
||||
/**
|
||||
* 全局切换后处理器
|
||||
*/
|
||||
public enablePostProcessing = true;
|
||||
/**
|
||||
* 这个场景中的实体列表
|
||||
*/
|
||||
public readonly entities: EntityList;
|
||||
/**
|
||||
* 管理当前在场景实体上的所有可呈现组件的列表
|
||||
*/
|
||||
public readonly renderableComponents: RenderableComponentList;
|
||||
/**
|
||||
* 管理所有实体处理器
|
||||
*/
|
||||
public readonly entityProcessors: EntityProcessorList;
|
||||
/** 场景 */
|
||||
export class Scene extends egret.DisplayObjectContainer {
|
||||
/**
|
||||
* 默认场景摄像机
|
||||
*/
|
||||
public camera: Camera;
|
||||
/**
|
||||
* 场景特定内容管理器。使用它来加载仅由这个场景需要的任何资源。如果你有全局/多场景资源,你可以使用SceneManager.content。
|
||||
* contentManager来加载它们,因为Nez不会卸载它们。
|
||||
*/
|
||||
public readonly content: ContentManager;
|
||||
/**
|
||||
* 全局切换后处理器
|
||||
*/
|
||||
public enablePostProcessing = true;
|
||||
/**
|
||||
* 这个场景中的实体列表
|
||||
*/
|
||||
public readonly entities: EntityList;
|
||||
/**
|
||||
* 管理当前在场景实体上的所有可呈现组件的列表
|
||||
*/
|
||||
public readonly renderableComponents: RenderableComponentList;
|
||||
/**
|
||||
* 管理所有实体处理器
|
||||
*/
|
||||
public readonly entityProcessors: EntityProcessorList;
|
||||
|
||||
public _renderers: Renderer[] = [];
|
||||
public readonly _postProcessors: PostProcessor[] = [];
|
||||
public _didSceneBegin;
|
||||
public _renderers: Renderer[] = [];
|
||||
public readonly _postProcessors: PostProcessor[] = [];
|
||||
public _didSceneBegin;
|
||||
|
||||
/**
|
||||
* 辅助器,创建一个场景与DefaultRenderer附加并准备使用
|
||||
*/
|
||||
public static createWithDefaultRenderer(){
|
||||
let scene = new Scene();
|
||||
scene.addRenderer(new DefaultRenderer());
|
||||
return scene;
|
||||
}
|
||||
constructor() {
|
||||
super();
|
||||
this.entities = new EntityList(this);
|
||||
this.renderableComponents = new RenderableComponentList();
|
||||
this.content = new ContentManager();
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.entities = new EntityList(this);
|
||||
this.renderableComponents = new RenderableComponentList();
|
||||
this.content = new ContentManager();
|
||||
this.entityProcessors = new EntityProcessorList();
|
||||
|
||||
this.entityProcessors = new EntityProcessorList();
|
||||
this.initialize();
|
||||
}
|
||||
|
||||
this.initialize();
|
||||
}
|
||||
/**
|
||||
* 辅助器,创建一个场景与DefaultRenderer附加并准备使用
|
||||
*/
|
||||
public static createWithDefaultRenderer() {
|
||||
let scene = new Scene();
|
||||
scene.addRenderer(new DefaultRenderer());
|
||||
return scene;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在场景子类中重写这个并在这里进行加载。在场景设置好之后,在调用begin之前,从构造器中调用。
|
||||
*/
|
||||
public initialize(){}
|
||||
/**
|
||||
* 在场景子类中重写这个并在这里进行加载。在场景设置好之后,在调用begin之前,从构造器中调用。
|
||||
*/
|
||||
public initialize() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 在场景子类中重写这个。当SceneManager将此场景设置为活动场景时,将调用此操作。
|
||||
*/
|
||||
public async onStart() {}
|
||||
/**
|
||||
* 在场景子类中重写这个。当SceneManager将此场景设置为活动场景时,将调用此操作。
|
||||
*/
|
||||
public async onStart() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 在场景子类中重写这个,并在这里做任何必要的卸载。当SceneManager从活动槽中删除此场景时调用。
|
||||
*/
|
||||
public unload() { }
|
||||
/**
|
||||
* 在场景子类中重写这个,并在这里做任何必要的卸载。当SceneManager从活动槽中删除此场景时调用。
|
||||
*/
|
||||
public unload() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 在场景子类中重写这个,当该场景当获得焦点时调用
|
||||
*/
|
||||
public onActive() {}
|
||||
/**
|
||||
* 在场景子类中重写这个,当该场景当获得焦点时调用
|
||||
*/
|
||||
public onActive() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 在场景子类中重写这个,当该场景当失去焦点时调用
|
||||
*/
|
||||
public onDeactive() {}
|
||||
/**
|
||||
* 在场景子类中重写这个,当该场景当失去焦点时调用
|
||||
*/
|
||||
public onDeactive() {
|
||||
}
|
||||
|
||||
public async begin() {
|
||||
if (this._renderers.length == 0) {
|
||||
this.addRenderer(new DefaultRenderer());
|
||||
console.warn("场景开始时没有渲染器 自动添加DefaultRenderer以保证能够正常渲染");
|
||||
}
|
||||
|
||||
this.camera = this.createEntity("camera").getOrCreateComponent(new Camera());
|
||||
|
||||
Physics.reset();
|
||||
|
||||
if (this.entityProcessors)
|
||||
this.entityProcessors.begin();
|
||||
|
||||
this.addEventListener(egret.Event.ACTIVATE, this.onActive, this);
|
||||
this.addEventListener(egret.Event.DEACTIVATE, this.onDeactive, this);
|
||||
this.camera.onSceneSizeChanged(this.stage.stageWidth, this.stage.stageHeight);
|
||||
|
||||
this._didSceneBegin = true;
|
||||
this.onStart();
|
||||
}
|
||||
|
||||
public end() {
|
||||
this._didSceneBegin = false;
|
||||
|
||||
this.removeEventListener(egret.Event.DEACTIVATE, this.onDeactive, this);
|
||||
this.removeEventListener(egret.Event.ACTIVATE, this.onActive, this);
|
||||
|
||||
for (let i = 0; i < this._renderers.length; i++) {
|
||||
this._renderers[i].unload();
|
||||
}
|
||||
|
||||
for (let i = 0; i < this._postProcessors.length; i++) {
|
||||
this._postProcessors[i].unload();
|
||||
}
|
||||
|
||||
this.entities.removeAllEntities();
|
||||
this.removeChildren();
|
||||
|
||||
this.camera = null;
|
||||
this.content.dispose();
|
||||
|
||||
if (this.entityProcessors)
|
||||
this.entityProcessors.end();
|
||||
|
||||
if (this.parent)
|
||||
this.parent.removeChild(this);
|
||||
|
||||
this.unload();
|
||||
}
|
||||
|
||||
public update() {
|
||||
// 更新我们的列表,以防它们有任何变化
|
||||
this.entities.updateLists();
|
||||
|
||||
// 更新我们的实体解析器
|
||||
if (this.entityProcessors)
|
||||
this.entityProcessors.update();
|
||||
|
||||
// 更新我们的实体组
|
||||
this.entities.update();
|
||||
|
||||
if (this.entityProcessors)
|
||||
this.entityProcessors.lateUpdate();
|
||||
|
||||
// 我们在实体之后更新我们的呈现。如果添加了任何新的渲染,请进行更新
|
||||
this.renderableComponents.updateList();
|
||||
}
|
||||
|
||||
public render() {
|
||||
if (this._renderers.length == 0){
|
||||
console.error("there are no renderers in the scene!");
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < this._renderers.length; i++) {
|
||||
this._renderers[i].render(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 现在的任何后处理器都要完成它的处理
|
||||
* 只有在SceneTransition请求渲染时,它才会有一个值。
|
||||
*/
|
||||
public postRender() {
|
||||
if (this.enablePostProcessing) {
|
||||
for (let i = 0; i < this._postProcessors.length; i++) {
|
||||
if (this._postProcessors[i].enabled) {
|
||||
this._postProcessors[i].process();
|
||||
}
|
||||
public async begin() {
|
||||
if (this._renderers.length == 0) {
|
||||
this.addRenderer(new DefaultRenderer());
|
||||
console.warn("场景开始时没有渲染器 自动添加DefaultRenderer以保证能够正常渲染");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 为场景添加一个渲染器
|
||||
* @param renderer
|
||||
*/
|
||||
public addRenderer<T extends Renderer>(renderer: T) {
|
||||
this._renderers.push(renderer);
|
||||
this._renderers.sort();
|
||||
this.camera = this.createEntity("camera").getOrCreateComponent(new Camera());
|
||||
|
||||
renderer.onAddedToScene(this);
|
||||
Physics.reset();
|
||||
|
||||
return renderer;
|
||||
}
|
||||
if (this.entityProcessors)
|
||||
this.entityProcessors.begin();
|
||||
|
||||
/**
|
||||
* 获取类型为T的第一个渲染器
|
||||
* @param type
|
||||
*/
|
||||
public getRenderer<T extends Renderer>(type): T {
|
||||
for (let i = 0; i < this._renderers.length; i++) {
|
||||
if (this._renderers[i] instanceof type)
|
||||
return this._renderers[i] as T;
|
||||
}
|
||||
this.addEventListener(egret.Event.ACTIVATE, this.onActive, this);
|
||||
this.addEventListener(egret.Event.DEACTIVATE, this.onDeactive, this);
|
||||
this.camera.onSceneSizeChanged(this.stage.stageWidth, this.stage.stageHeight);
|
||||
|
||||
return null;
|
||||
}
|
||||
this._didSceneBegin = true;
|
||||
this.onStart();
|
||||
}
|
||||
|
||||
/**
|
||||
* 从场景中移除渲染器
|
||||
* @param renderer
|
||||
*/
|
||||
public removeRenderer(renderer: Renderer) {
|
||||
if (!this._renderers.contains(renderer))
|
||||
return;
|
||||
this._renderers.remove(renderer);
|
||||
renderer.unload();
|
||||
}
|
||||
public end() {
|
||||
this._didSceneBegin = false;
|
||||
|
||||
/**
|
||||
* 添加一个后处理器到场景。设置场景字段并调用后处理器。onAddedToScene使后处理器可以使用场景ContentManager加载资源。
|
||||
* @param postProcessor
|
||||
*/
|
||||
public addPostProcessor<T extends PostProcessor>(postProcessor: T): T{
|
||||
this._postProcessors.push(postProcessor);
|
||||
this._postProcessors.sort();
|
||||
postProcessor.onAddedToScene(this);
|
||||
this.removeEventListener(egret.Event.DEACTIVATE, this.onDeactive, this);
|
||||
this.removeEventListener(egret.Event.ACTIVATE, this.onActive, this);
|
||||
|
||||
if (this._didSceneBegin){
|
||||
postProcessor.onSceneBackBufferSizeChanged(this.stage.stageWidth, this.stage.stageHeight);
|
||||
}
|
||||
for (let i = 0; i < this._renderers.length; i++) {
|
||||
this._renderers[i].unload();
|
||||
}
|
||||
|
||||
return postProcessor;
|
||||
}
|
||||
for (let i = 0; i < this._postProcessors.length; i++) {
|
||||
this._postProcessors[i].unload();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取类型为T的第一个后处理器
|
||||
* @param type
|
||||
*/
|
||||
public getPostProcessor<T extends PostProcessor>(type): T{
|
||||
for (let i = 0; i < this._postProcessors.length; i ++){
|
||||
if (this._postProcessors[i] instanceof type)
|
||||
return this._postProcessors[i] as T;
|
||||
}
|
||||
this.entities.removeAllEntities();
|
||||
this.removeChildren();
|
||||
|
||||
return null;
|
||||
}
|
||||
this.camera = null;
|
||||
this.content.dispose();
|
||||
|
||||
/**
|
||||
* 删除一个后处理程序。注意,在删除时不会调用unload,因此如果不再需要PostProcessor,请确保调用unload来释放资源。
|
||||
* @param postProcessor
|
||||
*/
|
||||
public removePostProcessor(postProcessor: PostProcessor){
|
||||
if (!this._postProcessors.contains(postProcessor))
|
||||
return;
|
||||
if (this.entityProcessors)
|
||||
this.entityProcessors.end();
|
||||
|
||||
this._postProcessors.remove(postProcessor);
|
||||
postProcessor.unload();
|
||||
}
|
||||
if (this.parent)
|
||||
this.parent.removeChild(this);
|
||||
|
||||
/**
|
||||
* 将实体添加到此场景,并返回它
|
||||
* @param name
|
||||
*/
|
||||
public createEntity(name: string) {
|
||||
let entity = new Entity(name);
|
||||
return this.addEntity(entity);
|
||||
}
|
||||
this.unload();
|
||||
}
|
||||
|
||||
/**
|
||||
* 在场景的实体列表中添加一个实体
|
||||
* @param entity
|
||||
*/
|
||||
public addEntity(entity: Entity) {
|
||||
if (this.entities.buffer.contains(entity))
|
||||
console.warn(`You are attempting to add the same entity to a scene twice: ${entity}`);
|
||||
this.entities.add(entity);
|
||||
entity.scene = this;
|
||||
public update() {
|
||||
// 更新我们的列表,以防它们有任何变化
|
||||
this.entities.updateLists();
|
||||
|
||||
for (let i = 0; i < entity.transform.childCount; i++)
|
||||
this.addEntity(entity.transform.getChild(i).entity);
|
||||
// 更新我们的实体解析器
|
||||
if (this.entityProcessors)
|
||||
this.entityProcessors.update();
|
||||
|
||||
return entity;
|
||||
}
|
||||
// 更新我们的实体组
|
||||
this.entities.update();
|
||||
|
||||
/**
|
||||
* 从场景中删除所有实体
|
||||
*/
|
||||
public destroyAllEntities() {
|
||||
for (let i = 0; i < this.entities.count; i++) {
|
||||
this.entities.buffer[i].destroy();
|
||||
}
|
||||
}
|
||||
if (this.entityProcessors)
|
||||
this.entityProcessors.lateUpdate();
|
||||
|
||||
/**
|
||||
* 搜索并返回第一个具有名称的实体
|
||||
* @param name
|
||||
*/
|
||||
public findEntity(name: string): Entity {
|
||||
return this.entities.findEntity(name);
|
||||
}
|
||||
// 我们在实体之后更新我们的呈现。如果添加了任何新的渲染,请进行更新
|
||||
this.renderableComponents.updateList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回具有给定标记的所有实体
|
||||
* @param tag
|
||||
*/
|
||||
public findEntitiesWithTag(tag: number): Entity[]{
|
||||
return this.entities.entitiesWithTag(tag);
|
||||
}
|
||||
public render() {
|
||||
if (this._renderers.length == 0) {
|
||||
console.error("there are no renderers in the scene!");
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回类型为T的所有实体
|
||||
* @param type
|
||||
*/
|
||||
public entitiesOfType<T extends Entity>(type): T[]{
|
||||
return this.entities.entitiesOfType<T>(type);
|
||||
}
|
||||
for (let i = 0; i < this._renderers.length; i++) {
|
||||
this._renderers[i].render(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回第一个启用加载的类型为T的组件
|
||||
* @param type
|
||||
*/
|
||||
public findComponentOfType<T extends Component>(type): T {
|
||||
return this.entities.findComponentOfType<T>(type);
|
||||
}
|
||||
/**
|
||||
* 现在的任何后处理器都要完成它的处理
|
||||
* 只有在SceneTransition请求渲染时,它才会有一个值。
|
||||
*/
|
||||
public postRender() {
|
||||
if (this.enablePostProcessing) {
|
||||
for (let i = 0; i < this._postProcessors.length; i++) {
|
||||
if (this._postProcessors[i].enabled) {
|
||||
this._postProcessors[i].process();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回类型为T的所有已启用已加载组件的列表
|
||||
* @param type
|
||||
*/
|
||||
public findComponentsOfType<T extends Component>(type): T[] {
|
||||
return this.entities.findComponentsOfType<T>(type);
|
||||
}
|
||||
/**
|
||||
* 为场景添加一个渲染器
|
||||
* @param renderer
|
||||
*/
|
||||
public addRenderer<T extends Renderer>(renderer: T) {
|
||||
this._renderers.push(renderer);
|
||||
this._renderers.sort();
|
||||
|
||||
/**
|
||||
* 在场景中添加一个EntitySystem处理器
|
||||
* @param processor 处理器
|
||||
*/
|
||||
public addEntityProcessor(processor: EntitySystem) {
|
||||
processor.scene = this;
|
||||
this.entityProcessors.add(processor);
|
||||
return processor;
|
||||
}
|
||||
renderer.onAddedToScene(this);
|
||||
|
||||
/**
|
||||
* 从场景中删除EntitySystem处理器
|
||||
* @param processor
|
||||
*/
|
||||
public removeEntityProcessor(processor: EntitySystem) {
|
||||
this.entityProcessors.remove(processor);
|
||||
}
|
||||
return renderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取EntitySystem处理器
|
||||
*/
|
||||
public getEntityProcessor<T extends EntitySystem>(): T {
|
||||
return this.entityProcessors.getProcessor<T>();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 获取类型为T的第一个渲染器
|
||||
* @param type
|
||||
*/
|
||||
public getRenderer<T extends Renderer>(type): T {
|
||||
for (let i = 0; i < this._renderers.length; i++) {
|
||||
if (this._renderers[i] instanceof type)
|
||||
return this._renderers[i] as T;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从场景中移除渲染器
|
||||
* @param renderer
|
||||
*/
|
||||
public removeRenderer(renderer: Renderer) {
|
||||
if (!this._renderers.contains(renderer))
|
||||
return;
|
||||
this._renderers.remove(renderer);
|
||||
renderer.unload();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加一个后处理器到场景。设置场景字段并调用后处理器。onAddedToScene使后处理器可以使用场景ContentManager加载资源。
|
||||
* @param postProcessor
|
||||
*/
|
||||
public addPostProcessor<T extends PostProcessor>(postProcessor: T): T {
|
||||
this._postProcessors.push(postProcessor);
|
||||
this._postProcessors.sort();
|
||||
postProcessor.onAddedToScene(this);
|
||||
|
||||
if (this._didSceneBegin) {
|
||||
postProcessor.onSceneBackBufferSizeChanged(this.stage.stageWidth, this.stage.stageHeight);
|
||||
}
|
||||
|
||||
return postProcessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取类型为T的第一个后处理器
|
||||
* @param type
|
||||
*/
|
||||
public getPostProcessor<T extends PostProcessor>(type): T {
|
||||
for (let i = 0; i < this._postProcessors.length; i++) {
|
||||
if (this._postProcessors[i] instanceof type)
|
||||
return this._postProcessors[i] as T;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除一个后处理程序。注意,在删除时不会调用unload,因此如果不再需要PostProcessor,请确保调用unload来释放资源。
|
||||
* @param postProcessor
|
||||
*/
|
||||
public removePostProcessor(postProcessor: PostProcessor) {
|
||||
if (!this._postProcessors.contains(postProcessor))
|
||||
return;
|
||||
|
||||
this._postProcessors.remove(postProcessor);
|
||||
postProcessor.unload();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将实体添加到此场景,并返回它
|
||||
* @param name
|
||||
*/
|
||||
public createEntity(name: string) {
|
||||
let entity = new Entity(name);
|
||||
return this.addEntity(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在场景的实体列表中添加一个实体
|
||||
* @param entity
|
||||
*/
|
||||
public addEntity(entity: Entity) {
|
||||
if (this.entities.buffer.contains(entity))
|
||||
console.warn(`You are attempting to add the same entity to a scene twice: ${entity}`);
|
||||
this.entities.add(entity);
|
||||
entity.scene = this;
|
||||
|
||||
for (let i = 0; i < entity.transform.childCount; i++)
|
||||
this.addEntity(entity.transform.getChild(i).entity);
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从场景中删除所有实体
|
||||
*/
|
||||
public destroyAllEntities() {
|
||||
for (let i = 0; i < this.entities.count; i++) {
|
||||
this.entities.buffer[i].destroy();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索并返回第一个具有名称的实体
|
||||
* @param name
|
||||
*/
|
||||
public findEntity(name: string): Entity {
|
||||
return this.entities.findEntity(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回具有给定标记的所有实体
|
||||
* @param tag
|
||||
*/
|
||||
public findEntitiesWithTag(tag: number): Entity[] {
|
||||
return this.entities.entitiesWithTag(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回类型为T的所有实体
|
||||
* @param type
|
||||
*/
|
||||
public entitiesOfType<T extends Entity>(type): T[] {
|
||||
return this.entities.entitiesOfType<T>(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回第一个启用加载的类型为T的组件
|
||||
* @param type
|
||||
*/
|
||||
public findComponentOfType<T extends Component>(type): T {
|
||||
return this.entities.findComponentOfType<T>(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回类型为T的所有已启用已加载组件的列表
|
||||
* @param type
|
||||
*/
|
||||
public findComponentsOfType<T extends Component>(type): T[] {
|
||||
return this.entities.findComponentsOfType<T>(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在场景中添加一个EntitySystem处理器
|
||||
* @param processor 处理器
|
||||
*/
|
||||
public addEntityProcessor(processor: EntitySystem) {
|
||||
processor.scene = this;
|
||||
this.entityProcessors.add(processor);
|
||||
return processor;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从场景中删除EntitySystem处理器
|
||||
* @param processor
|
||||
*/
|
||||
public removeEntityProcessor(processor: EntitySystem) {
|
||||
this.entityProcessors.remove(processor);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取EntitySystem处理器
|
||||
*/
|
||||
public getEntityProcessor<T extends EntitySystem>(): T {
|
||||
return this.entityProcessors.getProcessor<T>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,80 +1,82 @@
|
||||
module es {
|
||||
export class EntitySystem {
|
||||
private _scene: Scene;
|
||||
private _entities: Entity[] = [];
|
||||
private _matcher: Matcher;
|
||||
|
||||
public get matcher(){
|
||||
return this._matcher;
|
||||
constructor(matcher?: Matcher) {
|
||||
this._matcher = matcher ? matcher : Matcher.empty();
|
||||
}
|
||||
|
||||
public get scene(){
|
||||
private _scene: Scene;
|
||||
|
||||
public get scene() {
|
||||
return this._scene;
|
||||
}
|
||||
|
||||
public set scene(value: Scene){
|
||||
public set scene(value: Scene) {
|
||||
this._scene = value;
|
||||
this._entities = [];
|
||||
}
|
||||
|
||||
constructor(matcher?: Matcher){
|
||||
this._matcher = matcher ? matcher : Matcher.empty();
|
||||
private _matcher: Matcher;
|
||||
|
||||
public get matcher() {
|
||||
return this._matcher;
|
||||
}
|
||||
|
||||
public initialize(){
|
||||
public initialize() {
|
||||
|
||||
}
|
||||
|
||||
public onChanged(entity: Entity){
|
||||
public onChanged(entity: Entity) {
|
||||
let contains = this._entities.contains(entity);
|
||||
let interest = this._matcher.IsIntersted(entity);
|
||||
|
||||
if (interest && !contains)
|
||||
this.add(entity);
|
||||
else if(!interest && contains)
|
||||
else if (!interest && contains)
|
||||
this.remove(entity);
|
||||
}
|
||||
|
||||
public add(entity: Entity){
|
||||
public add(entity: Entity) {
|
||||
this._entities.push(entity);
|
||||
this.onAdded(entity);
|
||||
}
|
||||
|
||||
public onAdded(entity: Entity){
|
||||
public onAdded(entity: Entity) {
|
||||
}
|
||||
|
||||
public remove(entity: Entity){
|
||||
public remove(entity: Entity) {
|
||||
this._entities.remove(entity);
|
||||
this.onRemoved(entity);
|
||||
}
|
||||
|
||||
public onRemoved(entity: Entity){
|
||||
public onRemoved(entity: Entity) {
|
||||
|
||||
}
|
||||
|
||||
public update(){
|
||||
public update() {
|
||||
this.begin();
|
||||
this.process(this._entities);
|
||||
}
|
||||
|
||||
public lateUpdate(){
|
||||
public lateUpdate() {
|
||||
this.lateProcess(this._entities);
|
||||
this.end();
|
||||
}
|
||||
|
||||
protected begin(){
|
||||
protected begin() {
|
||||
|
||||
}
|
||||
|
||||
protected process(entities: Entity[]){
|
||||
protected process(entities: Entity[]) {
|
||||
|
||||
}
|
||||
|
||||
protected lateProcess(entities: Entity[]){
|
||||
protected lateProcess(entities: Entity[]) {
|
||||
|
||||
}
|
||||
|
||||
protected end(){
|
||||
protected end() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
module es {
|
||||
export abstract class PassiveSystem extends EntitySystem {
|
||||
public onChanged(entity: Entity){
|
||||
public onChanged(entity: Entity) {
|
||||
|
||||
}
|
||||
|
||||
protected process(entities: Entity[]){
|
||||
protected process(entities: Entity[]) {
|
||||
// 我们用我们自己的不考虑实体的基本实体系统来代替
|
||||
this.begin();
|
||||
this.end();
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
/** 用于协调其他系统的通用系统基类 */
|
||||
module es {
|
||||
export abstract class ProcessingSystem extends EntitySystem {
|
||||
public onChanged(entity: Entity){
|
||||
public onChanged(entity: Entity) {
|
||||
|
||||
}
|
||||
|
||||
protected process(entities: Entity[]){
|
||||
this.begin();
|
||||
this.processSystem();
|
||||
this.end();
|
||||
}
|
||||
|
||||
/** 处理我们的系统 每帧调用 */
|
||||
public abstract processSystem();
|
||||
|
||||
protected process(entities: Entity[]) {
|
||||
this.begin();
|
||||
this.processSystem();
|
||||
this.end();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,78 @@ module es {
|
||||
export class Transform extends HashObject {
|
||||
/** 与此转换关联的实体 */
|
||||
public readonly entity: Entity;
|
||||
public hierarchyDirty: DirtyType;
|
||||
public _localDirty: boolean;
|
||||
public _localPositionDirty: boolean;
|
||||
public _localScaleDirty: boolean;
|
||||
public _localRotationDirty: boolean;
|
||||
public _positionDirty: boolean;
|
||||
public _worldToLocalDirty: boolean;
|
||||
public _worldInverseDirty: boolean;
|
||||
/**
|
||||
* 值会根据位置、旋转和比例自动重新计算
|
||||
*/
|
||||
public _localTransform: Matrix2D = Matrix2D.create();
|
||||
/**
|
||||
* 值将自动从本地和父矩阵重新计算。
|
||||
*/
|
||||
public _worldTransform = Matrix2D.create().identity();
|
||||
public _rotationMatrix: Matrix2D = Matrix2D.create();
|
||||
public _translationMatrix: Matrix2D = Matrix2D.create();
|
||||
public _scaleMatrix: Matrix2D = Matrix2D.create();
|
||||
public _children: Transform[];
|
||||
|
||||
constructor(entity: Entity) {
|
||||
super();
|
||||
this.entity = entity;
|
||||
this.scale = Vector2.one;
|
||||
this._children = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 这个转换的所有子元素
|
||||
*/
|
||||
public get childCount() {
|
||||
return this._children.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* 变换在世界空间的旋转度
|
||||
*/
|
||||
public get rotationDegrees(): number {
|
||||
return MathHelper.toDegrees(this._rotation);
|
||||
}
|
||||
|
||||
/**
|
||||
* 变换在世界空间的旋转度
|
||||
* @param value
|
||||
*/
|
||||
public set rotationDegrees(value: number) {
|
||||
this.setRotation(MathHelper.toRadians(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* 旋转相对于父变换旋转的角度
|
||||
*/
|
||||
public get localRotationDegrees(): number {
|
||||
return MathHelper.toDegrees(this._localRotation);
|
||||
}
|
||||
|
||||
/**
|
||||
* 旋转相对于父变换旋转的角度
|
||||
* @param value
|
||||
*/
|
||||
public set localRotationDegrees(value: number) {
|
||||
this.localRotation = MathHelper.toRadians(value);
|
||||
}
|
||||
|
||||
public get localToWorldTransform(): Matrix2D {
|
||||
this.updateTransform();
|
||||
return this._worldTransform;
|
||||
}
|
||||
|
||||
public _parent: Transform;
|
||||
|
||||
/**
|
||||
* 获取此转换的父转换
|
||||
*/
|
||||
@@ -34,22 +106,46 @@ module es {
|
||||
this.setParent(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 这个转换的所有子元素
|
||||
*/
|
||||
public get childCount() {
|
||||
return this._children.length;
|
||||
public _worldToLocalTransform = Matrix2D.create().identity();
|
||||
|
||||
public get worldToLocalTransform(): Matrix2D {
|
||||
if (this._worldToLocalDirty) {
|
||||
if (!this.parent) {
|
||||
this._worldToLocalTransform = Matrix2D.create().identity();
|
||||
} else {
|
||||
this.parent.updateTransform();
|
||||
this._worldToLocalTransform = this.parent._worldTransform.invert();
|
||||
}
|
||||
|
||||
this._worldToLocalDirty = false;
|
||||
}
|
||||
|
||||
return this._worldToLocalTransform;
|
||||
}
|
||||
|
||||
public _worldInverseTransform = Matrix2D.create().identity();
|
||||
|
||||
public get worldInverseTransform(): Matrix2D {
|
||||
this.updateTransform();
|
||||
if (this._worldInverseDirty) {
|
||||
this._worldInverseTransform = this._worldTransform.invert();
|
||||
this._worldInverseDirty = false;
|
||||
}
|
||||
|
||||
return this._worldInverseTransform;
|
||||
}
|
||||
|
||||
public _position: Vector2 = Vector2.zero;
|
||||
|
||||
/**
|
||||
* 变换在世界空间中的位置
|
||||
*/
|
||||
public get position(): Vector2 {
|
||||
this.updateTransform();
|
||||
if (this._positionDirty){
|
||||
if (!this.parent){
|
||||
if (this._positionDirty) {
|
||||
if (!this.parent) {
|
||||
this._position = this._localPosition;
|
||||
}else{
|
||||
} else {
|
||||
this.parent.updateTransform();
|
||||
this._position = Vector2Ext.transformR(this._localPosition, this.parent._worldTransform);
|
||||
}
|
||||
@@ -64,10 +160,48 @@ module es {
|
||||
* 变换在世界空间中的位置
|
||||
* @param value
|
||||
*/
|
||||
public set position(value: Vector2){
|
||||
public set position(value: Vector2) {
|
||||
this.setPosition(value.x, value.y);
|
||||
}
|
||||
|
||||
public _scale: Vector2 = Vector2.one;
|
||||
|
||||
/**
|
||||
* 变换在世界空间的缩放
|
||||
*/
|
||||
public get scale(): Vector2 {
|
||||
this.updateTransform();
|
||||
return this._scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* 变换在世界空间的缩放
|
||||
* @param value
|
||||
*/
|
||||
public set scale(value: Vector2) {
|
||||
this.setScale(value);
|
||||
}
|
||||
|
||||
public _rotation: number = 0;
|
||||
|
||||
/**
|
||||
* 在世界空间中以弧度旋转的变换
|
||||
*/
|
||||
public get rotation(): number {
|
||||
this.updateTransform();
|
||||
return this._rotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* 变换在世界空间的旋转度
|
||||
* @param value
|
||||
*/
|
||||
public set rotation(value: number) {
|
||||
this.setRotation(value);
|
||||
}
|
||||
|
||||
public _localPosition: Vector2 = Vector2.zero;
|
||||
|
||||
/**
|
||||
* 转换相对于父转换的位置。如果转换没有父元素,则与transform.position相同
|
||||
*/
|
||||
@@ -80,87 +214,11 @@ module es {
|
||||
* 转换相对于父转换的位置。如果转换没有父元素,则与transform.position相同
|
||||
* @param value
|
||||
*/
|
||||
public set localPosition(value: Vector2){
|
||||
public set localPosition(value: Vector2) {
|
||||
this.setLocalPosition(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在世界空间中以弧度旋转的变换
|
||||
*/
|
||||
public get rotation(): number {
|
||||
this.updateTransform();
|
||||
return this._rotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* 变换在世界空间的旋转度
|
||||
*/
|
||||
public get rotationDegrees(): number {
|
||||
return MathHelper.toDegrees(this._rotation);
|
||||
}
|
||||
|
||||
/**
|
||||
* 变换在世界空间的旋转度
|
||||
* @param value
|
||||
*/
|
||||
public set rotationDegrees(value: number){
|
||||
this.setRotation(MathHelper.toRadians(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* 变换在世界空间的旋转度
|
||||
* @param value
|
||||
*/
|
||||
public set rotation(value: number){
|
||||
this.setRotation(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 相对于父变换的旋转,变换的旋转。如果转换没有父元素,则与transform.rotation相同
|
||||
*/
|
||||
public get localRotation(): number {
|
||||
this.updateTransform();
|
||||
return this._localRotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* 相对于父变换的旋转,变换的旋转。如果转换没有父元素,则与transform.rotation相同
|
||||
* @param value
|
||||
*/
|
||||
public set localRotation(value: number){
|
||||
this.setLocalRotation(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 旋转相对于父变换旋转的角度
|
||||
*/
|
||||
public get localRotationDegrees(): number {
|
||||
return MathHelper.toDegrees(this._localRotation);
|
||||
}
|
||||
|
||||
/**
|
||||
* 旋转相对于父变换旋转的角度
|
||||
* @param value
|
||||
*/
|
||||
public set localRotationDegrees(value: number){
|
||||
this.localRotation = MathHelper.toRadians(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 变换在世界空间的缩放
|
||||
*/
|
||||
public get scale(): Vector2{
|
||||
this.updateTransform();
|
||||
return this._scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* 变换在世界空间的缩放
|
||||
* @param value
|
||||
*/
|
||||
public set scale(value: Vector2){
|
||||
this.setScale(value);
|
||||
}
|
||||
public _localScale: Vector2 = Vector2.one;
|
||||
|
||||
/**
|
||||
* 转换相对于父元素的比例。如果转换没有父元素,则与transform.scale相同
|
||||
@@ -174,81 +232,26 @@ module es {
|
||||
* 转换相对于父元素的比例。如果转换没有父元素,则与transform.scale相同
|
||||
* @param value
|
||||
*/
|
||||
public set localScale(value: Vector2){
|
||||
public set localScale(value: Vector2) {
|
||||
this.setLocalScale(value);
|
||||
}
|
||||
|
||||
public get worldInverseTransform(): Matrix2D {
|
||||
this.updateTransform();
|
||||
if (this._worldInverseDirty){
|
||||
this._worldInverseTransform = this._worldTransform.invert();
|
||||
this._worldInverseDirty = false;
|
||||
}
|
||||
|
||||
return this._worldInverseTransform;
|
||||
}
|
||||
|
||||
public get localToWorldTransform(): Matrix2D {
|
||||
this.updateTransform();
|
||||
return this._worldTransform;
|
||||
}
|
||||
|
||||
public get worldToLocalTransform(): Matrix2D {
|
||||
if (this._worldToLocalDirty){
|
||||
if (!this.parent){
|
||||
this._worldToLocalTransform = Matrix2D.create().identity();
|
||||
}else{
|
||||
this.parent.updateTransform();
|
||||
this._worldToLocalTransform = this.parent._worldTransform.invert();
|
||||
}
|
||||
|
||||
this._worldToLocalDirty = false;
|
||||
}
|
||||
|
||||
return this._worldToLocalTransform;
|
||||
}
|
||||
|
||||
public _parent: Transform;
|
||||
public hierarchyDirty: DirtyType;
|
||||
|
||||
public _localDirty: boolean;
|
||||
public _localPositionDirty: boolean;
|
||||
public _localScaleDirty: boolean;
|
||||
public _localRotationDirty: boolean;
|
||||
public _positionDirty: boolean;
|
||||
public _worldToLocalDirty: boolean;
|
||||
public _worldInverseDirty: boolean;
|
||||
|
||||
/**
|
||||
* 值会根据位置、旋转和比例自动重新计算
|
||||
*/
|
||||
public _localTransform: Matrix2D = Matrix2D.create();
|
||||
/**
|
||||
* 值将自动从本地和父矩阵重新计算。
|
||||
*/
|
||||
public _worldTransform = Matrix2D.create().identity();
|
||||
public _worldToLocalTransform = Matrix2D.create().identity();
|
||||
public _worldInverseTransform = Matrix2D.create().identity();
|
||||
|
||||
public _rotationMatrix: Matrix2D = Matrix2D.create();
|
||||
public _translationMatrix: Matrix2D = Matrix2D.create();
|
||||
public _scaleMatrix: Matrix2D = Matrix2D.create();
|
||||
|
||||
public _position: Vector2 = Vector2.zero;
|
||||
public _scale: Vector2 = Vector2.one;
|
||||
public _rotation: number = 0;
|
||||
|
||||
public _localPosition: Vector2 = Vector2.zero;
|
||||
public _localScale: Vector2 = Vector2.one;
|
||||
public _localRotation: number = 0;
|
||||
|
||||
public _children: Transform[];
|
||||
/**
|
||||
* 相对于父变换的旋转,变换的旋转。如果转换没有父元素,则与transform.rotation相同
|
||||
*/
|
||||
public get localRotation(): number {
|
||||
this.updateTransform();
|
||||
return this._localRotation;
|
||||
}
|
||||
|
||||
constructor(entity: Entity) {
|
||||
super();
|
||||
this.entity = entity;
|
||||
this.scale = Vector2.one;
|
||||
this._children = [];
|
||||
/**
|
||||
* 相对于父变换的旋转,变换的旋转。如果转换没有父元素,则与transform.rotation相同
|
||||
* @param value
|
||||
*/
|
||||
public set localRotation(value: number) {
|
||||
this.setLocalRotation(value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -289,7 +292,7 @@ module es {
|
||||
return this;
|
||||
|
||||
this._position = position;
|
||||
if (this.parent){
|
||||
if (this.parent) {
|
||||
this.localPosition = Vector2Ext.transformR(this._position, this._worldToLocalTransform);
|
||||
} else {
|
||||
this.localPosition = position;
|
||||
@@ -321,7 +324,7 @@ module es {
|
||||
*/
|
||||
public setRotation(radians: number): Transform {
|
||||
this._rotation = radians;
|
||||
if (this.parent){
|
||||
if (this.parent) {
|
||||
this.localRotation = this.parent.rotation + radians;
|
||||
} else {
|
||||
this.localRotation = radians;
|
||||
@@ -352,7 +355,7 @@ module es {
|
||||
* 相对于父变换的旋转设置变换的旋转。如果转换没有父元素,则与transform.rotation相同
|
||||
* @param radians
|
||||
*/
|
||||
public setLocalRotation(radians: number){
|
||||
public setLocalRotation(radians: number) {
|
||||
this._localRotation = radians;
|
||||
this._localDirty = this._positionDirty = this._localPositionDirty = this._localRotationDirty = this._localScaleDirty = true;
|
||||
this.setDirty(DirtyType.rotationDirty);
|
||||
@@ -374,9 +377,9 @@ module es {
|
||||
*/
|
||||
public setScale(scale: Vector2): Transform {
|
||||
this._scale = scale;
|
||||
if (this.parent){
|
||||
if (this.parent) {
|
||||
this.localScale = Vector2.divide(scale, this.parent._scale);
|
||||
}else{
|
||||
} else {
|
||||
this.localScale = scale;
|
||||
}
|
||||
return this;
|
||||
@@ -401,23 +404,23 @@ module es {
|
||||
this.position = this._position.round();
|
||||
}
|
||||
|
||||
public updateTransform(){
|
||||
if (this.hierarchyDirty != DirtyType.clean){
|
||||
public updateTransform() {
|
||||
if (this.hierarchyDirty != DirtyType.clean) {
|
||||
if (this.parent)
|
||||
this.parent.updateTransform();
|
||||
|
||||
if (this._localDirty){
|
||||
if (this._localPositionDirty){
|
||||
if (this._localDirty) {
|
||||
if (this._localPositionDirty) {
|
||||
this._translationMatrix = Matrix2D.create().translate(this._localPosition.x, this._localPosition.y);
|
||||
this._localPositionDirty = false;
|
||||
}
|
||||
|
||||
if (this._localRotationDirty){
|
||||
if (this._localRotationDirty) {
|
||||
this._rotationMatrix = Matrix2D.create().rotate(this._localRotation);
|
||||
this._localRotationDirty = false;
|
||||
}
|
||||
|
||||
if (this._localScaleDirty){
|
||||
if (this._localScaleDirty) {
|
||||
this._scaleMatrix = Matrix2D.create().scale(this._localScale.x, this._localScale.y);
|
||||
this._localScaleDirty = false;
|
||||
}
|
||||
@@ -425,7 +428,7 @@ module es {
|
||||
this._localTransform = this._scaleMatrix.multiply(this._rotationMatrix);
|
||||
this._localTransform = this._localTransform.multiply(this._translationMatrix);
|
||||
|
||||
if (!this.parent){
|
||||
if (!this.parent) {
|
||||
this._worldTransform = this._localTransform;
|
||||
this._rotation = this._localRotation;
|
||||
this._scale = this._localScale;
|
||||
@@ -435,7 +438,7 @@ module es {
|
||||
this._localDirty = false;
|
||||
}
|
||||
|
||||
if (this.parent){
|
||||
if (this.parent) {
|
||||
this._worldTransform = this._localTransform.multiply(this.parent._worldTransform);
|
||||
|
||||
this._rotation = this._localRotation + this.parent._rotation;
|
||||
@@ -449,8 +452,8 @@ module es {
|
||||
}
|
||||
}
|
||||
|
||||
public setDirty(dirtyFlagType: DirtyType){
|
||||
if ((this.hierarchyDirty & dirtyFlagType) == 0){
|
||||
public setDirty(dirtyFlagType: DirtyType) {
|
||||
if ((this.hierarchyDirty & dirtyFlagType) == 0) {
|
||||
this.hierarchyDirty |= dirtyFlagType;
|
||||
|
||||
switch (dirtyFlagType) {
|
||||
@@ -469,7 +472,7 @@ module es {
|
||||
this._children = [];
|
||||
|
||||
// 告诉子项发生了变换
|
||||
for (let i = 0; i < this._children.length; i ++)
|
||||
for (let i = 0; i < this._children.length; i++)
|
||||
this._children[i].setDirty(dirtyFlagType);
|
||||
}
|
||||
}
|
||||
@@ -491,13 +494,13 @@ module es {
|
||||
this.setDirty(DirtyType.scaleDirty);
|
||||
}
|
||||
|
||||
public toString(): string{
|
||||
public toString(): string {
|
||||
return `[Transform: parent: ${this.parent}, position: ${this.position}, rotation: ${this.rotation},
|
||||
scale: ${this.scale}, localPosition: ${this._localPosition}, localRotation: ${this._localRotation},
|
||||
localScale: ${this._localScale}]`;
|
||||
}
|
||||
|
||||
public equals(other: Transform){
|
||||
public equals(other: Transform) {
|
||||
return other.hashCode == this.hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,43 +4,43 @@ module es {
|
||||
*
|
||||
* 它是由一个位向量实现的,但同样可以把它看成是一个非负整数的集合;集合中的每个整数由对应索引处的集合位表示。该结构的大小由集合中的最大整数决定。
|
||||
*/
|
||||
export class BitSet{
|
||||
export class BitSet {
|
||||
private static LONG_MASK: number = 0x3f;
|
||||
private _bits: number[];
|
||||
|
||||
constructor(nbits: number = 64){
|
||||
constructor(nbits: number = 64) {
|
||||
let length = nbits >> 6;
|
||||
if ((nbits & BitSet.LONG_MASK) != 0)
|
||||
length ++;
|
||||
length++;
|
||||
|
||||
this._bits = new Array(length);
|
||||
}
|
||||
|
||||
public and(bs: BitSet){
|
||||
public and(bs: BitSet) {
|
||||
let max = Math.min(this._bits.length, bs._bits.length);
|
||||
let i;
|
||||
for (let i = 0; i < max; ++i)
|
||||
this._bits[i] &= bs._bits[i];
|
||||
|
||||
while (i < this._bits.length)
|
||||
this._bits[i ++] = 0;
|
||||
this._bits[i++] = 0;
|
||||
}
|
||||
|
||||
public andNot(bs: BitSet){
|
||||
public andNot(bs: BitSet) {
|
||||
let i = Math.min(this._bits.length, bs._bits.length);
|
||||
while(--i >= 0)
|
||||
while (--i >= 0)
|
||||
this._bits[i] &= ~bs._bits[i];
|
||||
}
|
||||
|
||||
public cardinality(): number{
|
||||
public cardinality(): number {
|
||||
let card = 0;
|
||||
for (let i = this._bits.length - 1; i >= 0; i --){
|
||||
for (let i = this._bits.length - 1; i >= 0; i--) {
|
||||
let a = this._bits[i];
|
||||
|
||||
if (a == 0)
|
||||
continue;
|
||||
|
||||
if (a == -1){
|
||||
if (a == -1) {
|
||||
card += 64;
|
||||
continue;
|
||||
}
|
||||
@@ -56,26 +56,18 @@ module es {
|
||||
return card;
|
||||
}
|
||||
|
||||
public clear(pos?: number){
|
||||
if (pos != undefined){
|
||||
public clear(pos?: number) {
|
||||
if (pos != undefined) {
|
||||
let offset = pos >> 6;
|
||||
this.ensure(offset);
|
||||
this._bits[offset] &= ~(1 << pos);
|
||||
}else{
|
||||
for (let i = 0; i < this._bits.length; i ++)
|
||||
} else {
|
||||
for (let i = 0; i < this._bits.length; i++)
|
||||
this._bits[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private ensure(lastElt: number){
|
||||
if (lastElt >= this._bits.length){
|
||||
let nd = new Number[lastElt + 1];
|
||||
nd = this._bits.copyWithin(0, 0, this._bits.length);
|
||||
this._bits = nd;
|
||||
}
|
||||
}
|
||||
|
||||
public get(pos: number): boolean{
|
||||
public get(pos: number): boolean {
|
||||
let offset = pos >> 6;
|
||||
if (offset >= this._bits.length)
|
||||
return false;
|
||||
@@ -83,9 +75,9 @@ module es {
|
||||
return (this._bits[offset] & (1 << pos)) != 0;
|
||||
}
|
||||
|
||||
public intersects(set: BitSet){
|
||||
public intersects(set: BitSet) {
|
||||
let i = Math.min(this._bits.length, set._bits.length);
|
||||
while (--i >= 0){
|
||||
while (--i >= 0) {
|
||||
if ((this._bits[i] & set._bits[i]) != 0)
|
||||
return true;
|
||||
}
|
||||
@@ -93,8 +85,8 @@ module es {
|
||||
return false;
|
||||
}
|
||||
|
||||
public isEmpty(): boolean{
|
||||
for (let i = this._bits.length - 1; i >= 0; i --){
|
||||
public isEmpty(): boolean {
|
||||
for (let i = this._bits.length - 1; i >= 0; i--) {
|
||||
if (this._bits[i])
|
||||
return false;
|
||||
}
|
||||
@@ -102,34 +94,42 @@ module es {
|
||||
return true;
|
||||
}
|
||||
|
||||
public nextSetBit(from: number){
|
||||
public nextSetBit(from: number) {
|
||||
let offset = from >> 6;
|
||||
let mask = 1 << from;
|
||||
while (offset < this._bits.length){
|
||||
while (offset < this._bits.length) {
|
||||
let h = this._bits[offset];
|
||||
do {
|
||||
if ((h & mask) != 0)
|
||||
return from;
|
||||
|
||||
mask <<= 1;
|
||||
from ++;
|
||||
from++;
|
||||
} while (mask != 0);
|
||||
|
||||
mask = 1;
|
||||
offset ++;
|
||||
offset++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public set(pos: number, value: boolean = true){
|
||||
if (value){
|
||||
public set(pos: number, value: boolean = true) {
|
||||
if (value) {
|
||||
let offset = pos >> 6;
|
||||
this.ensure(offset);
|
||||
this._bits[offset] |= 1 << pos;
|
||||
}else{
|
||||
} else {
|
||||
this.clear(pos);
|
||||
}
|
||||
}
|
||||
|
||||
private ensure(lastElt: number) {
|
||||
if (lastElt >= this._bits.length) {
|
||||
let nd = new Number[lastElt + 1];
|
||||
nd = this._bits.copyWithin(0, 0, this._bits.length);
|
||||
this._bits = nd;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ module es {
|
||||
return this._components;
|
||||
}
|
||||
|
||||
public markEntityListUnsorted(){
|
||||
public markEntityListUnsorted() {
|
||||
this._isComponentListUnsorted = true;
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ module es {
|
||||
let component = this._components[i];
|
||||
|
||||
// 处理渲染层列表
|
||||
if (component instanceof RenderableComponent){
|
||||
if (component instanceof RenderableComponent) {
|
||||
this._entity.scene.removeChild(component.displayObject);
|
||||
this._entity.scene.renderableComponents.remove(component);
|
||||
}
|
||||
@@ -91,7 +91,7 @@ module es {
|
||||
for (let i = 0; i < this._components.length; i++) {
|
||||
let component = this._components[i];
|
||||
|
||||
if (component instanceof RenderableComponent){
|
||||
if (component instanceof RenderableComponent) {
|
||||
this._entity.scene.addChild(component.displayObject);
|
||||
this._entity.scene.renderableComponents.add(component);
|
||||
}
|
||||
@@ -117,7 +117,7 @@ module es {
|
||||
if (this._componentsToAdd.length > 0) {
|
||||
for (let i = 0, count = this._componentsToAdd.length; i < count; i++) {
|
||||
let component = this._componentsToAdd[i];
|
||||
if (component instanceof RenderableComponent){
|
||||
if (component instanceof RenderableComponent) {
|
||||
this._entity.scene.addChild(component.displayObject);
|
||||
this._entity.scene.renderableComponents.add(component);
|
||||
}
|
||||
@@ -148,7 +148,7 @@ module es {
|
||||
this._tempBufferList.length = 0;
|
||||
}
|
||||
|
||||
if (this._isComponentListUnsorted){
|
||||
if (this._isComponentListUnsorted) {
|
||||
this._components.sort(ComponentList.compareUpdatableOrder.compare);
|
||||
this._isComponentListUnsorted = false;
|
||||
}
|
||||
@@ -156,7 +156,7 @@ module es {
|
||||
|
||||
public handleRemove(component: Component) {
|
||||
// 处理渲染层列表
|
||||
if (component instanceof RenderableComponent){
|
||||
if (component instanceof RenderableComponent) {
|
||||
this._entity.scene.removeChild(component.displayObject);
|
||||
this._entity.scene.renderableComponents.remove(component);
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
module es {
|
||||
export class ComponentTypeManager{
|
||||
export class ComponentTypeManager {
|
||||
private static _componentTypesMask: Map<any, number> = new Map<any, number>();
|
||||
|
||||
public static add(type){
|
||||
public static add(type) {
|
||||
if (!this._componentTypesMask.has(type))
|
||||
this._componentTypesMask[type] = this._componentTypesMask.size;
|
||||
}
|
||||
|
||||
public static getIndexFor(type){
|
||||
public static getIndexFor(type) {
|
||||
let v = -1;
|
||||
if (!this._componentTypesMask.has(type)){
|
||||
if (!this._componentTypesMask.has(type)) {
|
||||
this.add(type);
|
||||
v = this._componentTypesMask.get(type);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module es {
|
||||
export class EntityList{
|
||||
export class EntityList {
|
||||
public scene: Scene;
|
||||
/**
|
||||
* 添加到场景中的实体列表
|
||||
@@ -27,23 +27,23 @@ module es {
|
||||
*/
|
||||
public _tempEntityList: Entity[] = [];
|
||||
|
||||
constructor(scene: Scene){
|
||||
constructor(scene: Scene) {
|
||||
this.scene = scene;
|
||||
}
|
||||
|
||||
public get count(){
|
||||
public get count() {
|
||||
return this._entities.length;
|
||||
}
|
||||
|
||||
public get buffer(){
|
||||
public get buffer() {
|
||||
return this._entities;
|
||||
}
|
||||
|
||||
public markEntityListUnsorted(){
|
||||
public markEntityListUnsorted() {
|
||||
this._isEntityListUnsorted = true;
|
||||
}
|
||||
|
||||
public markTagUnsorted(tag: number){
|
||||
public markTagUnsorted(tag: number) {
|
||||
this._unsortedTags.push(tag);
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ module es {
|
||||
* 将实体添加到列表中。所有生命周期方法将在下一帧中被调用。
|
||||
* @param entity
|
||||
*/
|
||||
public add(entity: Entity){
|
||||
public add(entity: Entity) {
|
||||
if (this._entitiesToAdded.indexOf(entity) == -1)
|
||||
this._entitiesToAdded.push(entity);
|
||||
}
|
||||
@@ -60,14 +60,14 @@ module es {
|
||||
* 从列表中删除一个实体。所有生命周期方法将在下一帧中被调用。
|
||||
* @param entity
|
||||
*/
|
||||
public remove(entity: Entity){
|
||||
if (!this._entitiesToRemove.contains(entity)){
|
||||
public remove(entity: Entity) {
|
||||
if (!this._entitiesToRemove.contains(entity)) {
|
||||
console.warn(`You are trying to remove an entity (${entity.name}) that you already removed`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 防止在同一帧中添加或删除实体
|
||||
if (this._entitiesToAdded.contains(entity)){
|
||||
if (this._entitiesToAdded.contains(entity)) {
|
||||
this._entitiesToAdded.remove(entity);
|
||||
return;
|
||||
}
|
||||
@@ -79,7 +79,7 @@ module es {
|
||||
/**
|
||||
* 从实体列表中删除所有实体
|
||||
*/
|
||||
public removeAllEntities(){
|
||||
public removeAllEntities() {
|
||||
this._unsortedTags.length = 0;
|
||||
this._entitiesToAdded.length = 0;
|
||||
this._isEntityListUnsorted = false;
|
||||
@@ -88,7 +88,7 @@ module es {
|
||||
// 它们仍然在_entitiesToRemove列表中,该列表将由更新列表处理。
|
||||
this.updateLists();
|
||||
|
||||
for (let i = 0; i < this._entities.length; i ++){
|
||||
for (let i = 0; i < this._entities.length; i++) {
|
||||
this._entities[i]._isDestroyed = true;
|
||||
this._entities[i].onRemovedFromScene();
|
||||
this._entities[i].scene = null;
|
||||
@@ -106,9 +106,9 @@ module es {
|
||||
return this._entities.contains(entity) || this._entitiesToAdded.contains(entity);
|
||||
}
|
||||
|
||||
public getTagList(tag: number){
|
||||
public getTagList(tag: number) {
|
||||
let list = this._entityDict.get(tag);
|
||||
if (!list){
|
||||
if (!list) {
|
||||
list = [];
|
||||
this._entityDict.set(tag, list);
|
||||
}
|
||||
@@ -116,31 +116,31 @@ module es {
|
||||
return this._entityDict.get(tag);
|
||||
}
|
||||
|
||||
public addToTagList(entity: Entity){
|
||||
public addToTagList(entity: Entity) {
|
||||
let list = this.getTagList(entity.tag);
|
||||
if (!list.contains(entity)){
|
||||
if (!list.contains(entity)) {
|
||||
list.push(entity);
|
||||
this._unsortedTags.push(entity.tag);
|
||||
}
|
||||
}
|
||||
|
||||
public removeFromTagList(entity: Entity){
|
||||
public removeFromTagList(entity: Entity) {
|
||||
let list = this._entityDict.get(entity.tag);
|
||||
if (list){
|
||||
if (list) {
|
||||
list.remove(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public update(){
|
||||
for (let i = 0; i < this._entities.length; i++){
|
||||
public update() {
|
||||
for (let i = 0; i < this._entities.length; i++) {
|
||||
let entity = this._entities[i];
|
||||
if (entity.enabled && (entity.updateInterval == 1 || Time.frameCount % entity.updateInterval == 0))
|
||||
entity.update();
|
||||
}
|
||||
}
|
||||
|
||||
public updateLists(){
|
||||
if (this._entitiesToRemove.length > 0){
|
||||
public updateLists() {
|
||||
if (this._entitiesToRemove.length > 0) {
|
||||
let temp = this._entitiesToRemove;
|
||||
this._entitiesToRemove = this._tempEntityList;
|
||||
this._tempEntityList = temp;
|
||||
@@ -157,12 +157,12 @@ module es {
|
||||
this._tempEntityList.length = 0;
|
||||
}
|
||||
|
||||
if (this._entitiesToAdded.length > 0){
|
||||
if (this._entitiesToAdded.length > 0) {
|
||||
let temp = this._entitiesToAdded;
|
||||
this._entitiesToAdded = this._tempEntityList;
|
||||
this._tempEntityList = temp;
|
||||
this._tempEntityList.forEach(entity => {
|
||||
if (!this._entities.contains(entity)){
|
||||
if (!this._entities.contains(entity)) {
|
||||
this._entities.push(entity);
|
||||
entity.scene = this.scene;
|
||||
|
||||
@@ -178,12 +178,12 @@ module es {
|
||||
this._isEntityListUnsorted = true;
|
||||
}
|
||||
|
||||
if (this._isEntityListUnsorted){
|
||||
if (this._isEntityListUnsorted) {
|
||||
this._entities.sort();
|
||||
this._isEntityListUnsorted = false;
|
||||
}
|
||||
|
||||
if (this._unsortedTags.length > 0){
|
||||
if (this._unsortedTags.length > 0) {
|
||||
this._unsortedTags.forEach(tag => {
|
||||
this._entityDict.get(tag).sort();
|
||||
});
|
||||
@@ -196,8 +196,8 @@ module es {
|
||||
* 返回找到的第一个实体的名称。如果没有找到,则返回null。
|
||||
* @param name
|
||||
*/
|
||||
public findEntity(name: string){
|
||||
for (let i = 0; i < this._entities.length; i ++){
|
||||
public findEntity(name: string) {
|
||||
for (let i = 0; i < this._entities.length; i++) {
|
||||
if (this._entities[i].name == name)
|
||||
return this._entities[i];
|
||||
}
|
||||
@@ -209,11 +209,11 @@ module es {
|
||||
* 返回带有标记的所有实体的列表。如果没有实体具有标记,则返回一个空列表。可以通过ListPool.free将返回的列表放回池中。
|
||||
* @param tag
|
||||
*/
|
||||
public entitiesWithTag(tag: number){
|
||||
public entitiesWithTag(tag: number) {
|
||||
let list = this.getTagList(tag);
|
||||
|
||||
let returnList = ListPool.obtain<Entity>();
|
||||
for (let i = 0; i < list.length; i ++)
|
||||
for (let i = 0; i < list.length; i++)
|
||||
returnList.push(list[i]);
|
||||
|
||||
return returnList;
|
||||
@@ -223,9 +223,9 @@ module es {
|
||||
* 返回t类型的所有实体的列表。返回的列表可以通过ListPool.free放回池中。
|
||||
* @param type
|
||||
*/
|
||||
public entitiesOfType<T extends Entity>(type): T[]{
|
||||
public entitiesOfType<T extends Entity>(type): T[] {
|
||||
let list = ListPool.obtain<T>();
|
||||
for (let i = 0; i < this._entities.length; i ++){
|
||||
for (let i = 0; i < this._entities.length; i++) {
|
||||
if (this._entities[i] instanceof type)
|
||||
list.push(this._entities[i] as T);
|
||||
}
|
||||
@@ -242,17 +242,17 @@ module es {
|
||||
* @param type
|
||||
*/
|
||||
public findComponentOfType<T extends Component>(type): T {
|
||||
for (let i = 0; i < this._entities.length; i ++){
|
||||
if (this._entities[i].enabled){
|
||||
for (let i = 0; i < this._entities.length; i++) {
|
||||
if (this._entities[i].enabled) {
|
||||
let comp = this._entities[i].getComponent<T>(type);
|
||||
if (comp)
|
||||
return comp;
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < this._entitiesToAdded.length; i ++){
|
||||
for (let i = 0; i < this._entitiesToAdded.length; i++) {
|
||||
let entity = this._entitiesToAdded[i];
|
||||
if (entity.enabled){
|
||||
if (entity.enabled) {
|
||||
let comp = entity.getComponent<T>(type);
|
||||
if (comp)
|
||||
return comp;
|
||||
@@ -266,17 +266,17 @@ module es {
|
||||
* 返回在类型t的场景中找到的所有组件。返回的列表可以通过ListPool.free放回池中。
|
||||
* @param type
|
||||
*/
|
||||
public findComponentsOfType<T extends Component>(type): T[]{
|
||||
public findComponentsOfType<T extends Component>(type): T[] {
|
||||
let comps = ListPool.obtain<T>();
|
||||
for (let i = 0; i < this._entities.length; i ++){
|
||||
for (let i = 0; i < this._entities.length; i++) {
|
||||
if (this._entities[i].enabled)
|
||||
this._entities[i].getComponents(type, comps);
|
||||
}
|
||||
|
||||
for (let i = 0; i < this._entitiesToAdded.length; i ++){
|
||||
for (let i = 0; i < this._entitiesToAdded.length; i++) {
|
||||
let entity = this._entitiesToAdded[i];
|
||||
if (entity.enabled)
|
||||
entity.getComponents(type,comps);
|
||||
entity.getComponents(type, comps);
|
||||
}
|
||||
|
||||
return comps;
|
||||
|
||||
@@ -2,64 +2,52 @@ module es {
|
||||
export class EntityProcessorList {
|
||||
private _processors: EntitySystem[] = [];
|
||||
|
||||
public add(processor: EntitySystem){
|
||||
public add(processor: EntitySystem) {
|
||||
this._processors.push(processor);
|
||||
}
|
||||
|
||||
public remove(processor: EntitySystem){
|
||||
public remove(processor: EntitySystem) {
|
||||
this._processors.remove(processor);
|
||||
}
|
||||
|
||||
public onComponentAdded(entity: Entity){
|
||||
public onComponentAdded(entity: Entity) {
|
||||
this.notifyEntityChanged(entity);
|
||||
}
|
||||
|
||||
public onComponentRemoved(entity: Entity){
|
||||
public onComponentRemoved(entity: Entity) {
|
||||
this.notifyEntityChanged(entity);
|
||||
}
|
||||
|
||||
public onEntityAdded(entity: Entity){
|
||||
public onEntityAdded(entity: Entity) {
|
||||
this.notifyEntityChanged(entity);
|
||||
}
|
||||
|
||||
public onEntityRemoved(entity: Entity){
|
||||
public onEntityRemoved(entity: Entity) {
|
||||
this.removeFromProcessors(entity);
|
||||
}
|
||||
|
||||
protected notifyEntityChanged(entity: Entity){
|
||||
for (let i = 0; i < this._processors.length; i ++){
|
||||
this._processors[i].onChanged(entity);
|
||||
}
|
||||
}
|
||||
|
||||
protected removeFromProcessors(entity: Entity){
|
||||
for (let i = 0; i < this._processors.length; i ++){
|
||||
this._processors[i].remove(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public begin(){
|
||||
public begin() {
|
||||
|
||||
}
|
||||
|
||||
public update(){
|
||||
for (let i = 0; i < this._processors.length; i++){
|
||||
public update() {
|
||||
for (let i = 0; i < this._processors.length; i++) {
|
||||
this._processors[i].update();
|
||||
}
|
||||
}
|
||||
|
||||
public lateUpdate(){
|
||||
for (let i = 0; i < this._processors.length; i ++){
|
||||
public lateUpdate() {
|
||||
for (let i = 0; i < this._processors.length; i++) {
|
||||
this._processors[i].lateUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public end(){
|
||||
public end() {
|
||||
|
||||
}
|
||||
|
||||
public getProcessor<T extends EntitySystem>(): T{
|
||||
for (let i = 0; i < this._processors.length; i ++){
|
||||
public getProcessor<T extends EntitySystem>(): T {
|
||||
for (let i = 0; i < this._processors.length; i++) {
|
||||
let processor = this._processors[i];
|
||||
if (processor instanceof EntitySystem)
|
||||
return processor as T;
|
||||
@@ -67,5 +55,17 @@ module es {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected notifyEntityChanged(entity: Entity) {
|
||||
for (let i = 0; i < this._processors.length; i++) {
|
||||
this._processors[i].onChanged(entity);
|
||||
}
|
||||
}
|
||||
|
||||
protected removeFromProcessors(entity: Entity) {
|
||||
for (let i = 0; i < this._processors.length; i++) {
|
||||
this._processors[i].remove(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
module es {
|
||||
export class Matcher{
|
||||
export class Matcher {
|
||||
protected allSet = new BitSet();
|
||||
protected exclusionSet = new BitSet();
|
||||
protected oneSet = new BitSet();
|
||||
|
||||
public static empty(){
|
||||
public static empty() {
|
||||
return new Matcher();
|
||||
}
|
||||
|
||||
public getAllSet(){
|
||||
public getAllSet() {
|
||||
return this.allSet;
|
||||
}
|
||||
|
||||
public getExclusionSet(){
|
||||
public getExclusionSet() {
|
||||
return this.exclusionSet;
|
||||
}
|
||||
|
||||
public getOneSet(){
|
||||
public getOneSet() {
|
||||
return this.oneSet;
|
||||
}
|
||||
|
||||
public IsIntersted(e: Entity){
|
||||
if (!this.allSet.isEmpty()){
|
||||
for (let i = this.allSet.nextSetBit(0); i >= 0; i = this.allSet.nextSetBit(i + 1)){
|
||||
public IsIntersted(e: Entity) {
|
||||
if (!this.allSet.isEmpty()) {
|
||||
for (let i = this.allSet.nextSetBit(0); i >= 0; i = this.allSet.nextSetBit(i + 1)) {
|
||||
if (!e.componentBits.get(i))
|
||||
return false;
|
||||
}
|
||||
@@ -37,7 +37,7 @@ module es {
|
||||
return true;
|
||||
}
|
||||
|
||||
public all(...types: any[]): Matcher{
|
||||
public all(...types: any[]): Matcher {
|
||||
types.forEach(type => {
|
||||
this.allSet.set(ComponentTypeManager.getIndexFor(type));
|
||||
});
|
||||
@@ -45,7 +45,7 @@ module es {
|
||||
return this;
|
||||
}
|
||||
|
||||
public exclude(...types: any[]){
|
||||
public exclude(...types: any[]) {
|
||||
types.forEach(type => {
|
||||
this.exclusionSet.set(ComponentTypeManager.getIndexFor(type));
|
||||
});
|
||||
@@ -53,7 +53,7 @@ module es {
|
||||
return this;
|
||||
}
|
||||
|
||||
public one(...types: any[]){
|
||||
public one(...types: any[]) {
|
||||
types.forEach(type => {
|
||||
this.oneSet.set(ComponentTypeManager.getIndexFor(type));
|
||||
});
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
class ObjectUtils {
|
||||
/**
|
||||
* 对象深度拷贝
|
||||
* @param p any 源对象
|
||||
* @param c any 目标对象, 不传则返回新对象, 传则合并属性, 相同名字的属性则会覆盖
|
||||
*/
|
||||
/**
|
||||
* 对象深度拷贝
|
||||
* @param p any 源对象
|
||||
* @param c any 目标对象, 不传则返回新对象, 传则合并属性, 相同名字的属性则会覆盖
|
||||
*/
|
||||
public static clone<T>(p: any, c: T = null): T {
|
||||
var c = c || <T>{};
|
||||
for (let i in p) {
|
||||
if (typeof p[i] === 'object') {
|
||||
c[i] = p[i] instanceof Array ? [] : {};
|
||||
this.clone(p[i], c[i]);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
c[i] = p[i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,23 @@
|
||||
class StringUtils {
|
||||
/**
|
||||
* 匹配中文字符
|
||||
* @param str 需要匹配的字符串
|
||||
* @return
|
||||
*/
|
||||
* 特殊符号字符串
|
||||
*/
|
||||
private static specialSigns: string[] = [
|
||||
'&', '&',
|
||||
'<', '<',
|
||||
'>', '>',
|
||||
'"', '"',
|
||||
"'", ''',
|
||||
'®', '®',
|
||||
'©', '©',
|
||||
'™', '™',
|
||||
];
|
||||
|
||||
/**
|
||||
* 匹配中文字符
|
||||
* @param str 需要匹配的字符串
|
||||
* @return
|
||||
*/
|
||||
public static matchChineseWord(str: string): string[] {
|
||||
//中文字符的unicode值[\u4E00-\u9FA5]
|
||||
let patternA: RegExp = /[\u4E00-\u9FA5]+/gim;
|
||||
@@ -12,7 +26,7 @@ class StringUtils {
|
||||
|
||||
/**
|
||||
* 去除字符串左端的空白字符
|
||||
* @param target 目标字符串
|
||||
* @param target 目标字符串
|
||||
* @return
|
||||
*/
|
||||
public static lTrim(target: string): string {
|
||||
@@ -25,7 +39,7 @@ class StringUtils {
|
||||
|
||||
/**
|
||||
* 去除字符串右端的空白字符
|
||||
* @param target 目标字符串
|
||||
* @param target 目标字符串
|
||||
* @return
|
||||
*/
|
||||
public static rTrim(target: string): string {
|
||||
@@ -36,7 +50,6 @@ class StringUtils {
|
||||
return target.slice(0, endIndex + 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 返回一个去除2段空白字符的字符串
|
||||
* @param target
|
||||
@@ -69,7 +82,7 @@ class StringUtils {
|
||||
* @return 返回执行替换后的字符串
|
||||
*/
|
||||
public static replaceMatch(mainStr: string, targetStr: string,
|
||||
replaceStr: string, caseMark: boolean = false): string {
|
||||
replaceStr: string, caseMark: boolean = false): string {
|
||||
let len: number = mainStr.length;
|
||||
let tempStr: string = "";
|
||||
let isMatch: boolean = false;
|
||||
@@ -84,35 +97,18 @@ class StringUtils {
|
||||
if (isMatch) {
|
||||
tempStr += replaceStr;
|
||||
i = i + tempTarget.length - 1;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
tempStr += mainStr.charAt(i);
|
||||
}
|
||||
}
|
||||
return tempStr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 特殊符号字符串
|
||||
*/
|
||||
private static specialSigns: string[] = [
|
||||
'&', '&',
|
||||
'<', '<',
|
||||
'>', '>',
|
||||
'"', '"',
|
||||
"'", ''',
|
||||
'®', '®',
|
||||
'©', '©',
|
||||
'™', '™',
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* 用html实体换掉字符窜中的特殊字符
|
||||
* @param str 需要替换的字符串
|
||||
* @param reversion 是否翻转替换:将转义符号替换为正常的符号
|
||||
* @return 换掉特殊字符后的字符串
|
||||
* @param str 需要替换的字符串
|
||||
* @param reversion 是否翻转替换:将转义符号替换为正常的符号
|
||||
* @return 换掉特殊字符后的字符串
|
||||
*/
|
||||
public static htmlSpecialChars(str: string, reversion: boolean = false): string {
|
||||
let len: number = this.specialSigns.length;
|
||||
@@ -133,27 +129,27 @@ class StringUtils {
|
||||
|
||||
|
||||
/**
|
||||
* 给数字字符前面添 "0"
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* trace( StringFormat.zfill('1') );
|
||||
* // 01
|
||||
*
|
||||
* trace( StringFormat.zfill('16', 5) );
|
||||
* // 00016
|
||||
*
|
||||
* trace( StringFormat.zfill('-3', 3) );
|
||||
* // -03
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @param str 要进行处理的字符串
|
||||
* @param width 处理后字符串的长度,
|
||||
* 如果str.length >= width,将不做任何处理直接返回原始的str。
|
||||
* @return
|
||||
*
|
||||
*/
|
||||
* 给数字字符前面添 "0"
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* trace( StringFormat.zfill('1') );
|
||||
* // 01
|
||||
*
|
||||
* trace( StringFormat.zfill('16', 5) );
|
||||
* // 00016
|
||||
*
|
||||
* trace( StringFormat.zfill('-3', 3) );
|
||||
* // -03
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @param str 要进行处理的字符串
|
||||
* @param width 处理后字符串的长度,
|
||||
* 如果str.length >= width,将不做任何处理直接返回原始的str。
|
||||
* @return
|
||||
*
|
||||
*/
|
||||
public static zfill(str: string, width: number = 2): string {
|
||||
if (!str) {
|
||||
return str;
|
||||
@@ -185,7 +181,7 @@ class StringUtils {
|
||||
|
||||
/**
|
||||
* 翻转字符串
|
||||
* @param str 字符串
|
||||
* @param str 字符串
|
||||
* @return 翻转后的字符串
|
||||
*/
|
||||
public static reverse(str: string): string {
|
||||
@@ -198,14 +194,14 @@ class StringUtils {
|
||||
|
||||
/**
|
||||
* 截断某段字符串
|
||||
* @param str 目标字符串
|
||||
* @param start 需要截断的起始索引
|
||||
* @param len 截断长度
|
||||
* @param order 顺序,true从字符串头部开始计算,false从字符串尾巴开始结算。
|
||||
* @return 截断后的字符串
|
||||
* @param str 目标字符串
|
||||
* @param start 需要截断的起始索引
|
||||
* @param len 截断长度
|
||||
* @param order 顺序,true从字符串头部开始计算,false从字符串尾巴开始结算。
|
||||
* @return 截断后的字符串
|
||||
*/
|
||||
public static cutOff(str: string, start: number,
|
||||
len: number, order: boolean = true): string {
|
||||
len: number, order: boolean = true): string {
|
||||
start = Math.floor(start);
|
||||
len = Math.floor(len);
|
||||
let length: number = str.length;
|
||||
@@ -215,8 +211,7 @@ class StringUtils {
|
||||
let newStr: string;
|
||||
if (order) {
|
||||
newStr = str.substring(0, s) + str.substr(e, length);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
s = length - 1 - start - len;
|
||||
e = s + len;
|
||||
newStr = str.substring(0, s + 1) + str.substr(e + 1, length);
|
||||
|
||||
@@ -6,15 +6,15 @@ module es {
|
||||
public static sharedCanvas: HTMLCanvasElement;
|
||||
public static sharedContext: CanvasRenderingContext2D;
|
||||
|
||||
public static convertImageToCanvas(texture: egret.Texture, rect?: egret.Rectangle): HTMLCanvasElement{
|
||||
if (!this.sharedCanvas){
|
||||
public static convertImageToCanvas(texture: egret.Texture, rect?: egret.Rectangle): HTMLCanvasElement {
|
||||
if (!this.sharedCanvas) {
|
||||
this.sharedCanvas = egret.sys.createCanvas();
|
||||
this.sharedContext = this.sharedCanvas.getContext("2d");
|
||||
}
|
||||
|
||||
let w = texture.$getTextureWidth();
|
||||
let h = texture.$getTextureHeight();
|
||||
if (!rect){
|
||||
if (!rect) {
|
||||
rect = egret.$TempRectangle;
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
@@ -44,8 +44,7 @@ module es {
|
||||
}
|
||||
renderTexture = new egret.RenderTexture();
|
||||
renderTexture.drawToTexture(new egret.Bitmap(texture));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
renderTexture = <egret.RenderTexture>texture;
|
||||
}
|
||||
//从RenderTexture中读取像素数据,填入canvas
|
||||
@@ -71,8 +70,7 @@ module es {
|
||||
}
|
||||
|
||||
return surface;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
let bitmapData = texture;
|
||||
let offsetX: number = Math.round(bitmapData.$offsetX);
|
||||
let offsetY: number = Math.round(bitmapData.$offsetY);
|
||||
@@ -90,8 +88,7 @@ module es {
|
||||
let surface = this.convertImageToCanvas(texture, rect);
|
||||
let result = surface.toDataURL(type, encoderOptions);
|
||||
return result;
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
egret.$error(1033);
|
||||
}
|
||||
return null;
|
||||
@@ -117,7 +114,7 @@ module es {
|
||||
success: function (res) {
|
||||
//todo
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -135,8 +132,7 @@ module es {
|
||||
if (!(<egret.RenderTexture>texture).$renderBuffer) {
|
||||
renderTexture = new egret.RenderTexture();
|
||||
renderTexture.drawToTexture(new egret.Bitmap(texture));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
renderTexture = <egret.RenderTexture>texture;
|
||||
}
|
||||
//从RenderTexture中读取像素数据
|
||||
@@ -147,8 +143,7 @@ module es {
|
||||
let surface = this.convertImageToCanvas(texture);
|
||||
let result = this.sharedContext.getImageData(x, y, width, height).data;
|
||||
return <number[]><any>result;
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
egret.$error(1039);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,22 +9,21 @@ module es {
|
||||
public static timeScale = 1;
|
||||
/** 已传递的帧总数 */
|
||||
public static frameCount = 0;
|
||||
|
||||
private static _lastTime = 0;
|
||||
/** 自场景加载以来的总时间 */
|
||||
public static _timeSinceSceneLoad;
|
||||
private static _lastTime = 0;
|
||||
|
||||
public static update(currentTime: number){
|
||||
public static update(currentTime: number) {
|
||||
let dt = (currentTime - this._lastTime) / 1000;
|
||||
this.deltaTime = dt * this.timeScale;
|
||||
this.unscaledDeltaTime = dt;
|
||||
this._timeSinceSceneLoad += dt;
|
||||
this.frameCount ++;
|
||||
this.frameCount++;
|
||||
|
||||
this._lastTime = currentTime;
|
||||
}
|
||||
|
||||
public static sceneChanged(){
|
||||
public static sceneChanged() {
|
||||
this._timeSinceSceneLoad = 0;
|
||||
}
|
||||
|
||||
@@ -32,7 +31,7 @@ module es {
|
||||
* 允许在间隔检查。只应该使用高于delta的间隔值,否则它将始终返回true。
|
||||
* @param interval
|
||||
*/
|
||||
public static checkEvery(interval: number){
|
||||
public static checkEvery(interval: number) {
|
||||
// 我们减去了delta,因为timeSinceSceneLoad已经包含了这个update ticks delta
|
||||
return (this._timeSinceSceneLoad / interval) > ((this._timeSinceSceneLoad - this.deltaTime) / interval);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
class TimeUtils {
|
||||
/**
|
||||
* 计算月份ID
|
||||
* @param d 指定计算日期
|
||||
* @returns 月ID
|
||||
*/
|
||||
* 计算月份ID
|
||||
* @param d 指定计算日期
|
||||
* @returns 月ID
|
||||
*/
|
||||
public static monthId(d: Date = null): number {
|
||||
d = d ? d : new Date();
|
||||
let y = d.getFullYear();
|
||||
@@ -35,7 +35,8 @@ class TimeUtils {
|
||||
d = d ? d : new Date();
|
||||
let c: Date = new Date();
|
||||
c.setTime(d.getTime());
|
||||
c.setDate(1); c.setMonth(0);//当年第一天
|
||||
c.setDate(1);
|
||||
c.setMonth(0);//当年第一天
|
||||
|
||||
let year: number = c.getFullYear();
|
||||
let firstDay: number = c.getDay();
|
||||
@@ -51,7 +52,8 @@ class TimeUtils {
|
||||
}
|
||||
let num: number = this.diffDay(d, c, false);
|
||||
if (num < 0) {
|
||||
c.setDate(1); c.setMonth(0);//当年第一天
|
||||
c.setDate(1);
|
||||
c.setMonth(0);//当年第一天
|
||||
c.setDate(c.getDate() - 1);
|
||||
return this.weekId(c, false);
|
||||
}
|
||||
@@ -66,7 +68,8 @@ class TimeUtils {
|
||||
}
|
||||
if (first && (!max || endDay < 4)) {
|
||||
c.setFullYear(c.getFullYear() + 1);
|
||||
c.setDate(1); c.setMonth(0);//当年第一天
|
||||
c.setDate(1);
|
||||
c.setMonth(0);//当年第一天
|
||||
return this.weekId(c, false);
|
||||
}
|
||||
}
|
||||
@@ -151,9 +154,9 @@ class TimeUtils {
|
||||
|
||||
/**
|
||||
* 秒数转换为时间形式。
|
||||
* @param time 秒数
|
||||
* @param partition 分隔符
|
||||
* @param showHour 是否显示小时
|
||||
* @param time 秒数
|
||||
* @param partition 分隔符
|
||||
* @param showHour 是否显示小时
|
||||
* @return 返回一个以分隔符分割的时, 分, 秒
|
||||
*
|
||||
* 比如: time = 4351; secondToTime(time)返回字符串01:12:31;
|
||||
|
||||
@@ -309,7 +309,7 @@ Array.prototype.groupBy = function (keySelector) {
|
||||
if (typeof (array.reduce) === "function") {
|
||||
let keys = [];
|
||||
return array.reduce(function (groups, element, index) {
|
||||
let key = JSON.stringify(keySelector.call(arguments[1], element, index, array))
|
||||
let key = JSON.stringify(keySelector.call(arguments[1], element, index, array));
|
||||
let index2 = keys.findIndex(function (x) {
|
||||
return x === key;
|
||||
});
|
||||
|
||||
@@ -64,8 +64,8 @@ module es {
|
||||
"gl_FragColor = vec4(final_colour/(z*z), 1.0);\n" +
|
||||
"}";
|
||||
|
||||
constructor(){
|
||||
super(PostProcessor.default_vert, GaussianBlurEffect.blur_frag,{
|
||||
constructor() {
|
||||
super(PostProcessor.default_vert, GaussianBlurEffect.blur_frag, {
|
||||
screenWidth: Core.graphicsDevice.viewport.width,
|
||||
screenHeight: Core.graphicsDevice.viewport.height
|
||||
});
|
||||
|
||||
@@ -29,7 +29,7 @@ module es {
|
||||
"gl_FragColor = c;\n" +
|
||||
"}";
|
||||
|
||||
constructor(){
|
||||
constructor() {
|
||||
super(PolygonLightEffect.vertSrc, PolygonLightEffect.fragmentSrc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
module es {
|
||||
export class GraphicsCapabilities extends egret.Capabilities {
|
||||
|
||||
public initialize(device: GraphicsDevice){
|
||||
public initialize(device: GraphicsDevice) {
|
||||
this.platformInitialize(device);
|
||||
}
|
||||
|
||||
private platformInitialize(device: GraphicsDevice){
|
||||
private platformInitialize(device: GraphicsDevice) {
|
||||
if (GraphicsCapabilities.runtimeType != egret.RuntimeType.WXGAME)
|
||||
return;
|
||||
let capabilities = this;
|
||||
@@ -13,14 +13,14 @@ module es {
|
||||
|
||||
let systemInfo = wx.getSystemInfoSync();
|
||||
let systemStr = systemInfo.system.toLowerCase();
|
||||
if (systemStr.indexOf("ios") > -1){
|
||||
if (systemStr.indexOf("ios") > -1) {
|
||||
capabilities["os"] = "iOS";
|
||||
} else if(systemStr.indexOf("android") > -1){
|
||||
} else if (systemStr.indexOf("android") > -1) {
|
||||
capabilities["os"] = "Android";
|
||||
}
|
||||
|
||||
let language = systemInfo.language;
|
||||
if (language.indexOf('zh') > -1){
|
||||
if (language.indexOf('zh') > -1) {
|
||||
language = "zh-CN";
|
||||
} else {
|
||||
language = "en-US";
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
module es {
|
||||
export class GraphicsDevice {
|
||||
private _viewport: Viewport;
|
||||
public get viewport(): Viewport{
|
||||
return this._viewport;
|
||||
}
|
||||
|
||||
public graphicsCapabilities: GraphicsCapabilities;
|
||||
|
||||
constructor(){
|
||||
constructor() {
|
||||
this.setup();
|
||||
this.graphicsCapabilities = new GraphicsCapabilities();
|
||||
this.graphicsCapabilities.initialize(this);
|
||||
}
|
||||
|
||||
private setup(){
|
||||
private _viewport: Viewport;
|
||||
|
||||
public get viewport(): Viewport {
|
||||
return this._viewport;
|
||||
}
|
||||
|
||||
private setup() {
|
||||
this._viewport = new Viewport(0, 0, Core._instance.stage.stageWidth, Core._instance.stage.stageHeight);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
module es {
|
||||
export class PostProcessor {
|
||||
public enabled: boolean;
|
||||
public effect: egret.Filter;
|
||||
public scene: Scene;
|
||||
public shape: egret.Shape;
|
||||
|
||||
public static default_vert = "attribute vec2 aVertexPosition;\n" +
|
||||
"attribute vec2 aTextureCoord;\n" +
|
||||
"attribute vec2 aColor;\n" +
|
||||
@@ -22,13 +17,17 @@ module es {
|
||||
"vTextureCoord = aTextureCoord;\n" +
|
||||
"vColor = vec4(aColor.x, aColor.x, aColor.x, aColor.x);\n" +
|
||||
"}";
|
||||
public enabled: boolean;
|
||||
public effect: egret.Filter;
|
||||
public scene: Scene;
|
||||
public shape: egret.Shape;
|
||||
|
||||
constructor(effect: egret.Filter = null){
|
||||
constructor(effect: egret.Filter = null) {
|
||||
this.enabled = true;
|
||||
this.effect = effect;
|
||||
}
|
||||
|
||||
public onAddedToScene(scene: Scene){
|
||||
public onAddedToScene(scene: Scene) {
|
||||
this.scene = scene;
|
||||
this.shape = new egret.Shape();
|
||||
this.shape.graphics.beginFill(0xFFFFFF, 1);
|
||||
@@ -37,24 +36,25 @@ module es {
|
||||
scene.addChild(this.shape);
|
||||
}
|
||||
|
||||
public process(){
|
||||
public process() {
|
||||
this.drawFullscreenQuad();
|
||||
}
|
||||
|
||||
public onSceneBackBufferSizeChanged(newWidth: number, newHeight: number){}
|
||||
|
||||
protected drawFullscreenQuad(){
|
||||
this.scene.filters = [this.effect];
|
||||
// this.shape.filters = [this.effect];
|
||||
public onSceneBackBufferSizeChanged(newWidth: number, newHeight: number) {
|
||||
}
|
||||
|
||||
public unload(){
|
||||
if (this.effect){
|
||||
public unload() {
|
||||
if (this.effect) {
|
||||
this.effect = null;
|
||||
}
|
||||
|
||||
this.scene.removeChild(this.shape);
|
||||
this.scene = null;
|
||||
}
|
||||
|
||||
protected drawFullscreenQuad() {
|
||||
this.scene.filters = [this.effect];
|
||||
// this.shape.filters = [this.effect];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module es {
|
||||
export class GaussianBlurPostProcessor extends PostProcessor {
|
||||
public onAddedToScene(scene: Scene){
|
||||
public onAddedToScene(scene: Scene) {
|
||||
super.onAddedToScene(scene);
|
||||
this.effect = new GaussianBlurEffect();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
///<reference path="./Renderer.ts" />
|
||||
module es {
|
||||
export class DefaultRenderer extends Renderer {
|
||||
constructor(){
|
||||
constructor() {
|
||||
super(0, null);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ module es {
|
||||
let cam = this.camera ? this.camera : scene.camera;
|
||||
this.beginRender(cam);
|
||||
|
||||
for (let i = 0; i < scene.renderableComponents.count; i++){
|
||||
for (let i = 0; i < scene.renderableComponents.count; i++) {
|
||||
let renderable = scene.renderableComponents.buffer[i];
|
||||
if (renderable.enabled && renderable.isVisibleFromCamera(cam))
|
||||
this.renderAfterStateCheck(renderable, cam);
|
||||
|
||||
@@ -40,7 +40,7 @@ module es {
|
||||
* 用于排序IRenderables的比较器
|
||||
*/
|
||||
export class RenderableComparer {
|
||||
public compare(self: IRenderable, other: IRenderable){
|
||||
public compare(self: IRenderable, other: IRenderable) {
|
||||
return other.renderLayer - self.renderLayer;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,10 @@
|
||||
module es {
|
||||
export class PolyLight extends RenderableComponent {
|
||||
public power: number;
|
||||
protected _radius: number;
|
||||
private _lightEffect;
|
||||
private _indices: number[] = [];
|
||||
|
||||
public get radius(){
|
||||
return this._radius;
|
||||
}
|
||||
public set radius(value: number){
|
||||
this.setRadius(value);
|
||||
}
|
||||
|
||||
constructor(radius: number, color: number, power: number){
|
||||
constructor(radius: number, color: number, power: number) {
|
||||
super();
|
||||
|
||||
this.radius = radius;
|
||||
@@ -21,18 +13,18 @@ module es {
|
||||
this.computeTriangleIndices();
|
||||
}
|
||||
|
||||
private computeTriangleIndices(totalTris: number = 20){
|
||||
this._indices.length = 0;
|
||||
protected _radius: number;
|
||||
|
||||
for (let i = 0; i < totalTris; i += 2){
|
||||
this._indices.push(0);
|
||||
this._indices.push(i + 2);
|
||||
this._indices.push(i + 1);
|
||||
}
|
||||
public get radius() {
|
||||
return this._radius;
|
||||
}
|
||||
|
||||
public setRadius(radius: number){
|
||||
if (radius != this._radius){
|
||||
public set radius(value: number) {
|
||||
this.setRadius(value);
|
||||
}
|
||||
|
||||
public setRadius(radius: number) {
|
||||
if (radius != this._radius) {
|
||||
this._radius = radius;
|
||||
this._areBoundsDirty = true;
|
||||
}
|
||||
@@ -41,8 +33,18 @@ module es {
|
||||
public render(camera: Camera) {
|
||||
}
|
||||
|
||||
public reset(){
|
||||
public reset() {
|
||||
|
||||
}
|
||||
|
||||
private computeTriangleIndices(totalTris: number = 20) {
|
||||
this._indices.length = 0;
|
||||
|
||||
for (let i = 0; i < totalTris; i += 2) {
|
||||
this._indices.push(0);
|
||||
this._indices.push(i + 2);
|
||||
this._indices.push(i + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ module es {
|
||||
*/
|
||||
public readonly renderOrder: number = 0;
|
||||
|
||||
protected constructor(renderOrder: number, camera: Camera = null){
|
||||
protected constructor(renderOrder: number, camera: Camera = null) {
|
||||
this.camera = camera;
|
||||
this.renderOrder = renderOrder;
|
||||
}
|
||||
@@ -23,41 +23,44 @@ module es {
|
||||
* 当渲染器被添加到场景时调用
|
||||
* @param scene
|
||||
*/
|
||||
public onAddedToScene(scene: Scene){}
|
||||
public onAddedToScene(scene: Scene) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 当场景结束或渲染器从场景中移除时调用。使用这个进行清理。
|
||||
*/
|
||||
public unload(){ }
|
||||
|
||||
/**
|
||||
*
|
||||
* @param cam
|
||||
*/
|
||||
protected beginRender(cam: Camera){ }
|
||||
public unload() {
|
||||
}
|
||||
|
||||
public abstract render(scene: Scene);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param renderable
|
||||
* @param cam
|
||||
*/
|
||||
protected renderAfterStateCheck(renderable: IRenderable, cam: Camera){
|
||||
renderable.render(cam);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当默认场景渲染目标被调整大小和当场景已经开始添加渲染器时调用
|
||||
* @param newWidth
|
||||
* @param newHeight
|
||||
*/
|
||||
public onSceneBackBufferSizeChanged(newWidth: number, newHeight: number){
|
||||
public onSceneBackBufferSizeChanged(newWidth: number, newHeight: number) {
|
||||
|
||||
}
|
||||
|
||||
public compareTo(other: Renderer): number{
|
||||
public compareTo(other: Renderer): number {
|
||||
return this.renderOrder - other.renderOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param cam
|
||||
*/
|
||||
protected beginRender(cam: Camera) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param renderable
|
||||
* @param cam
|
||||
*/
|
||||
protected renderAfterStateCheck(renderable: IRenderable, cam: Camera) {
|
||||
renderable.render(cam);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,17 +18,17 @@ module es {
|
||||
this._mask.graphics.drawRect(0, 0, Core.graphicsDevice.viewport.width, Core.graphicsDevice.viewport.height);
|
||||
this._mask.graphics.endFill();
|
||||
|
||||
egret.Tween.get(this).to({ _alpha: 1}, this.fadeOutDuration * 1000, this.fadeEaseType)
|
||||
egret.Tween.get(this).to({_alpha: 1}, this.fadeOutDuration * 1000, this.fadeEaseType)
|
||||
.call(async () => {
|
||||
await this.loadNextScene();
|
||||
}).wait(this.delayBeforeFadeInDuration).call(() => {
|
||||
egret.Tween.get(this).to({ _alpha: 0 }, this.fadeOutDuration * 1000, this.fadeEaseType).call(() => {
|
||||
egret.Tween.get(this).to({_alpha: 0}, this.fadeOutDuration * 1000, this.fadeEaseType).call(() => {
|
||||
this.transitionComplete();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public render(){
|
||||
public render() {
|
||||
this._mask.graphics.clear();
|
||||
this._mask.graphics.beginFill(this.fadeToColor, this._alpha);
|
||||
this._mask.graphics.drawRect(0, 0, Core.graphicsDevice.viewport.width, Core.graphicsDevice.viewport.height);
|
||||
|
||||
@@ -3,7 +3,6 @@ module es {
|
||||
* SceneTransition用于从一个场景过渡到另一个场景或在一个有效果的场景中过渡
|
||||
*/
|
||||
export abstract class SceneTransition {
|
||||
private _hasPreviousSceneRender: boolean;
|
||||
/** 是否加载新场景的标志 */
|
||||
public loadsNewScene: boolean;
|
||||
/**
|
||||
@@ -11,15 +10,22 @@ module es {
|
||||
* 对于场景过渡,isNewSceneLoaded应该在中点设置为true,这就标识一个新的场景被加载了。
|
||||
*/
|
||||
public isNewSceneLoaded: boolean;
|
||||
/** 返回新加载场景的函数 */
|
||||
protected sceneLoadAction: Function;
|
||||
/** 在loadNextScene执行时调用。这在进行场景间过渡时很有用,这样你就知道什么时候可以更多地使用相机或者重置任何实体 */
|
||||
public onScreenObscured: Function;
|
||||
/** 当转换完成执行时调用,以便可以调用其他工作,比如启动另一个转换。 */
|
||||
public onTransitionCompleted: Function;
|
||||
/** 返回新加载场景的函数 */
|
||||
protected sceneLoadAction: Function;
|
||||
|
||||
public get hasPreviousSceneRender(){
|
||||
if (!this._hasPreviousSceneRender){
|
||||
constructor(sceneLoadAction: Function) {
|
||||
this.sceneLoadAction = sceneLoadAction;
|
||||
this.loadsNewScene = sceneLoadAction != null;
|
||||
}
|
||||
|
||||
private _hasPreviousSceneRender: boolean;
|
||||
|
||||
public get hasPreviousSceneRender() {
|
||||
if (!this._hasPreviousSceneRender) {
|
||||
this._hasPreviousSceneRender = true;
|
||||
return false;
|
||||
}
|
||||
@@ -27,13 +33,9 @@ module es {
|
||||
return true;
|
||||
}
|
||||
|
||||
constructor(sceneLoadAction: Function) {
|
||||
this.sceneLoadAction = sceneLoadAction;
|
||||
this.loadsNewScene = sceneLoadAction != null;
|
||||
public preRender() {
|
||||
}
|
||||
|
||||
public preRender() { }
|
||||
|
||||
public render() {
|
||||
|
||||
}
|
||||
@@ -43,6 +45,17 @@ module es {
|
||||
this.transitionComplete();
|
||||
}
|
||||
|
||||
public tickEffectProgressProperty(filter: egret.CustomFilter, duration: number, easeType: Function, reverseDirection = false): Promise<boolean> {
|
||||
return new Promise((resolve) => {
|
||||
let start = reverseDirection ? 1 : 0;
|
||||
let end = reverseDirection ? 0 : 1;
|
||||
|
||||
egret.Tween.get(filter.uniforms).set({_progress: start}).to({_progress: end}, duration * 1000, easeType).call(() => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
protected transitionComplete() {
|
||||
Core._instance._sceneTransition = null;
|
||||
|
||||
@@ -62,16 +75,5 @@ module es {
|
||||
Core.scene = await this.sceneLoadAction();
|
||||
this.isNewSceneLoaded = true;
|
||||
}
|
||||
|
||||
public tickEffectProgressProperty(filter: egret.CustomFilter, duration: number, easeType: Function, reverseDirection = false): Promise<boolean>{
|
||||
return new Promise((resolve)=>{
|
||||
let start = reverseDirection ? 1 : 0;
|
||||
let end = reverseDirection ? 0 : 1;
|
||||
|
||||
egret.Tween.get(filter.uniforms).set({_progress: start}).to({_progress: end}, duration * 1000, easeType).call(()=>{
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,14 @@
|
||||
module es {
|
||||
export class WindTransition extends SceneTransition {
|
||||
public duration = 1;
|
||||
public easeType = egret.Ease.quadOut;
|
||||
private _mask: egret.Shape;
|
||||
private _windEffect: egret.CustomFilter;
|
||||
|
||||
public duration = 1;
|
||||
public set windSegments(value: number) {
|
||||
this._windEffect.uniforms._windSegments = value;
|
||||
}
|
||||
public set size(value: number) {
|
||||
this._windEffect.uniforms._size = value;
|
||||
}
|
||||
public easeType = egret.Ease.quadOut;
|
||||
constructor(sceneLoadAction: Function) {
|
||||
super(sceneLoadAction);
|
||||
|
||||
let vertexSrc = "attribute vec2 aVertexPosition;\n" +
|
||||
let vertexSrc = "attribute vec2 aVertexPosition;\n" +
|
||||
"attribute vec2 aTextureCoord;\n" +
|
||||
|
||||
"uniform vec2 projectionVector;\n" +
|
||||
@@ -56,6 +50,14 @@ module es {
|
||||
this._mask.filters = [this._windEffect];
|
||||
}
|
||||
|
||||
public set windSegments(value: number) {
|
||||
this._windEffect.uniforms._windSegments = value;
|
||||
}
|
||||
|
||||
public set size(value: number) {
|
||||
this._windEffect.uniforms._size = value;
|
||||
}
|
||||
|
||||
public async onBeginTransition() {
|
||||
this.loadNextScene();
|
||||
await this.tickEffectProgressProperty(this._windEffect, this.duration, this.easeType);
|
||||
|
||||
@@ -2,42 +2,10 @@ module es {
|
||||
export class Viewport {
|
||||
private _x: number;
|
||||
private _y: number;
|
||||
private _width: number;
|
||||
private _height: number;
|
||||
private _minDepth: number;
|
||||
private _maxDepth: number;
|
||||
|
||||
public get height(){
|
||||
return this._height;
|
||||
}
|
||||
public set height(value: number){
|
||||
this._height = value;
|
||||
}
|
||||
|
||||
public get width(){
|
||||
return this._width;
|
||||
}
|
||||
public set width(value: number){
|
||||
this._width = value;
|
||||
}
|
||||
|
||||
public get aspectRatio(){
|
||||
if ((this._height != 0) && (this._width != 0))
|
||||
return (this._width / this._height);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public get bounds(){
|
||||
return new Rectangle(this._x, this._y, this._width, this._height);
|
||||
}
|
||||
public set bounds(value: Rectangle){
|
||||
this._x = value.x;
|
||||
this._y = value.y;
|
||||
this._width = value.width;
|
||||
this._height = value.height;
|
||||
}
|
||||
|
||||
constructor(x: number, y: number, width: number, height: number){
|
||||
constructor(x: number, y: number, width: number, height: number) {
|
||||
this._x = x;
|
||||
this._y = y;
|
||||
this._width = width;
|
||||
@@ -46,5 +14,42 @@ module es {
|
||||
this._maxDepth = 1;
|
||||
}
|
||||
|
||||
private _width: number;
|
||||
|
||||
public get width() {
|
||||
return this._width;
|
||||
}
|
||||
|
||||
public set width(value: number) {
|
||||
this._width = value;
|
||||
}
|
||||
|
||||
private _height: number;
|
||||
|
||||
public get height() {
|
||||
return this._height;
|
||||
}
|
||||
|
||||
public set height(value: number) {
|
||||
this._height = value;
|
||||
}
|
||||
|
||||
public get aspectRatio() {
|
||||
if ((this._height != 0) && (this._width != 0))
|
||||
return (this._width / this._height);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public get bounds() {
|
||||
return new Rectangle(this._x, this._y, this._width, this._height);
|
||||
}
|
||||
|
||||
public set bounds(value: Rectangle) {
|
||||
this._x = value.x;
|
||||
this._y = value.y;
|
||||
this._width = value.width;
|
||||
this._height = value.height;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ module es {
|
||||
* @param self
|
||||
* @param flag
|
||||
*/
|
||||
public static isFlagSet(self: number, flag: number): boolean{
|
||||
public static isFlagSet(self: number, flag: number): boolean {
|
||||
return (self & flag) != 0;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ module es {
|
||||
* @param self
|
||||
* @param flag
|
||||
*/
|
||||
public static isUnshiftedFlagSet(self: number, flag: number): boolean{
|
||||
public static isUnshiftedFlagSet(self: number, flag: number): boolean {
|
||||
flag = 1 << flag;
|
||||
return (self & flag) != 0;
|
||||
}
|
||||
@@ -30,7 +30,7 @@ module es {
|
||||
* @param self
|
||||
* @param flag
|
||||
*/
|
||||
public static setFlagExclusive(self: number, flag: number){
|
||||
public static setFlagExclusive(self: number, flag: number) {
|
||||
return 1 << flag;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ module es {
|
||||
* @param self
|
||||
* @param flag
|
||||
*/
|
||||
public static setFlag(self: number, flag: number){
|
||||
public static setFlag(self: number, flag: number) {
|
||||
return (self | 1 << flag);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ module es {
|
||||
* @param self
|
||||
* @param flag
|
||||
*/
|
||||
public static unsetFlag(self: number, flag: number){
|
||||
public static unsetFlag(self: number, flag: number) {
|
||||
flag = 1 << flag;
|
||||
return (self & (~flag));
|
||||
}
|
||||
@@ -57,7 +57,7 @@ module es {
|
||||
* 反转数值集合位
|
||||
* @param self
|
||||
*/
|
||||
public static invertFlags(self: number){
|
||||
public static invertFlags(self: number) {
|
||||
return ~self;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ module es {
|
||||
* 将弧度转换成角度。
|
||||
* @param radians 用弧度表示的角
|
||||
*/
|
||||
public static toDegrees(radians: number){
|
||||
public static toDegrees(radians: number) {
|
||||
return radians * 57.295779513082320876798154814105;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ module es {
|
||||
* 将角度转换为弧度
|
||||
* @param degrees
|
||||
*/
|
||||
public static toRadians(degrees: number){
|
||||
public static toRadians(degrees: number) {
|
||||
return degrees * 0.017453292519943295769236907684886;
|
||||
}
|
||||
|
||||
@@ -28,15 +28,15 @@ module es {
|
||||
* @param rightMin
|
||||
* @param rightMax
|
||||
*/
|
||||
public static map(value: number, leftMin: number, leftMax: number, rightMin: number, rightMax: number){
|
||||
public static map(value: number, leftMin: number, leftMax: number, rightMin: number, rightMax: number) {
|
||||
return rightMin + (value - leftMin) * (rightMax - rightMin) / (leftMax - leftMin);
|
||||
}
|
||||
|
||||
public static lerp(value1: number, value2: number, amount: number){
|
||||
public static lerp(value1: number, value2: number, amount: number) {
|
||||
return value1 + (value2 - value1) * amount;
|
||||
}
|
||||
|
||||
public static clamp(value: number, min: number, max: number){
|
||||
public static clamp(value: number, min: number, max: number) {
|
||||
if (value < min)
|
||||
return min;
|
||||
|
||||
@@ -46,7 +46,7 @@ module es {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static pointOnCirlce(circleCenter: Vector2, radius: number, angleInDegrees: number){
|
||||
public static pointOnCirlce(circleCenter: Vector2, radius: number, angleInDegrees: number) {
|
||||
let radians = MathHelper.toRadians(angleInDegrees);
|
||||
return new Vector2(Math.cos(radians) * radians + circleCenter.x, Math.sin(radians) * radians + circleCenter.y);
|
||||
}
|
||||
@@ -55,7 +55,7 @@ module es {
|
||||
* 如果值为偶数,返回true
|
||||
* @param value
|
||||
*/
|
||||
public static isEven(value: number){
|
||||
public static isEven(value: number) {
|
||||
return value % 2 == 0;
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ module es {
|
||||
* 数值限定在0-1之间
|
||||
* @param value
|
||||
*/
|
||||
public static clamp01(value: number){
|
||||
public static clamp01(value: number) {
|
||||
if (value < 0)
|
||||
return 0;
|
||||
|
||||
@@ -73,7 +73,7 @@ module es {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static angleBetweenVectors(from: Vector2, to: Vector2){
|
||||
public static angleBetweenVectors(from: Vector2, to: Vector2) {
|
||||
return Math.atan2(to.y - from.y, to.x - from.x);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,57 +1,69 @@
|
||||
module es {
|
||||
export var matrixPool = [];
|
||||
|
||||
/**
|
||||
* 表示右手3 * 3的浮点矩阵,可以存储平移、缩放和旋转信息。
|
||||
*/
|
||||
export class Matrix2D extends egret.Matrix{
|
||||
public get m11(): number{
|
||||
export class Matrix2D extends egret.Matrix {
|
||||
public get m11(): number {
|
||||
return this.a;
|
||||
}
|
||||
public set m11(value: number){
|
||||
|
||||
public set m11(value: number) {
|
||||
this.a = value;
|
||||
}
|
||||
public get m12(): number{
|
||||
|
||||
public get m12(): number {
|
||||
return this.b;
|
||||
}
|
||||
public set m12(value: number){
|
||||
|
||||
public set m12(value: number) {
|
||||
this.b = value;
|
||||
}
|
||||
public get m21(): number{
|
||||
|
||||
public get m21(): number {
|
||||
return this.c;
|
||||
}
|
||||
public set m21(value: number){
|
||||
|
||||
public set m21(value: number) {
|
||||
this.c = value;
|
||||
}
|
||||
public get m22(): number{
|
||||
|
||||
public get m22(): number {
|
||||
return this.d;
|
||||
}
|
||||
public set m22(value: number){
|
||||
|
||||
public set m22(value: number) {
|
||||
this.d = value;
|
||||
}
|
||||
|
||||
public get m31(): number {
|
||||
return this.tx;
|
||||
}
|
||||
public set m31(value: number){
|
||||
|
||||
public set m31(value: number) {
|
||||
this.tx = value;
|
||||
}
|
||||
public get m32(): number{
|
||||
|
||||
public get m32(): number {
|
||||
return this.ty;
|
||||
}
|
||||
public set m32(value: number){
|
||||
|
||||
public set m32(value: number) {
|
||||
this.ty = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从对象池中取出或创建一个新的Matrix对象。
|
||||
*/
|
||||
public static create(): Matrix2D{
|
||||
public static create(): Matrix2D {
|
||||
let matrix = matrixPool.pop();
|
||||
if (!matrix)
|
||||
matrix = new Matrix2D();
|
||||
return matrix;
|
||||
}
|
||||
|
||||
public identity(): Matrix2D{
|
||||
public identity(): Matrix2D {
|
||||
this.a = this.d = 1;
|
||||
this.b = this.c = this.tx = this.ty = 0;
|
||||
return this;
|
||||
@@ -64,12 +76,12 @@ module es {
|
||||
}
|
||||
|
||||
public scale(sx: number, sy: number): Matrix2D {
|
||||
if (sx !== 1){
|
||||
if (sx !== 1) {
|
||||
this.a *= sx;
|
||||
this.c *= sx;
|
||||
this.tx *= sx;
|
||||
}
|
||||
if (sy !== 1){
|
||||
if (sy !== 1) {
|
||||
this.b *= sy;
|
||||
this.d *= sy;
|
||||
this.ty *= sy;
|
||||
@@ -108,7 +120,7 @@ module es {
|
||||
* 创建一个新的matrix, 它包含两个矩阵的和。
|
||||
* @param matrix
|
||||
*/
|
||||
public add(matrix: Matrix2D): Matrix2D{
|
||||
public add(matrix: Matrix2D): Matrix2D {
|
||||
this.m11 += matrix.m11;
|
||||
this.m12 += matrix.m12;
|
||||
|
||||
@@ -134,7 +146,7 @@ module es {
|
||||
return this;
|
||||
}
|
||||
|
||||
public divide(matrix: Matrix2D): Matrix2D{
|
||||
public divide(matrix: Matrix2D): Matrix2D {
|
||||
this.m11 /= matrix.m11;
|
||||
this.m12 /= matrix.m12;
|
||||
|
||||
@@ -147,15 +159,15 @@ module es {
|
||||
return this;
|
||||
}
|
||||
|
||||
public multiply(matrix: Matrix2D): Matrix2D{
|
||||
let m11 = ( this.m11 * matrix.m11 ) + ( this.m12 * matrix.m21 );
|
||||
let m12 = ( this.m11 * matrix.m12 ) + ( this.m12 * matrix.m22 );
|
||||
public multiply(matrix: Matrix2D): Matrix2D {
|
||||
let m11 = (this.m11 * matrix.m11) + (this.m12 * matrix.m21);
|
||||
let m12 = (this.m11 * matrix.m12) + (this.m12 * matrix.m22);
|
||||
|
||||
let m21 = ( this.m21 * matrix.m11 ) + ( this.m22 * matrix.m21 );
|
||||
let m22 = ( this.m21 * matrix.m12 ) + ( this.m22 * matrix.m22 );
|
||||
let m21 = (this.m21 * matrix.m11) + (this.m22 * matrix.m21);
|
||||
let m22 = (this.m21 * matrix.m12) + (this.m22 * matrix.m22);
|
||||
|
||||
let m31 = ( this.m31 * matrix.m11 ) + ( this.m32 * matrix.m21 ) + matrix.m31;
|
||||
let m32 = ( this.m31 * matrix.m12 ) + ( this.m32 * matrix.m22 ) + matrix.m32;
|
||||
let m31 = (this.m31 * matrix.m11) + (this.m32 * matrix.m21) + matrix.m31;
|
||||
let m32 = (this.m31 * matrix.m12) + (this.m32 * matrix.m22) + matrix.m32;
|
||||
|
||||
this.m11 = m11;
|
||||
this.m12 = m12;
|
||||
@@ -169,7 +181,7 @@ module es {
|
||||
return this;
|
||||
}
|
||||
|
||||
public determinant(){
|
||||
public determinant() {
|
||||
return this.m11 * this.m22 - this.m12 * this.m21;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ module es {
|
||||
export class Rectangle extends egret.Rectangle {
|
||||
public _tempMat: Matrix2D;
|
||||
public _transformMat: Matrix2D;
|
||||
|
||||
/**
|
||||
* 获取矩形的最大点,即右下角
|
||||
*/
|
||||
@@ -18,6 +19,7 @@ module es {
|
||||
public get location() {
|
||||
return new Vector2(this.x, this.y);
|
||||
}
|
||||
|
||||
/** 左上角的坐标 */
|
||||
public set location(value: Vector2) {
|
||||
this.x = value.x;
|
||||
@@ -33,6 +35,41 @@ module es {
|
||||
this.height = value.y;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个矩形的最小/最大点(左上角,右下角的点)
|
||||
* @param minX
|
||||
* @param minY
|
||||
* @param maxX
|
||||
* @param maxY
|
||||
*/
|
||||
public static fromMinMax(minX: number, minY: number, maxX: number, maxY: number) {
|
||||
return new Rectangle(minX, minY, maxX - minX, maxY - minY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 给定多边形的点,计算边界
|
||||
* @param points
|
||||
*/
|
||||
public static rectEncompassingPoints(points: Vector2[]) {
|
||||
// 我们需要求出x/y的最小值/最大值
|
||||
let minX = Number.POSITIVE_INFINITY;
|
||||
let minY = Number.POSITIVE_INFINITY;
|
||||
let maxX = Number.NEGATIVE_INFINITY;
|
||||
let maxY = Number.NEGATIVE_INFINITY;
|
||||
|
||||
for (let i = 0; i < points.length; i++) {
|
||||
let pt = points[i];
|
||||
|
||||
if (pt.x < minX) minX = pt.x;
|
||||
if (pt.x > maxX) maxX = pt.x;
|
||||
|
||||
if (pt.y < minY) minY = pt.y;
|
||||
if (pt.y > maxY) maxY = pt.y;
|
||||
}
|
||||
|
||||
return this.fromMinMax(minX, minY, maxX, maxY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否与另一个矩形相交
|
||||
* @param value
|
||||
@@ -58,17 +95,6 @@ module es {
|
||||
return new Vector2(this.width * 0.5, this.height * 0.5);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个矩形的最小/最大点(左上角,右下角的点)
|
||||
* @param minX
|
||||
* @param minY
|
||||
* @param maxX
|
||||
* @param maxY
|
||||
*/
|
||||
public static fromMinMax(minX: number, minY: number, maxX: number, maxY: number) {
|
||||
return new Rectangle(minX, minY, maxX - minX, maxY - minY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取矩形边界上与给定点最近的点
|
||||
* @param point
|
||||
@@ -142,8 +168,8 @@ module es {
|
||||
return boundsPoint;
|
||||
}
|
||||
|
||||
public calculateBounds(parentPosition: Vector2, position: Vector2, origin: Vector2, scale: Vector2, rotation: number, width: number, height: number){
|
||||
if (rotation == 0){
|
||||
public calculateBounds(parentPosition: Vector2, position: Vector2, origin: Vector2, scale: Vector2, rotation: number, width: number, height: number) {
|
||||
if (rotation == 0) {
|
||||
this.x = parentPosition.x + position.x - origin.x * scale.x;
|
||||
this.y = parentPosition.y + position.y - origin.y * scale.y;
|
||||
this.width = width * scale.x;
|
||||
@@ -183,29 +209,5 @@ module es {
|
||||
this.height = maxY - minY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 给定多边形的点,计算边界
|
||||
* @param points
|
||||
*/
|
||||
public static rectEncompassingPoints(points: Vector2[]) {
|
||||
// 我们需要求出x/y的最小值/最大值
|
||||
let minX = Number.POSITIVE_INFINITY;
|
||||
let minY = Number.POSITIVE_INFINITY;
|
||||
let maxX = Number.NEGATIVE_INFINITY;
|
||||
let maxY = Number.NEGATIVE_INFINITY;
|
||||
|
||||
for (let i = 0; i < points.length; i++) {
|
||||
let pt = points[i];
|
||||
|
||||
if (pt.x < minX) minX = pt.x;
|
||||
if (pt.x > maxX) maxX = pt.x;
|
||||
|
||||
if (pt.y < minY) minY = pt.y;
|
||||
if (pt.y > maxY) maxY = pt.y;
|
||||
}
|
||||
|
||||
return this.fromMinMax(minX, minY, maxX, maxY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,77 +1,37 @@
|
||||
module es {
|
||||
/** 2d 向量 */
|
||||
export class Vector2 {
|
||||
public x: number = 0;
|
||||
public y: number = 0;
|
||||
|
||||
private static readonly unitYVector = new Vector2(0, 1);
|
||||
private static readonly unitXVector = new Vector2(1, 0);
|
||||
private static readonly unitVector2 = new Vector2(1, 1);
|
||||
private static readonly zeroVector2 = new Vector2(0, 0);
|
||||
public static get zero(){
|
||||
return Vector2.zeroVector2;
|
||||
}
|
||||
|
||||
public static get one(){
|
||||
return Vector2.unitVector2;
|
||||
}
|
||||
|
||||
public static get unitX(){
|
||||
return Vector2.unitXVector;
|
||||
}
|
||||
|
||||
public static get unitY(){
|
||||
return Vector2.unitYVector;
|
||||
}
|
||||
public x: number = 0;
|
||||
public y: number = 0;
|
||||
|
||||
/**
|
||||
* 从两个值构造一个带有X和Y的二维向量。
|
||||
* @param x 二维空间中的x坐标
|
||||
* @param y 二维空间的y坐标
|
||||
*/
|
||||
constructor(x? : number, y?: number){
|
||||
constructor(x?: number, y?: number) {
|
||||
this.x = x ? x : 0;
|
||||
this.y = y ? y : this.x;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
public add(value: Vector2): Vector2{
|
||||
this.x += value.x;
|
||||
this.y += value.y;
|
||||
return this;
|
||||
public static get zero() {
|
||||
return Vector2.zeroVector2;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
public divide(value: Vector2): Vector2{
|
||||
this.x /= value.x;
|
||||
this.y /= value.y;
|
||||
return this;
|
||||
public static get one() {
|
||||
return Vector2.unitVector2;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
public multiply(value: Vector2): Vector2{
|
||||
this.x *= value.x;
|
||||
this.y *= value.y;
|
||||
return this;
|
||||
public static get unitX() {
|
||||
return Vector2.unitXVector;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
public subtract(value: Vector2){
|
||||
this.x -= value.x;
|
||||
this.y -= value.y;
|
||||
return this;
|
||||
public static get unitY() {
|
||||
return Vector2.unitYVector;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,7 +39,7 @@ module es {
|
||||
* @param value1
|
||||
* @param value2
|
||||
*/
|
||||
public static add(value1: Vector2, value2: Vector2){
|
||||
public static add(value1: Vector2, value2: Vector2) {
|
||||
let result: Vector2 = new Vector2(0, 0);
|
||||
result.x = value1.x + value2.x;
|
||||
result.y = value1.y + value2.y;
|
||||
@@ -91,7 +51,7 @@ module es {
|
||||
* @param value1
|
||||
* @param value2
|
||||
*/
|
||||
public static divide(value1: Vector2, value2: Vector2){
|
||||
public static divide(value1: Vector2, value2: Vector2) {
|
||||
let result: Vector2 = new Vector2(0, 0);
|
||||
result.x = value1.x / value2.x;
|
||||
result.y = value1.y / value2.y;
|
||||
@@ -103,7 +63,7 @@ module es {
|
||||
* @param value1
|
||||
* @param value2
|
||||
*/
|
||||
public static multiply(value1: Vector2, value2: Vector2){
|
||||
public static multiply(value1: Vector2, value2: Vector2) {
|
||||
let result: Vector2 = new Vector2(0, 0);
|
||||
result.x = value1.x * value2.x;
|
||||
result.y = value1.y * value2.y;
|
||||
@@ -115,36 +75,19 @@ module es {
|
||||
* @param value1
|
||||
* @param value2
|
||||
*/
|
||||
public static subtract(value1: Vector2, value2: Vector2){
|
||||
public static subtract(value1: Vector2, value2: Vector2) {
|
||||
let result: Vector2 = new Vector2(0, 0);
|
||||
result.x = value1.x - value2.x;
|
||||
result.y = value1.y - value2.y;
|
||||
return result;
|
||||
}
|
||||
|
||||
/** 变成一个方向相同的单位向量 */
|
||||
public normalize(){
|
||||
let val = 1 / Math.sqrt((this.x * this.x) + (this.y * this.y));
|
||||
this.x *= val;
|
||||
this.y *= val;
|
||||
}
|
||||
|
||||
/** 返回它的长度 */
|
||||
public length(){
|
||||
return Math.sqrt((this.x * this.x) + (this.y * this.y));
|
||||
}
|
||||
|
||||
/** 对x和y值四舍五入 */
|
||||
public round(): Vector2{
|
||||
return new Vector2(Math.round(this.x), Math.round(this.y));
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个新的Vector2
|
||||
* 它包含来自另一个向量的标准化值。
|
||||
* @param value
|
||||
*/
|
||||
public static normalize(value: Vector2){
|
||||
public static normalize(value: Vector2) {
|
||||
let val = 1 / Math.sqrt((value.x * value.x) + (value.y * value.y));
|
||||
value.x *= val;
|
||||
value.y *= val;
|
||||
@@ -156,7 +99,7 @@ module es {
|
||||
* @param value1
|
||||
* @param value2
|
||||
*/
|
||||
public static dot(value1: Vector2, value2: Vector2): number{
|
||||
public static dot(value1: Vector2, value2: Vector2): number {
|
||||
return (value1.x * value2.x) + (value1.y * value2.y);
|
||||
}
|
||||
|
||||
@@ -165,7 +108,7 @@ module es {
|
||||
* @param value1
|
||||
* @param value2
|
||||
*/
|
||||
public static distanceSquared(value1: Vector2, value2: Vector2){
|
||||
public static distanceSquared(value1: Vector2, value2: Vector2) {
|
||||
let v1 = value1.x - value2.x, v2 = value1.y - value2.y;
|
||||
return (v1 * v1) + (v2 * v2);
|
||||
}
|
||||
@@ -176,7 +119,7 @@ module es {
|
||||
* @param min
|
||||
* @param max
|
||||
*/
|
||||
public static clamp(value1: Vector2, min: Vector2, max: Vector2){
|
||||
public static clamp(value1: Vector2, min: Vector2, max: Vector2) {
|
||||
return new Vector2(MathHelper.clamp(value1.x, min.x, max.x),
|
||||
MathHelper.clamp(value1.y, min.y, max.y));
|
||||
}
|
||||
@@ -187,7 +130,7 @@ module es {
|
||||
* @param value2 第二个向量
|
||||
* @param amount 权重值(0.0到1.0之间)
|
||||
*/
|
||||
public static lerp(value1: Vector2, value2: Vector2, amount: number){
|
||||
public static lerp(value1: Vector2, value2: Vector2, amount: number) {
|
||||
return new Vector2(MathHelper.lerp(value1.x, value2.x, amount), MathHelper.lerp(value1.y, value2.y, amount));
|
||||
}
|
||||
|
||||
@@ -196,7 +139,7 @@ module es {
|
||||
* @param position
|
||||
* @param matrix
|
||||
*/
|
||||
public static transform(position: Vector2, matrix: Matrix2D){
|
||||
public static transform(position: Vector2, matrix: Matrix2D) {
|
||||
return new Vector2((position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m31,
|
||||
(position.x * matrix.m12) + (position.y * matrix.m22) + matrix.m32);
|
||||
}
|
||||
@@ -206,7 +149,7 @@ module es {
|
||||
* @param value1
|
||||
* @param value2
|
||||
*/
|
||||
public static distance(value1: Vector2, value2: Vector2){
|
||||
public static distance(value1: Vector2, value2: Vector2) {
|
||||
let v1 = value1.x - value2.x, v2 = value1.y - value2.y;
|
||||
return Math.sqrt((v1 * v1) + (v2 * v2));
|
||||
}
|
||||
@@ -215,7 +158,7 @@ module es {
|
||||
* 矢量反演的结果
|
||||
* @param value
|
||||
*/
|
||||
public static negate(value: Vector2){
|
||||
public static negate(value: Vector2) {
|
||||
let result: Vector2 = new Vector2();
|
||||
result.x = -value.x;
|
||||
result.y = -value.y;
|
||||
@@ -223,7 +166,64 @@ module es {
|
||||
return result;
|
||||
}
|
||||
|
||||
public equals(other: Vector2){
|
||||
/**
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
public add(value: Vector2): Vector2 {
|
||||
this.x += value.x;
|
||||
this.y += value.y;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
public divide(value: Vector2): Vector2 {
|
||||
this.x /= value.x;
|
||||
this.y /= value.y;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
public multiply(value: Vector2): Vector2 {
|
||||
this.x *= value.x;
|
||||
this.y *= value.y;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
public subtract(value: Vector2) {
|
||||
this.x -= value.x;
|
||||
this.y -= value.y;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** 变成一个方向相同的单位向量 */
|
||||
public normalize() {
|
||||
let val = 1 / Math.sqrt((this.x * this.x) + (this.y * this.y));
|
||||
this.x *= val;
|
||||
this.y *= val;
|
||||
}
|
||||
|
||||
/** 返回它的长度 */
|
||||
public length() {
|
||||
return Math.sqrt((this.x * this.x) + (this.y * this.y));
|
||||
}
|
||||
|
||||
/** 对x和y值四舍五入 */
|
||||
public round(): Vector2 {
|
||||
return new Vector2(Math.round(this.x), Math.round(this.y));
|
||||
}
|
||||
|
||||
public equals(other: Vector2) {
|
||||
return other.x == this.x && other.y == this.y;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ module es {
|
||||
public y: number;
|
||||
public z: number;
|
||||
|
||||
constructor(x: number, y: number, z: number){
|
||||
constructor(x: number, y: number, z: number) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
|
||||
@@ -50,8 +50,8 @@ module es {
|
||||
this.checkForExitedColliders();
|
||||
}
|
||||
|
||||
private checkForExitedColliders(){
|
||||
for (let i = 0; i < this._activeTriggerIntersections.length; i ++){
|
||||
private checkForExitedColliders() {
|
||||
for (let i = 0; i < this._activeTriggerIntersections.length; i++) {
|
||||
let index = this._previousTriggerIntersections.findIndex(value => {
|
||||
if (value.first == this._activeTriggerIntersections[i].first && value.second == this._activeTriggerIntersections[i].second)
|
||||
return true;
|
||||
@@ -62,12 +62,12 @@ module es {
|
||||
this._previousTriggerIntersections.removeAt(index);
|
||||
}
|
||||
|
||||
for (let i = 0; i < this._previousTriggerIntersections.length; i ++){
|
||||
for (let i = 0; i < this._previousTriggerIntersections.length; i++) {
|
||||
this.notifyTriggerListeners(this._previousTriggerIntersections[i], false)
|
||||
}
|
||||
this._previousTriggerIntersections.length = 0;
|
||||
for (let i = 0; i < this._activeTriggerIntersections.length; i ++){
|
||||
if (!this._previousTriggerIntersections.contains(this._activeTriggerIntersections[i])){
|
||||
for (let i = 0; i < this._activeTriggerIntersections.length; i++) {
|
||||
if (!this._previousTriggerIntersections.contains(this._activeTriggerIntersections[i])) {
|
||||
this._previousTriggerIntersections.push(this._activeTriggerIntersections[i]);
|
||||
}
|
||||
}
|
||||
@@ -76,8 +76,8 @@ module es {
|
||||
|
||||
private notifyTriggerListeners(collisionPair: Pair<Collider>, isEntering: boolean) {
|
||||
collisionPair.first.entity.getComponents("ITriggerListener", this._tempTriggerList);
|
||||
for (let i = 0; i < this._tempTriggerList.length; i ++){
|
||||
if (isEntering){
|
||||
for (let i = 0; i < this._tempTriggerList.length; i++) {
|
||||
if (isEntering) {
|
||||
this._tempTriggerList[i].onTriggerEnter(collisionPair.second, collisionPair.first);
|
||||
} else {
|
||||
this._tempTriggerList[i].onTriggerExit(collisionPair.second, collisionPair.first);
|
||||
@@ -85,10 +85,10 @@ module es {
|
||||
|
||||
this._tempTriggerList.length = 0;
|
||||
|
||||
if (collisionPair.second.entity){
|
||||
if (collisionPair.second.entity) {
|
||||
collisionPair.second.entity.getComponents("ITriggerListener", this._tempTriggerList);
|
||||
for (let i = 0; i < this._tempTriggerList.length; i ++){
|
||||
if (isEntering){
|
||||
for (let i = 0; i < this._tempTriggerList.length; i++) {
|
||||
if (isEntering) {
|
||||
this._tempTriggerList[i].onTriggerEnter(collisionPair.first, collisionPair.second);
|
||||
} else {
|
||||
this._tempTriggerList[i].onTriggerExit(collisionPair.first, collisionPair.second);
|
||||
|
||||
@@ -88,42 +88,42 @@ module es {
|
||||
return vx * vx + vy * vy < cRadius * cRadius;
|
||||
}
|
||||
|
||||
public static isRectToLine(rect: Rectangle, lineFrom: Vector2, lineTo: Vector2){
|
||||
public static isRectToLine(rect: Rectangle, lineFrom: Vector2, lineTo: Vector2) {
|
||||
let fromSector = this.getSector(rect.x, rect.y, rect.width, rect.height, lineFrom);
|
||||
let toSector = this.getSector(rect.x, rect.y, rect.width, rect.height, lineTo);
|
||||
|
||||
if (fromSector == PointSectors.center || toSector == PointSectors.center){
|
||||
if (fromSector == PointSectors.center || toSector == PointSectors.center) {
|
||||
return true;
|
||||
} else if((fromSector & toSector) != 0){
|
||||
} else if ((fromSector & toSector) != 0) {
|
||||
return false;
|
||||
} else{
|
||||
} else {
|
||||
let both = fromSector | toSector;
|
||||
// 线对边进行检查
|
||||
let edgeFrom: Vector2;
|
||||
let edgeTo: Vector2;
|
||||
|
||||
if ((both & PointSectors.top) != 0){
|
||||
if ((both & PointSectors.top) != 0) {
|
||||
edgeFrom = new Vector2(rect.x, rect.y);
|
||||
edgeTo = new Vector2(rect.x + rect.width, rect.y);
|
||||
if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo))
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((both & PointSectors.bottom) != 0){
|
||||
if ((both & PointSectors.bottom) != 0) {
|
||||
edgeFrom = new Vector2(rect.x, rect.y + rect.height);
|
||||
edgeTo = new Vector2(rect.x + rect.width, rect.y + rect.height);
|
||||
if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo))
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((both & PointSectors.left) != 0){
|
||||
if ((both & PointSectors.left) != 0) {
|
||||
edgeFrom = new Vector2(rect.x, rect.y);
|
||||
edgeTo = new Vector2(rect.x, rect.y + rect.height);
|
||||
if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo))
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((both & PointSectors.right) != 0){
|
||||
if ((both & PointSectors.right) != 0) {
|
||||
edgeFrom = new Vector2(rect.x + rect.width, rect.y);
|
||||
edgeTo = new Vector2(rect.x + rect.width, rect.y + rect.height);
|
||||
if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo))
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
module es {
|
||||
export class Physics {
|
||||
private static _spatialHash: SpatialHash;
|
||||
/** 调用reset并创建一个新的SpatialHash时使用的单元格大小 */
|
||||
public static spatialHashCellSize = 100;
|
||||
/** 接受layerMask的所有方法的默认值 */
|
||||
public static readonly allLayers: number = -1;
|
||||
private static _spatialHash: SpatialHash;
|
||||
|
||||
public static reset(){
|
||||
public static reset() {
|
||||
this._spatialHash = new SpatialHash(this.spatialHashCellSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从SpatialHash中移除所有碰撞器
|
||||
*/
|
||||
public static clear(){
|
||||
public static clear() {
|
||||
this._spatialHash.clear();
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@ module es {
|
||||
* @param results
|
||||
* @param layerMask
|
||||
*/
|
||||
public static overlapCircleAll(center: Vector2, randius: number, results: any[], layerMask = -1){
|
||||
if (results.length == 0){
|
||||
public static overlapCircleAll(center: Vector2, randius: number, results: any[], layerMask = -1) {
|
||||
if (results.length == 0) {
|
||||
console.error("An empty results array was passed in. No results will ever be returned.");
|
||||
return;
|
||||
}
|
||||
@@ -38,7 +38,7 @@ module es {
|
||||
* @param rect
|
||||
* @param layerMask
|
||||
*/
|
||||
public static boxcastBroadphase(rect: Rectangle, layerMask: number = this.allLayers){
|
||||
public static boxcastBroadphase(rect: Rectangle, layerMask: number = this.allLayers) {
|
||||
return this._spatialHash.aabbBroadphase(rect, null, layerMask);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ module es {
|
||||
* @param rect
|
||||
* @param layerMask
|
||||
*/
|
||||
public static boxcastBroadphaseExcludingSelf(collider: Collider, rect: Rectangle, layerMask = this.allLayers){
|
||||
public static boxcastBroadphaseExcludingSelf(collider: Collider, rect: Rectangle, layerMask = this.allLayers) {
|
||||
return this._spatialHash.aabbBroadphase(rect, collider, layerMask);
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ module es {
|
||||
* 将对撞机添加到物理系统中
|
||||
* @param collider
|
||||
*/
|
||||
public static addCollider(collider: Collider){
|
||||
public static addCollider(collider: Collider) {
|
||||
Physics._spatialHash.register(collider);
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ module es {
|
||||
* 从物理系统中移除对撞机
|
||||
* @param collider
|
||||
*/
|
||||
public static removeCollider(collider: Collider){
|
||||
public static removeCollider(collider: Collider) {
|
||||
Physics._spatialHash.remove(collider);
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ module es {
|
||||
* 更新物理系统中对撞机的位置。这实际上只是移除然后重新添加带有新边界的碰撞器
|
||||
* @param collider
|
||||
*/
|
||||
public static updateCollider(collider: Collider){
|
||||
public static updateCollider(collider: Collider) {
|
||||
this._spatialHash.remove(collider);
|
||||
this._spatialHash.register(collider);
|
||||
}
|
||||
@@ -81,7 +81,7 @@ module es {
|
||||
* debug绘制空间散列的内容
|
||||
* @param secondsToDisplay
|
||||
*/
|
||||
public static debugDraw(secondsToDisplay){
|
||||
public static debugDraw(secondsToDisplay) {
|
||||
this._spatialHash.debugDraw(secondsToDisplay, 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ module es {
|
||||
public width: number;
|
||||
public height: number;
|
||||
|
||||
constructor(width: number, height: number){
|
||||
constructor(width: number, height: number) {
|
||||
super(Box.buildBox(width, height), true);
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
@@ -18,7 +18,7 @@ module es {
|
||||
* @param width
|
||||
* @param height
|
||||
*/
|
||||
private static buildBox(width: number, height: number): Vector2[]{
|
||||
private static buildBox(width: number, height: number): Vector2[] {
|
||||
// 我们在(0,0)的中心周围创建点
|
||||
let halfWidth = width / 2;
|
||||
let halfHeight = height / 2;
|
||||
@@ -36,7 +36,7 @@ module es {
|
||||
* @param width
|
||||
* @param height
|
||||
*/
|
||||
public updateBox(width: number, height: number){
|
||||
public updateBox(width: number, height: number) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
@@ -49,13 +49,13 @@ module es {
|
||||
this.points[2] = new Vector2(halfWidth, halfHeight);
|
||||
this.points[3] = new Vector2(-halfWidth, halfHeight);
|
||||
|
||||
for (let i = 0; i < this.points.length; i ++)
|
||||
for (let i = 0; i < this.points.length; i++)
|
||||
this._originalPoints[i] = this.points[i];
|
||||
}
|
||||
|
||||
public overlaps(other: Shape){
|
||||
public overlaps(other: Shape) {
|
||||
// 特殊情况,这一个高性能方式实现,其他情况则使用polygon方法检测
|
||||
if (this.isUnrotated){
|
||||
if (this.isUnrotated) {
|
||||
if (other instanceof Box)
|
||||
return this.bounds.intersects(other.bounds);
|
||||
|
||||
@@ -66,9 +66,9 @@ module es {
|
||||
return super.overlaps(other);
|
||||
}
|
||||
|
||||
public collidesWithShape(other: Shape, result: CollisionResult): boolean{
|
||||
public collidesWithShape(other: Shape, result: CollisionResult): boolean {
|
||||
// 特殊情况,这一个高性能方式实现,其他情况则使用polygon方法检测
|
||||
if (other instanceof Box && (other as Box).isUnrotated){
|
||||
if (other instanceof Box && (other as Box).isUnrotated) {
|
||||
return ShapeCollisions.boxToBox(this, other, result);
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ module es {
|
||||
return super.collidesWithShape(other, result);
|
||||
}
|
||||
|
||||
public containsPoint(point: Vector2){
|
||||
public containsPoint(point: Vector2) {
|
||||
if (this.isUnrotated)
|
||||
return this.bounds.contains(point.x, point.y);
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ module es {
|
||||
public normal: Vector2 = Vector2.zero;
|
||||
public point: Vector2 = Vector2.zero;
|
||||
|
||||
public invertResult(){
|
||||
public invertResult() {
|
||||
this.minimumTranslationVector = Vector2.negate(this.minimumTranslationVector);
|
||||
this.normal = Vector2.negate(this.normal);
|
||||
}
|
||||
|
||||
@@ -9,19 +9,7 @@ module es {
|
||||
* 保持顺时针与凸边形
|
||||
*/
|
||||
public points: Vector2[];
|
||||
|
||||
/**
|
||||
* 边缘法线用于SAT碰撞检测。缓存它们用于避免squareRoots
|
||||
* box只有两个边缘 因为其他两边是平行的
|
||||
*/
|
||||
public get edgeNormals(){
|
||||
if (this._areEdgeNormalsDirty)
|
||||
this.buildEdgeNormals();
|
||||
return this._edgeNormals;
|
||||
}
|
||||
|
||||
public _areEdgeNormalsDirty = true;
|
||||
public _edgeNormals: Vector2[];
|
||||
/**
|
||||
* 多边形的原始数据
|
||||
*/
|
||||
@@ -39,61 +27,25 @@ module es {
|
||||
* @param points
|
||||
* @param isBox
|
||||
*/
|
||||
constructor(points: Vector2[], isBox?: boolean){
|
||||
constructor(points: Vector2[], isBox?: boolean) {
|
||||
super();
|
||||
|
||||
this.setPoints(points);
|
||||
this.isBox = isBox;
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置点并重新计算中心和边缘法线
|
||||
* @param points
|
||||
*/
|
||||
public setPoints(points: Vector2[]) {
|
||||
this.points = points;
|
||||
this.recalculateCenterAndEdgeNormals();
|
||||
|
||||
this._originalPoints = [];
|
||||
for (let i = 0; i < this.points.length; i ++){
|
||||
this._originalPoints.push(this.points[i]);
|
||||
}
|
||||
}
|
||||
public _edgeNormals: Vector2[];
|
||||
|
||||
/**
|
||||
* 重新计算多边形中心
|
||||
* 如果点数改变必须调用该方法
|
||||
* 边缘法线用于SAT碰撞检测。缓存它们用于避免squareRoots
|
||||
* box只有两个边缘 因为其他两边是平行的
|
||||
*/
|
||||
public recalculateCenterAndEdgeNormals() {
|
||||
this._polygonCenter = Polygon.findPolygonCenter(this.points);
|
||||
this._areEdgeNormalsDirty = true;
|
||||
public get edgeNormals() {
|
||||
if (this._areEdgeNormalsDirty)
|
||||
this.buildEdgeNormals();
|
||||
return this._edgeNormals;
|
||||
}
|
||||
|
||||
/**
|
||||
* 建立多边形边缘法线
|
||||
* 它们仅由edgeNormals getter惰性创建和更新
|
||||
*/
|
||||
public buildEdgeNormals(){
|
||||
// 对于box 我们只需要两条边,因为另外两条边是平行的
|
||||
let totalEdges = this.isBox ? 2 : this.points.length;
|
||||
if (this._edgeNormals == null || this._edgeNormals.length != totalEdges)
|
||||
this._edgeNormals = new Array(totalEdges);
|
||||
|
||||
let p2: Vector2;
|
||||
for (let i = 0; i < totalEdges; i ++){
|
||||
let p1 = this.points[i];
|
||||
if (i + 1 >= this.points.length)
|
||||
p2 = this.points[0];
|
||||
else
|
||||
p2 = this.points[i + 1];
|
||||
|
||||
let perp = Vector2Ext.perpendicular(p1, p2);
|
||||
perp = Vector2.normalize(perp);
|
||||
this._edgeNormals[i] = perp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 建立一个对称的多边形(六边形,八角形,n角形)并返回点
|
||||
* @param vertCount
|
||||
@@ -114,9 +66,9 @@ module es {
|
||||
* 重定位多边形的点
|
||||
* @param points
|
||||
*/
|
||||
public static recenterPolygonVerts(points: Vector2[]){
|
||||
public static recenterPolygonVerts(points: Vector2[]) {
|
||||
let center = this.findPolygonCenter(points);
|
||||
for (let i = 0; i < points.length; i ++)
|
||||
for (let i = 0; i < points.length; i++)
|
||||
points[i] = Vector2.subtract(points[i], center);
|
||||
}
|
||||
|
||||
@@ -173,16 +125,63 @@ module es {
|
||||
return closestPoint;
|
||||
}
|
||||
|
||||
public recalculateBounds(collider: Collider){
|
||||
/**
|
||||
* 重置点并重新计算中心和边缘法线
|
||||
* @param points
|
||||
*/
|
||||
public setPoints(points: Vector2[]) {
|
||||
this.points = points;
|
||||
this.recalculateCenterAndEdgeNormals();
|
||||
|
||||
this._originalPoints = [];
|
||||
for (let i = 0; i < this.points.length; i++) {
|
||||
this._originalPoints.push(this.points[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新计算多边形中心
|
||||
* 如果点数改变必须调用该方法
|
||||
*/
|
||||
public recalculateCenterAndEdgeNormals() {
|
||||
this._polygonCenter = Polygon.findPolygonCenter(this.points);
|
||||
this._areEdgeNormalsDirty = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 建立多边形边缘法线
|
||||
* 它们仅由edgeNormals getter惰性创建和更新
|
||||
*/
|
||||
public buildEdgeNormals() {
|
||||
// 对于box 我们只需要两条边,因为另外两条边是平行的
|
||||
let totalEdges = this.isBox ? 2 : this.points.length;
|
||||
if (this._edgeNormals == null || this._edgeNormals.length != totalEdges)
|
||||
this._edgeNormals = new Array(totalEdges);
|
||||
|
||||
let p2: Vector2;
|
||||
for (let i = 0; i < totalEdges; i++) {
|
||||
let p1 = this.points[i];
|
||||
if (i + 1 >= this.points.length)
|
||||
p2 = this.points[0];
|
||||
else
|
||||
p2 = this.points[i + 1];
|
||||
|
||||
let perp = Vector2Ext.perpendicular(p1, p2);
|
||||
perp = Vector2.normalize(perp);
|
||||
this._edgeNormals[i] = perp;
|
||||
}
|
||||
}
|
||||
|
||||
public recalculateBounds(collider: Collider) {
|
||||
// 如果我们没有旋转或不关心TRS我们使用localOffset作为中心,我们会从那开始
|
||||
this.center = collider.localOffset;
|
||||
|
||||
if (collider.shouldColliderScaleAndRotateWithTransform){
|
||||
if (collider.shouldColliderScaleAndRotateWithTransform) {
|
||||
let hasUnitScale = true;
|
||||
let tempMat: Matrix2D;
|
||||
let combinedMatrix = Matrix2D.create().translate(-this._polygonCenter.x, -this._polygonCenter.y);
|
||||
|
||||
if (collider.entity.transform.scale != Vector2.zero){
|
||||
if (collider.entity.transform.scale != Vector2.zero) {
|
||||
tempMat = Matrix2D.create().scale(collider.entity.transform.scale.x, collider.entity.transform.scale.y);
|
||||
combinedMatrix = combinedMatrix.multiply(tempMat);
|
||||
hasUnitScale = false;
|
||||
@@ -191,7 +190,7 @@ module es {
|
||||
this.center = Vector2.multiply(collider.localOffset, collider.entity.transform.scale);
|
||||
}
|
||||
|
||||
if (collider.entity.transform.rotation != 0){
|
||||
if (collider.entity.transform.rotation != 0) {
|
||||
tempMat = Matrix2D.create().rotate(collider.entity.transform.rotation);
|
||||
combinedMatrix = combinedMatrix.multiply(tempMat);
|
||||
|
||||
@@ -222,13 +221,13 @@ module es {
|
||||
this.bounds.location = this.bounds.location.add(this.position);
|
||||
}
|
||||
|
||||
public overlaps(other: Shape){
|
||||
public overlaps(other: Shape) {
|
||||
let result: CollisionResult = new CollisionResult();
|
||||
if (other instanceof Polygon)
|
||||
return ShapeCollisions.polygonToPolygon(this, other, result);
|
||||
|
||||
if (other instanceof Circle){
|
||||
if (ShapeCollisions.circleToPolygon(other, this, result)){
|
||||
if (other instanceof Circle) {
|
||||
if (ShapeCollisions.circleToPolygon(other, this, result)) {
|
||||
result.invertResult();
|
||||
return true;
|
||||
}
|
||||
@@ -239,13 +238,13 @@ module es {
|
||||
throw new Error(`overlaps of Pologon to ${other} are not supported`);
|
||||
}
|
||||
|
||||
public collidesWithShape(other: Shape, result: CollisionResult): boolean{
|
||||
if (other instanceof Polygon){
|
||||
public collidesWithShape(other: Shape, result: CollisionResult): boolean {
|
||||
if (other instanceof Polygon) {
|
||||
return ShapeCollisions.polygonToPolygon(this, other, result);
|
||||
}
|
||||
|
||||
if (other instanceof Circle){
|
||||
if (ShapeCollisions.circleToPolygon(other, this, result)){
|
||||
if (other instanceof Circle) {
|
||||
if (ShapeCollisions.circleToPolygon(other, this, result)) {
|
||||
result.invertResult();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -16,11 +16,14 @@ module es {
|
||||
public bounds: Rectangle;
|
||||
|
||||
public abstract recalculateBounds(collider: Collider);
|
||||
|
||||
public abstract overlaps(other: Shape): boolean;
|
||||
|
||||
public abstract collidesWithShape(other: Shape, collisionResult: CollisionResult): boolean;
|
||||
|
||||
public abstract pointCollidesWithShape(point: Vector2, result: CollisionResult): boolean;
|
||||
|
||||
public clone(): Shape{
|
||||
public clone(): Shape {
|
||||
return ObjectUtils.clone<Shape>(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ module es {
|
||||
}
|
||||
}
|
||||
|
||||
return { min: min, max: max };
|
||||
return {min: min, max: max};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -245,11 +245,11 @@ module es {
|
||||
* @param first
|
||||
* @param second
|
||||
*/
|
||||
public static circleToCircle(first: Circle, second: Circle, result: CollisionResult): boolean{
|
||||
public static circleToCircle(first: Circle, second: Circle, result: CollisionResult): boolean {
|
||||
let distanceSquared = Vector2.distanceSquared(first.position, second.position);
|
||||
let sumOfRadii = first.radius + second.radius;
|
||||
let collided = distanceSquared < sumOfRadii * sumOfRadii;
|
||||
if (collided){
|
||||
if (collided) {
|
||||
result.normal = Vector2.normalize(Vector2.subtract(first.position, second.position));
|
||||
let depth = sumOfRadii - Math.sqrt(distanceSquared);
|
||||
result.minimumTranslationVector = Vector2.multiply(new Vector2(-depth), result.normal);
|
||||
@@ -267,9 +267,9 @@ module es {
|
||||
* @param second
|
||||
* @param result
|
||||
*/
|
||||
public static boxToBox(first: Box, second: Box, result: CollisionResult): boolean{
|
||||
public static boxToBox(first: Box, second: Box, result: CollisionResult): boolean {
|
||||
let minkowskiDiff = this.minkowskiDifference(first, second);
|
||||
if (minkowskiDiff.contains(0, 0)){
|
||||
if (minkowskiDiff.contains(0, 0)) {
|
||||
// 计算MTV。如果它是零,我们就可以称它为非碰撞
|
||||
result.minimumTranslationVector = minkowskiDiff.getClosestPointOnBoundsToOrigin();
|
||||
|
||||
@@ -285,7 +285,7 @@ module es {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static minkowskiDifference(first: Box, second: Box){
|
||||
private static minkowskiDifference(first: Box, second: Box) {
|
||||
// 我们需要第一个框的左上角
|
||||
// 碰撞器只会修改运动的位置所以我们需要用位置来计算出运动是什么。
|
||||
let positionOffset = Vector2.subtract(first.position, Vector2.add(first.bounds.location, Vector2.divide(first.bounds.size, new Vector2(2))));
|
||||
|
||||
@@ -30,33 +30,6 @@ module es {
|
||||
this._raycastParser = new RaycastResultParser();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单元格的x,y值作为世界空间的x,y值
|
||||
* @param x
|
||||
* @param y
|
||||
*/
|
||||
private cellCoords(x: number, y: number): Vector2 {
|
||||
return new Vector2(Math.floor(x * this._inverseCellSize), Math.floor(y * this._inverseCellSize));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取世界空间x,y值的单元格。
|
||||
* 如果单元格为空且createCellIfEmpty为true,则会创建一个新的单元格
|
||||
* @param x
|
||||
* @param y
|
||||
* @param createCellIfEmpty
|
||||
*/
|
||||
private cellAtPosition(x: number, y: number, createCellIfEmpty: boolean = false) {
|
||||
let cell: Collider[] = this._cellDict.tryGetValue(x, y);
|
||||
if (!cell) {
|
||||
if (createCellIfEmpty) {
|
||||
cell = [];
|
||||
this._cellDict.add(x, y, cell);
|
||||
}
|
||||
}
|
||||
return cell;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将对象添加到SpatialHash
|
||||
* @param collider
|
||||
@@ -111,11 +84,11 @@ module es {
|
||||
* 使用蛮力方法从SpatialHash中删除对象
|
||||
* @param obj
|
||||
*/
|
||||
public removeWithBruteForce(obj: Collider){
|
||||
public removeWithBruteForce(obj: Collider) {
|
||||
this._cellDict.remove(obj);
|
||||
}
|
||||
|
||||
public clear(){
|
||||
public clear() {
|
||||
this._cellDict.clear();
|
||||
}
|
||||
|
||||
@@ -124,9 +97,9 @@ module es {
|
||||
* @param secondsToDisplay
|
||||
* @param textScale
|
||||
*/
|
||||
public debugDraw(secondsToDisplay: number, textScale: number = 1){
|
||||
for (let x = this.gridBounds.x; x <= this.gridBounds.right; x ++){
|
||||
for (let y = this.gridBounds.y; y <= this.gridBounds.bottom; y ++){
|
||||
public debugDraw(secondsToDisplay: number, textScale: number = 1) {
|
||||
for (let x = this.gridBounds.x; x <= this.gridBounds.right; x++) {
|
||||
for (let y = this.gridBounds.y; y <= this.gridBounds.bottom; y++) {
|
||||
let cell = this.cellAtPosition(x, y);
|
||||
if (cell && cell.length > 0)
|
||||
this.debugDrawCellDetails(x, y, cell.length, secondsToDisplay, textScale);
|
||||
@@ -134,17 +107,13 @@ module es {
|
||||
}
|
||||
}
|
||||
|
||||
private debugDrawCellDetails(x: number, y: number, cellCount: number, secondsToDisplay = 0.5, textScale = 1){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回边框与单元格相交的所有对象
|
||||
* @param bounds
|
||||
* @param excludeCollider
|
||||
* @param layerMask
|
||||
*/
|
||||
public aabbBroadphase(bounds: Rectangle, excludeCollider: Collider, layerMask: number) : Collider[]{
|
||||
public aabbBroadphase(bounds: Rectangle, excludeCollider: Collider, layerMask: number): Collider[] {
|
||||
this._tempHashSet.length = 0;
|
||||
|
||||
let p1 = this.cellCoords(bounds.x, bounds.y);
|
||||
@@ -164,7 +133,7 @@ module es {
|
||||
if (collider == excludeCollider || !Flags.isFlagSet(layerMask, collider.physicsLayer))
|
||||
continue;
|
||||
|
||||
if (bounds.intersects(collider.bounds)){
|
||||
if (bounds.intersects(collider.bounds)) {
|
||||
if (this._tempHashSet.indexOf(collider) == -1)
|
||||
this._tempHashSet.push(collider);
|
||||
}
|
||||
@@ -196,14 +165,14 @@ module es {
|
||||
results[resultCounter] = collider;
|
||||
resultCounter++;
|
||||
} else if (collider instanceof CircleCollider) {
|
||||
if (collider.shape.overlaps(this._overlapTestCircle)){
|
||||
if (collider.shape.overlaps(this._overlapTestCircle)) {
|
||||
results[resultCounter] = collider;
|
||||
resultCounter ++;
|
||||
resultCounter++;
|
||||
}
|
||||
} else if(collider instanceof PolygonCollider) {
|
||||
if (collider.shape.overlaps(this._overlapTestCircle)){
|
||||
} else if (collider instanceof PolygonCollider) {
|
||||
if (collider.shape.overlaps(this._overlapTestCircle)) {
|
||||
results[resultCounter] = collider;
|
||||
resultCounter ++;
|
||||
resultCounter++;
|
||||
}
|
||||
} else {
|
||||
throw new Error("overlapCircle against this collider type is not implemented!");
|
||||
@@ -216,6 +185,37 @@ module es {
|
||||
|
||||
return resultCounter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单元格的x,y值作为世界空间的x,y值
|
||||
* @param x
|
||||
* @param y
|
||||
*/
|
||||
private cellCoords(x: number, y: number): Vector2 {
|
||||
return new Vector2(Math.floor(x * this._inverseCellSize), Math.floor(y * this._inverseCellSize));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取世界空间x,y值的单元格。
|
||||
* 如果单元格为空且createCellIfEmpty为true,则会创建一个新的单元格
|
||||
* @param x
|
||||
* @param y
|
||||
* @param createCellIfEmpty
|
||||
*/
|
||||
private cellAtPosition(x: number, y: number, createCellIfEmpty: boolean = false) {
|
||||
let cell: Collider[] = this._cellDict.tryGetValue(x, y);
|
||||
if (!cell) {
|
||||
if (createCellIfEmpty) {
|
||||
cell = [];
|
||||
this._cellDict.add(x, y, cell);
|
||||
}
|
||||
}
|
||||
return cell;
|
||||
}
|
||||
|
||||
private debugDrawCellDetails(x: number, y: number, cellCount: number, secondsToDisplay = 0.5, textScale = 1) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -225,15 +225,6 @@ module es {
|
||||
export class NumberDictionary {
|
||||
public _store: Map<string, Collider[]> = new Map<string, Collider[]>();
|
||||
|
||||
/**
|
||||
* 根据x和y值计算并返回散列键
|
||||
* @param x
|
||||
* @param y
|
||||
*/
|
||||
private getKey(x: number, y: number): string {
|
||||
return Long.fromNumber(x).shiftLeft(32).or(Long.fromNumber(y, true)).toString();
|
||||
}
|
||||
|
||||
public add(x: number, y: number, list: Collider[]) {
|
||||
this._store.set(this.getKey(x, y), list);
|
||||
}
|
||||
@@ -259,6 +250,15 @@ module es {
|
||||
public clear() {
|
||||
this._store.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据x和y值计算并返回散列键
|
||||
* @param x
|
||||
* @param y
|
||||
*/
|
||||
private getKey(x: number, y: number): string {
|
||||
return Long.fromNumber(x).shiftLeft(32).or(Long.fromNumber(y, true)).toString();
|
||||
}
|
||||
}
|
||||
|
||||
export class RaycastResultParser {
|
||||
|
||||
@@ -6,30 +6,30 @@ module es {
|
||||
public clientArea: Rectangle;
|
||||
public safeArea: Rectangle;
|
||||
|
||||
constructor(){
|
||||
constructor() {
|
||||
this.clientArea = new Rectangle(0, 0, Core.graphicsDevice.viewport.width, Core.graphicsDevice.viewport.height);
|
||||
this.safeArea = this.clientArea;
|
||||
}
|
||||
|
||||
public place(size: Vector2, horizontalMargin: number, verticalMargine: number, alignment: Alignment){
|
||||
public place(size: Vector2, horizontalMargin: number, verticalMargine: number, alignment: Alignment) {
|
||||
let rc = new Rectangle(0, 0, size.x, size.y);
|
||||
if ((alignment & Alignment.left) != 0){
|
||||
if ((alignment & Alignment.left) != 0) {
|
||||
rc.x = this.clientArea.x + (this.clientArea.width * horizontalMargin);
|
||||
}else if((alignment & Alignment.right) != 0){
|
||||
} else if ((alignment & Alignment.right) != 0) {
|
||||
rc.x = this.clientArea.x + (this.clientArea.width * (1 - horizontalMargin)) - rc.width;
|
||||
} else if((alignment & Alignment.horizontalCenter) != 0){
|
||||
} else if ((alignment & Alignment.horizontalCenter) != 0) {
|
||||
rc.x = this.clientArea.x + (this.clientArea.width - rc.width) / 2 + (horizontalMargin * this.clientArea.width);
|
||||
}else{
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
if ((alignment & Alignment.top) != 0){
|
||||
if ((alignment & Alignment.top) != 0) {
|
||||
rc.y = this.clientArea.y + (this.clientArea.height * verticalMargine);
|
||||
}else if((alignment & Alignment.bottom) != 0){
|
||||
} else if ((alignment & Alignment.bottom) != 0) {
|
||||
rc.y = this.clientArea.y + (this.clientArea.height * (1 - verticalMargine)) - rc.height;
|
||||
} else if((alignment & Alignment.verticalCenter) != 0){
|
||||
} else if ((alignment & Alignment.verticalCenter) != 0) {
|
||||
rc.y = this.clientArea.y + (this.clientArea.height - rc.height) / 2 + (verticalMargine * this.clientArea.height);
|
||||
}else{
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
namespace stopwatch {
|
||||
/**
|
||||
* 记录时间的持续时间,一些设计灵感来自物理秒表。
|
||||
*/
|
||||
* 记录时间的持续时间,一些设计灵感来自物理秒表。
|
||||
*/
|
||||
export class Stopwatch {
|
||||
/**
|
||||
/**
|
||||
* 秒表启动的系统时间。
|
||||
* undefined,如果秒表尚未启动,或已复位。
|
||||
* undefined,如果秒表尚未启动,或已复位。
|
||||
*/
|
||||
private _startSystemTime: number | undefined;
|
||||
/**
|
||||
/**
|
||||
* 秒表停止的系统时间。
|
||||
* undefined,如果秒表目前没有停止,尚未开始,或已复位。
|
||||
* undefined,如果秒表目前没有停止,尚未开始,或已复位。
|
||||
*/
|
||||
private _stopSystemTime: number | undefined;
|
||||
/** 自上次复位以来,秒表已停止的系统时间总数。 */
|
||||
private _stopDuration: number = 0;
|
||||
/**
|
||||
/**
|
||||
* 用秒表计时,当前等待的切片开始的时间。
|
||||
* undefined,如果秒表尚未启动,或已复位。
|
||||
*/
|
||||
@@ -25,7 +25,8 @@ namespace stopwatch {
|
||||
*/
|
||||
private _completeSlices: Slice[] = [];
|
||||
|
||||
constructor(private readonly getSystemTime = _defaultSystemTimeGetter) { }
|
||||
constructor(private readonly getSystemTime = _defaultSystemTimeGetter) {
|
||||
}
|
||||
|
||||
public getState() {
|
||||
if (this._startSystemTime === undefined) {
|
||||
@@ -37,22 +38,22 @@ namespace stopwatch {
|
||||
}
|
||||
}
|
||||
|
||||
public isIdle(){
|
||||
public isIdle() {
|
||||
return this.getState() === State.IDLE;
|
||||
}
|
||||
|
||||
public isRunning(){
|
||||
public isRunning() {
|
||||
return this.getState() === State.RUNNING;
|
||||
}
|
||||
|
||||
public isStopped(){
|
||||
public isStopped() {
|
||||
return this.getState() === State.STOPPED;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
public slice(){
|
||||
public slice() {
|
||||
return this.recordPendingSlice();
|
||||
}
|
||||
|
||||
@@ -80,20 +81,70 @@ namespace stopwatch {
|
||||
/**
|
||||
* 获取当前秒表时间。这是这个秒表自上次复位以来运行的系统时间总数。
|
||||
*/
|
||||
public getTime(){
|
||||
public getTime() {
|
||||
return this.caculateStopwatchTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* 完全重置这个秒表到它的初始状态。清除所有记录的运行持续时间、切片等。
|
||||
*/
|
||||
public reset() {
|
||||
this._startSystemTime = this._pendingSliceStartStopwatchTime = this._stopSystemTime = undefined;
|
||||
this._stopDuration = 0;
|
||||
this._completeSlices = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始(或继续)运行秒表。
|
||||
* @param forceReset
|
||||
*/
|
||||
public start(forceReset: boolean = false) {
|
||||
if (forceReset) {
|
||||
this.reset();
|
||||
}
|
||||
|
||||
if (this._stopSystemTime !== undefined) {
|
||||
const systemNow = this.getSystemTime();
|
||||
const stopDuration = systemNow - this._stopSystemTime;
|
||||
|
||||
this._stopDuration += stopDuration;
|
||||
this._stopSystemTime = undefined;
|
||||
} else if (this._startSystemTime === undefined) {
|
||||
const systemNow = this.getSystemTime();
|
||||
this._startSystemTime = systemNow;
|
||||
this._pendingSliceStartStopwatchTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param recordPendingSlice
|
||||
*/
|
||||
public stop(recordPendingSlice: boolean = false) {
|
||||
if (this._startSystemTime === undefined) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const systemTimeOfStopwatchTime = this.getSystemTimeOfCurrentStopwatchTime();
|
||||
|
||||
if (recordPendingSlice) {
|
||||
this.recordPendingSlice(this.caculateStopwatchTime(systemTimeOfStopwatchTime));
|
||||
}
|
||||
|
||||
this._stopSystemTime = systemTimeOfStopwatchTime;
|
||||
return this.getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算指定秒表时间的当前挂起片。
|
||||
* @param endStopwatchTime
|
||||
* @param endStopwatchTime
|
||||
*/
|
||||
private calculatePendingSlice(endStopwatchTime?: number): Slice {
|
||||
if (this._pendingSliceStartStopwatchTime === undefined){
|
||||
if (this._pendingSliceStartStopwatchTime === undefined) {
|
||||
return Object.freeze({startTime: 0, endTime: 0, duration: 0});
|
||||
}
|
||||
|
||||
if (endStopwatchTime === undefined){
|
||||
if (endStopwatchTime === undefined) {
|
||||
endStopwatchTime = this.getTime();
|
||||
}
|
||||
|
||||
@@ -106,9 +157,9 @@ namespace stopwatch {
|
||||
|
||||
/**
|
||||
* 计算指定系统时间的当前秒表时间。
|
||||
* @param endSystemTime
|
||||
* @param endSystemTime
|
||||
*/
|
||||
private caculateStopwatchTime(endSystemTime?: number){
|
||||
private caculateStopwatchTime(endSystemTime?: number) {
|
||||
if (this._startSystemTime === undefined)
|
||||
return 0;
|
||||
|
||||
@@ -122,67 +173,17 @@ namespace stopwatch {
|
||||
* 获取与当前秒表时间等效的系统时间。
|
||||
* 如果该秒表当前停止,则返回该秒表停止时的系统时间。
|
||||
*/
|
||||
private getSystemTimeOfCurrentStopwatchTime(){
|
||||
private getSystemTimeOfCurrentStopwatchTime() {
|
||||
return this._stopSystemTime === undefined ? this.getSystemTime() : this._stopSystemTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* 完全重置这个秒表到它的初始状态。清除所有记录的运行持续时间、切片等。
|
||||
*/
|
||||
public reset(){
|
||||
this._startSystemTime = this._pendingSliceStartStopwatchTime = this._stopSystemTime = undefined;
|
||||
this._stopDuration = 0;
|
||||
this._completeSlices = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始(或继续)运行秒表。
|
||||
* @param forceReset
|
||||
*/
|
||||
public start(forceReset: boolean = false){
|
||||
if (forceReset){
|
||||
this.reset();
|
||||
}
|
||||
|
||||
if (this._stopSystemTime !== undefined){
|
||||
const systemNow = this.getSystemTime();
|
||||
const stopDuration = systemNow - this._stopSystemTime;
|
||||
|
||||
this._stopDuration += stopDuration;
|
||||
this._stopSystemTime = undefined;
|
||||
} else if (this._startSystemTime === undefined){
|
||||
const systemNow = this.getSystemTime();
|
||||
this._startSystemTime = systemNow;
|
||||
this._pendingSliceStartStopwatchTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param recordPendingSlice
|
||||
*/
|
||||
public stop(recordPendingSlice: boolean = false){
|
||||
if (this._startSystemTime === undefined){
|
||||
return 0;
|
||||
}
|
||||
|
||||
const systemTimeOfStopwatchTime = this.getSystemTimeOfCurrentStopwatchTime();
|
||||
|
||||
if (recordPendingSlice){
|
||||
this.recordPendingSlice(this.caculateStopwatchTime(systemTimeOfStopwatchTime));
|
||||
}
|
||||
|
||||
this._stopSystemTime = systemTimeOfStopwatchTime;
|
||||
return this.getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束/记录当前挂起的片的私有实现。
|
||||
* @param endStopwatchTime
|
||||
* @param endStopwatchTime
|
||||
*/
|
||||
private recordPendingSlice(endStopwatchTime?: number){
|
||||
if (this._pendingSliceStartStopwatchTime !== undefined){
|
||||
if (endStopwatchTime === undefined){
|
||||
private recordPendingSlice(endStopwatchTime?: number) {
|
||||
if (this._pendingSliceStartStopwatchTime !== undefined) {
|
||||
if (endStopwatchTime === undefined) {
|
||||
endStopwatchTime = this.getTime();
|
||||
}
|
||||
|
||||
@@ -196,7 +197,7 @@ namespace stopwatch {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 返回某个系统的“当前时间”的函数。
|
||||
* 惟一的要求是,对该函数的每次调用都必须返回一个大于或等于前一次对该函数的调用的数字。
|
||||
|
||||
@@ -18,23 +18,19 @@ module es {
|
||||
public static readonly barPadding = 2;
|
||||
public static readonly autoAdjustDelay = 30;
|
||||
private static _instance;
|
||||
public static get Instance(): TimeRuler{
|
||||
if (!this._instance)
|
||||
this._instance = new TimeRuler();
|
||||
return this._instance;
|
||||
}
|
||||
private _frameKey = 'frame';
|
||||
private _logKey = 'log';
|
||||
|
||||
/** 每帧的日志 */
|
||||
private _logs: FrameLog[];
|
||||
/** 当前显示帧计数 */
|
||||
private sampleFrames: number;
|
||||
/** 获取/设置目标样本帧。 */
|
||||
public targetSampleFrames: number;
|
||||
/** 获取/设置计时器标尺宽度。 */
|
||||
public width: number;
|
||||
public enabled: true;
|
||||
/** */
|
||||
public showLog = false;
|
||||
private _frameKey = 'frame';
|
||||
private _logKey = 'log';
|
||||
/** 每帧的日志 */
|
||||
private _logs: FrameLog[];
|
||||
/** 当前显示帧计数 */
|
||||
private sampleFrames: number;
|
||||
/** TimerRuler画的位置。 */
|
||||
private _position: Vector2;
|
||||
/** 上一帧日志 */
|
||||
@@ -56,8 +52,6 @@ module es {
|
||||
* 为此,我们只需一直跟踪StartFrame调用的次数,直到Draw被调用。
|
||||
*/
|
||||
private _updateCount: number;
|
||||
/** */
|
||||
public showLog = false;
|
||||
private _frameAdjust: number;
|
||||
|
||||
constructor() {
|
||||
@@ -72,9 +66,10 @@ module es {
|
||||
this.onGraphicsDeviceReset();
|
||||
}
|
||||
|
||||
private onGraphicsDeviceReset() {
|
||||
let layout = new Layout();
|
||||
this._position = layout.place(new Vector2(this.width, TimeRuler.barHeight), 0, 0.01, Alignment.bottomCenter).location;
|
||||
public static get Instance(): TimeRuler {
|
||||
if (!this._instance)
|
||||
this._instance = new TimeRuler();
|
||||
return this._instance;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -244,7 +239,7 @@ module es {
|
||||
count += 1;
|
||||
egret.localStorage.setItem(this._logKey, count.toString());
|
||||
this.markers.forEach(markerInfo => {
|
||||
for (let i = 0; i < markerInfo.logs.length; ++i){
|
||||
for (let i = 0; i < markerInfo.logs.length; ++i) {
|
||||
markerInfo.logs[i].initialized = false;
|
||||
markerInfo.logs[i].snapMin = 0;
|
||||
markerInfo.logs[i].snapMax = 0;
|
||||
@@ -260,7 +255,7 @@ module es {
|
||||
});
|
||||
}
|
||||
|
||||
public render(position: Vector2 = this._position, width: number = this.width){
|
||||
public render(position: Vector2 = this._position, width: number = this.width) {
|
||||
egret.localStorage.setItem(this._frameKey, "0");
|
||||
|
||||
if (!this.showLog)
|
||||
@@ -269,22 +264,22 @@ module es {
|
||||
let height = 0;
|
||||
let maxTime = 0;
|
||||
this._prevLog.bars.forEach(bar => {
|
||||
if (bar.markCount > 0){
|
||||
if (bar.markCount > 0) {
|
||||
height += TimeRuler.barHeight + TimeRuler.barPadding * 2;
|
||||
maxTime = Math.max(maxTime, bar.markers[bar.markCount - 1].endTime);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
const frameSpan = 1 / 60 * 1000;
|
||||
let sampleSpan = this.sampleFrames * frameSpan;
|
||||
|
||||
if (maxTime > sampleSpan){
|
||||
if (maxTime > sampleSpan) {
|
||||
this._frameAdjust = Math.max(0, this._frameAdjust) + 1;
|
||||
}else{
|
||||
} else {
|
||||
this._frameAdjust = Math.min(0, this._frameAdjust) - 1;
|
||||
}
|
||||
|
||||
if (Math.max(this._frameAdjust) > TimeRuler.autoAdjustDelay){
|
||||
if (Math.max(this._frameAdjust) > TimeRuler.autoAdjustDelay) {
|
||||
this.sampleFrames = Math.min(TimeRuler.maxSampleFrames, this.sampleFrames);
|
||||
this.sampleFrames = Math.max(this.targetSampleFrames, (maxTime / frameSpan) + 1);
|
||||
|
||||
@@ -297,6 +292,11 @@ module es {
|
||||
|
||||
// TODO: draw
|
||||
}
|
||||
|
||||
private onGraphicsDeviceReset() {
|
||||
let layout = new Layout();
|
||||
this._position = layout.place(new Vector2(this.width, TimeRuler.barHeight), 0, 0.01, Alignment.bottomCenter).location;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -320,7 +320,7 @@ module es {
|
||||
public markerNests: number[] = new Array<number>(TimeRuler.maxNestCall);
|
||||
public nestCount: number = 0;
|
||||
|
||||
constructor(){
|
||||
constructor() {
|
||||
this.markers.fill(new Marker(), 0, TimeRuler.maxSamples);
|
||||
this.markerNests.fill(0, 0, TimeRuler.maxNestCall);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class ArrayUtils {
|
||||
/**
|
||||
* 执行冒泡排序
|
||||
* @param ary
|
||||
* @param ary
|
||||
* 算法参考 -- http://www.hiahia.org/datastructure/paixu/paixu8.3.1.1-1.htm
|
||||
*/
|
||||
public static bubbleSort(ary: number[]): void {
|
||||
@@ -24,7 +24,7 @@ class ArrayUtils {
|
||||
|
||||
/**
|
||||
* 执行插入排序
|
||||
* @param ary
|
||||
* @param ary
|
||||
*/
|
||||
public static insertionSort(ary: number[]): void {
|
||||
let len: number = ary.length;
|
||||
@@ -39,8 +39,8 @@ class ArrayUtils {
|
||||
|
||||
/**
|
||||
* 执行二分搜索
|
||||
* @param ary 搜索的数组(必须排序过)
|
||||
* @param value 需要搜索的值
|
||||
* @param ary 搜索的数组(必须排序过)
|
||||
* @param value 需要搜索的值
|
||||
* @return 返回匹配结果的数组索引
|
||||
*/
|
||||
public static binarySearch(ary: number[], value: number): number {
|
||||
@@ -59,8 +59,8 @@ class ArrayUtils {
|
||||
|
||||
/**
|
||||
* 返回匹配项的索引
|
||||
* @param ary
|
||||
* @param num
|
||||
* @param ary
|
||||
* @param num
|
||||
* @return 返回匹配项的索引
|
||||
*/
|
||||
public static findElementIndex(ary: any[], num: any): any {
|
||||
@@ -74,7 +74,7 @@ class ArrayUtils {
|
||||
|
||||
/**
|
||||
* 返回数组中最大值的索引
|
||||
* @param ary
|
||||
* @param ary
|
||||
* @return 返回数组中最大值的索引
|
||||
*/
|
||||
public static getMaxElementIndex(ary: number[]): number {
|
||||
@@ -88,10 +88,10 @@ class ArrayUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回数组中最小值的索引
|
||||
* @param ary
|
||||
* @return 返回数组中最小值的索引
|
||||
*/
|
||||
* 返回数组中最小值的索引
|
||||
* @param ary
|
||||
* @return 返回数组中最小值的索引
|
||||
*/
|
||||
public static getMinElementIndex(ary: number[]): number {
|
||||
let matchIndex: number = 0;
|
||||
let len: number = ary.length;
|
||||
@@ -104,8 +104,8 @@ class ArrayUtils {
|
||||
|
||||
/**
|
||||
* 返回一个"唯一性"数组
|
||||
* @param ary 需要唯一性的数组
|
||||
* @return 唯一性的数组
|
||||
* @param ary 需要唯一性的数组
|
||||
* @return 唯一性的数组
|
||||
* 比如: [1, 2, 2, 3, 4]
|
||||
* 返回: [1, 2, 3, 4]
|
||||
*/
|
||||
@@ -131,25 +131,24 @@ class ArrayUtils {
|
||||
* 比如数组A = [1, 2, 3, 4, 6]
|
||||
* 数组B = [0, 2, 1, 3, 4]
|
||||
* 返回[6, 0]
|
||||
* @param aryA
|
||||
* @param aryB
|
||||
* @param aryA
|
||||
* @param aryB
|
||||
* @return
|
||||
*/
|
||||
public static getDifferAry(aryA: number[], aryB: number[]): number[] {
|
||||
aryA = this.getUniqueAry(aryA);
|
||||
aryB = this.getUniqueAry(aryB);
|
||||
let ary: number[] = aryA.concat(aryB);
|
||||
let uObj: Object = new Object();
|
||||
let uObj: Object = {};
|
||||
let newAry: number[] = [];
|
||||
let count: number = ary.length;
|
||||
for (let j: number = 0; j < count; ++j) {
|
||||
if (!uObj[ary[j]]) {
|
||||
uObj[ary[j]] = new Object();
|
||||
uObj[ary[j]] = {};
|
||||
uObj[ary[j]].count = 0;
|
||||
uObj[ary[j]].key = ary[j];
|
||||
uObj[ary[j]].count++;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (uObj[ary[j]] instanceof Object) {
|
||||
uObj[ary[j]].count++;
|
||||
}
|
||||
@@ -165,9 +164,9 @@ class ArrayUtils {
|
||||
|
||||
/**
|
||||
* 交换数组元素
|
||||
* @param array 目标数组
|
||||
* @param index1 交换后的索引
|
||||
* @param index2 交换前的索引
|
||||
* @param array 目标数组
|
||||
* @param index1 交换后的索引
|
||||
* @param index2 交换前的索引
|
||||
*/
|
||||
public static swap(array: any[], index1: number, index2: number): void {
|
||||
let temp: any = array[index1];
|
||||
@@ -178,7 +177,7 @@ class ArrayUtils {
|
||||
|
||||
/**
|
||||
* 清除列表
|
||||
* @param ary 列表
|
||||
* @param ary 列表
|
||||
*/
|
||||
public static clearList(ary: any[]): void {
|
||||
if (!ary) return;
|
||||
@@ -190,7 +189,7 @@ class ArrayUtils {
|
||||
|
||||
/**
|
||||
* 克隆一个数组
|
||||
* @param ary 需要克隆的数组
|
||||
* @param ary 需要克隆的数组
|
||||
* @return 克隆的数组
|
||||
*/
|
||||
public static cloneList(ary: any[]): any[] {
|
||||
@@ -201,9 +200,9 @@ class ArrayUtils {
|
||||
|
||||
/**
|
||||
* 判断2个数组是否相同
|
||||
* @param ary1 数组1
|
||||
* @param ary2 数组2
|
||||
* @return 是否相同
|
||||
* @param ary1 数组1
|
||||
* @param ary2 数组2
|
||||
* @return 是否相同
|
||||
*/
|
||||
public static equals(ary1: number[], ary2: number[]): Boolean {
|
||||
if (ary1 == ary2) return true;
|
||||
@@ -219,8 +218,8 @@ class ArrayUtils {
|
||||
|
||||
/**
|
||||
* 根据索引插入元素,索引和索引后的元素都向后移动一位
|
||||
* @param index 插入索引
|
||||
* @param value 插入的元素
|
||||
* @param index 插入索引
|
||||
* @param value 插入的元素
|
||||
* @return 插入的元素 未插入则返回空
|
||||
*/
|
||||
public static insert(ary: any[], index: number, value: any): any {
|
||||
|
||||
@@ -4,7 +4,7 @@ class Base64Utils {
|
||||
private static _keyAll = Base64Utils._keyNum + Base64Utils._keyStr;
|
||||
/**
|
||||
* 加密
|
||||
* @param input
|
||||
* @param input
|
||||
*/
|
||||
public static encode = function (input) {
|
||||
let output = "";
|
||||
@@ -29,32 +29,12 @@ class Base64Utils {
|
||||
this._keyAll.charAt(enc3) + this._keyAll.charAt(enc4);
|
||||
}
|
||||
return this._keyStr.charAt(Math.floor((Math.random() * this._keyStr.length))) + output;
|
||||
}
|
||||
|
||||
private static _utf8_encode(string) {
|
||||
string = string.replace(/\r\n/g, "\n");
|
||||
let utftext = "";
|
||||
for (let n = 0; n < string.length; n++) {
|
||||
let c = string.charCodeAt(n);
|
||||
if (c < 128) {
|
||||
utftext += String.fromCharCode(c);
|
||||
} else if ((c > 127) && (c < 2048)) {
|
||||
utftext += String.fromCharCode((c >> 6) | 192);
|
||||
utftext += String.fromCharCode((c & 63) | 128);
|
||||
} else {
|
||||
utftext += String.fromCharCode((c >> 12) | 224);
|
||||
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
|
||||
utftext += String.fromCharCode((c & 63) | 128);
|
||||
}
|
||||
|
||||
}
|
||||
return utftext;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 解码
|
||||
* @param input
|
||||
* @param isNotStr
|
||||
* @param input
|
||||
* @param isNotStr
|
||||
*/
|
||||
public static decode(input, isNotStr: boolean = true) {
|
||||
let output = "";
|
||||
@@ -92,6 +72,26 @@ class Base64Utils {
|
||||
return output;
|
||||
}
|
||||
|
||||
private static _utf8_encode(string) {
|
||||
string = string.replace(/\r\n/g, "\n");
|
||||
let utftext = "";
|
||||
for (let n = 0; n < string.length; n++) {
|
||||
let c = string.charCodeAt(n);
|
||||
if (c < 128) {
|
||||
utftext += String.fromCharCode(c);
|
||||
} else if ((c > 127) && (c < 2048)) {
|
||||
utftext += String.fromCharCode((c >> 6) | 192);
|
||||
utftext += String.fromCharCode((c & 63) | 128);
|
||||
} else {
|
||||
utftext += String.fromCharCode((c >> 12) | 224);
|
||||
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
|
||||
utftext += String.fromCharCode((c & 63) | 128);
|
||||
}
|
||||
|
||||
}
|
||||
return utftext;
|
||||
}
|
||||
|
||||
private static _utf8_decode(utftext) {
|
||||
let string = "";
|
||||
let i = 0;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
module es {
|
||||
/** 各种辅助方法来辅助绘图 */
|
||||
export class DrawUtils {
|
||||
public static drawLine(shape: egret.Shape, start: Vector2, end: Vector2, color: number, thickness: number = 1){
|
||||
public static drawLine(shape: egret.Shape, start: Vector2, end: Vector2, color: number, thickness: number = 1) {
|
||||
this.drawLineAngle(shape, start, MathHelper.angleBetweenVectors(start, end), Vector2.distance(start, end), color, thickness);
|
||||
}
|
||||
|
||||
public static drawLineAngle(shape: egret.Shape, start: Vector2, radians: number, length: number, color: number, thickness = 1){
|
||||
public static drawLineAngle(shape: egret.Shape, start: Vector2, radians: number, length: number, color: number, thickness = 1) {
|
||||
shape.graphics.beginFill(color);
|
||||
shape.graphics.drawRect(start.x, start.y, 1, 1);
|
||||
shape.graphics.endFill();
|
||||
@@ -17,11 +17,11 @@ module es {
|
||||
shape.rotation = radians;
|
||||
}
|
||||
|
||||
public static drawHollowRect(shape: egret.Shape, rect: Rectangle, color: number, thickness = 1){
|
||||
public static drawHollowRect(shape: egret.Shape, rect: Rectangle, color: number, thickness = 1) {
|
||||
this.drawHollowRectR(shape, rect.x, rect.y, rect.width, rect.height, color, thickness);
|
||||
}
|
||||
|
||||
public static drawHollowRectR(shape: egret.Shape, x: number, y: number, width: number, height: number, color: number, thickness = 1){
|
||||
public static drawHollowRectR(shape: egret.Shape, x: number, y: number, width: number, height: number, color: number, thickness = 1) {
|
||||
let tl = new Vector2(x, y).round();
|
||||
let tr = new Vector2(x + width, y).round();
|
||||
let br = new Vector2(x + width, y + height).round();
|
||||
@@ -33,9 +33,9 @@ module es {
|
||||
this.drawLine(shape, bl, tl, color, thickness);
|
||||
}
|
||||
|
||||
public static drawPixel(shape: egret.Shape, position: Vector2, color: number, size: number = 1){
|
||||
public static drawPixel(shape: egret.Shape, position: Vector2, color: number, size: number = 1) {
|
||||
let destRect = new Rectangle(position.x, position.y, size, size);
|
||||
if (size != 1){
|
||||
if (size != 1) {
|
||||
destRect.x -= size * 0.5;
|
||||
destRect.y -= size * 0.5;
|
||||
}
|
||||
@@ -45,7 +45,7 @@ module es {
|
||||
shape.graphics.endFill();
|
||||
}
|
||||
|
||||
public static getColorMatrix(color: number): egret.ColorMatrixFilter{
|
||||
public static getColorMatrix(color: number): egret.ColorMatrixFilter {
|
||||
let colorMatrix = [
|
||||
1, 0, 0, 0, 0,
|
||||
0, 1, 0, 0, 0,
|
||||
|
||||
@@ -8,18 +8,19 @@ module es {
|
||||
/** 上下文 */
|
||||
public context: any;
|
||||
|
||||
constructor(func: Function, context: any){
|
||||
constructor(func: Function, context: any) {
|
||||
this.func = func;
|
||||
this.context = context;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于事件管理
|
||||
*/
|
||||
export class Emitter<T> {
|
||||
private _messageTable: Map<T, FuncPack[]>;
|
||||
|
||||
constructor(){
|
||||
constructor() {
|
||||
this._messageTable = new Map<T, FuncPack[]>();
|
||||
}
|
||||
|
||||
@@ -29,9 +30,9 @@ module es {
|
||||
* @param handler 监听函数
|
||||
* @param context 监听上下文
|
||||
*/
|
||||
public addObserver(eventType: T, handler: Function, context: any){
|
||||
public addObserver(eventType: T, handler: Function, context: any) {
|
||||
let list: FuncPack[] = this._messageTable.get(eventType);
|
||||
if (!list){
|
||||
if (!list) {
|
||||
list = [];
|
||||
this._messageTable.set(eventType, list);
|
||||
}
|
||||
@@ -46,7 +47,7 @@ module es {
|
||||
* @param eventType 事件类型
|
||||
* @param handler 事件函数
|
||||
*/
|
||||
public removeObserver(eventType: T, handler: Function){
|
||||
public removeObserver(eventType: T, handler: Function) {
|
||||
let messageData = this._messageTable.get(eventType);
|
||||
let index = messageData.findIndex(data => data.func == handler);
|
||||
if (index != -1)
|
||||
@@ -58,10 +59,10 @@ module es {
|
||||
* @param eventType 事件类型
|
||||
* @param data 事件数据
|
||||
*/
|
||||
public emit(eventType: T, data?: any){
|
||||
public emit(eventType: T, data?: any) {
|
||||
let list: FuncPack[] = this._messageTable.get(eventType);
|
||||
if (list){
|
||||
for (let i = list.length - 1; i >= 0; i --)
|
||||
if (list) {
|
||||
for (let i = list.length - 1; i >= 0; i--)
|
||||
list[i].func.call(list[i].context, data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
module es {
|
||||
export class GlobalManager {
|
||||
public _enabled: boolean;
|
||||
|
||||
/**
|
||||
* 如果true则启用了GlobalManager。
|
||||
* 状态的改变会导致调用OnEnabled/OnDisable
|
||||
*/
|
||||
public get enabled(){
|
||||
public get enabled() {
|
||||
return this._enabled;
|
||||
}
|
||||
|
||||
@@ -13,7 +15,7 @@ module es {
|
||||
* 状态的改变会导致调用OnEnabled/OnDisable
|
||||
* @param value
|
||||
*/
|
||||
public set enabled(value: boolean){
|
||||
public set enabled(value: boolean) {
|
||||
this.setEnabled(value);
|
||||
}
|
||||
|
||||
@@ -21,31 +23,33 @@ module es {
|
||||
* 启用/禁用这个GlobalManager
|
||||
* @param isEnabled
|
||||
*/
|
||||
public setEnabled(isEnabled: boolean){
|
||||
if (this._enabled != isEnabled){
|
||||
public setEnabled(isEnabled: boolean) {
|
||||
if (this._enabled != isEnabled) {
|
||||
this._enabled = isEnabled;
|
||||
if (this._enabled){
|
||||
if (this._enabled) {
|
||||
this.onEnabled();
|
||||
} else {
|
||||
this.onDisabled();
|
||||
}
|
||||
}
|
||||
}
|
||||
public _enabled: boolean;
|
||||
|
||||
/**
|
||||
* 此GlobalManager启用时调用
|
||||
*/
|
||||
public onEnabled(){}
|
||||
public onEnabled() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 此GlobalManager禁用时调用
|
||||
*/
|
||||
public onDisabled(){}
|
||||
public onDisabled() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 在frame .update之前调用每一帧
|
||||
*/
|
||||
public update(){}
|
||||
public update() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,12 @@ module es {
|
||||
public y = 0;
|
||||
public touchPoint: number = -1;
|
||||
public touchDown: boolean = false;
|
||||
public get position(){
|
||||
|
||||
public get position() {
|
||||
return new Vector2(this.x, this.y);
|
||||
}
|
||||
|
||||
public reset(){
|
||||
public reset() {
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.touchDown = false;
|
||||
@@ -19,55 +20,64 @@ module es {
|
||||
export class Input {
|
||||
private static _init: boolean = false;
|
||||
private static _previousTouchState: TouchState = new TouchState();
|
||||
private static _gameTouchs: TouchState[] = [];
|
||||
private static _resolutionOffset: Vector2 = new Vector2();
|
||||
private static _resolutionScale: Vector2 = Vector2.one;
|
||||
private static _touchIndex: number = 0;
|
||||
private static _totalTouchCount: number = 0;
|
||||
/** 返回第一个触摸点的坐标 */
|
||||
public static get touchPosition(){
|
||||
if (!this._gameTouchs[0])
|
||||
return Vector2.zero;
|
||||
return this._gameTouchs[0].position;
|
||||
}
|
||||
/** 获取最大触摸数 */
|
||||
public static get maxSupportedTouch(){
|
||||
return Core._instance.stage.maxTouches;
|
||||
}
|
||||
/**
|
||||
* 设置最大触摸数
|
||||
*/
|
||||
public static set maxSupportedTouch(value: number){
|
||||
Core._instance.stage.maxTouches = value;
|
||||
this.initTouchCache();
|
||||
}
|
||||
/** 获取缩放值 默认为1 */
|
||||
public static get resolutionScale(){
|
||||
return this._resolutionScale;
|
||||
}
|
||||
/** 当前触摸点数量 */
|
||||
public static get totalTouchCount(){
|
||||
return this._totalTouchCount;
|
||||
}
|
||||
|
||||
private static _gameTouchs: TouchState[] = [];
|
||||
|
||||
/**
|
||||
* 触摸列表 存放最大个数量触摸点信息
|
||||
* 可通过判断touchPoint是否为-1 来确定是否为有触摸
|
||||
* 通过判断touchDown 判断触摸点是否有按下
|
||||
*/
|
||||
public static get gameTouchs(){
|
||||
public static get gameTouchs() {
|
||||
return this._gameTouchs;
|
||||
}
|
||||
|
||||
private static _resolutionScale: Vector2 = Vector2.one;
|
||||
|
||||
/** 获取缩放值 默认为1 */
|
||||
public static get resolutionScale() {
|
||||
return this._resolutionScale;
|
||||
}
|
||||
|
||||
private static _totalTouchCount: number = 0;
|
||||
|
||||
/** 当前触摸点数量 */
|
||||
public static get totalTouchCount() {
|
||||
return this._totalTouchCount;
|
||||
}
|
||||
|
||||
/** 返回第一个触摸点的坐标 */
|
||||
public static get touchPosition() {
|
||||
if (!this._gameTouchs[0])
|
||||
return Vector2.zero;
|
||||
return this._gameTouchs[0].position;
|
||||
}
|
||||
|
||||
/** 获取最大触摸数 */
|
||||
public static get maxSupportedTouch() {
|
||||
return Core._instance.stage.maxTouches;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置最大触摸数
|
||||
*/
|
||||
public static set maxSupportedTouch(value: number) {
|
||||
Core._instance.stage.maxTouches = value;
|
||||
this.initTouchCache();
|
||||
}
|
||||
|
||||
/** 获取第一个触摸点距离上次距离的增量 */
|
||||
public static get touchPositionDelta(){
|
||||
public static get touchPositionDelta() {
|
||||
let delta = Vector2.subtract(this.touchPosition, this._previousTouchState.position);
|
||||
if (delta.length() > 0){
|
||||
if (delta.length() > 0) {
|
||||
this.setpreviousTouchState(this._gameTouchs[0]);
|
||||
}
|
||||
return delta;
|
||||
}
|
||||
|
||||
public static initialize(){
|
||||
public static initialize() {
|
||||
if (this._init)
|
||||
return;
|
||||
|
||||
@@ -81,67 +91,67 @@ module es {
|
||||
this.initTouchCache();
|
||||
}
|
||||
|
||||
private static initTouchCache(){
|
||||
public static scaledPosition(position: Vector2) {
|
||||
let scaledPos = new Vector2(position.x - this._resolutionOffset.x, position.y - this._resolutionOffset.y);
|
||||
return Vector2.multiply(scaledPos, this.resolutionScale);
|
||||
}
|
||||
|
||||
private static initTouchCache() {
|
||||
this._totalTouchCount = 0;
|
||||
this._touchIndex = 0;
|
||||
this._gameTouchs.length = 0;
|
||||
for (let i = 0; i < this.maxSupportedTouch; i ++){
|
||||
for (let i = 0; i < this.maxSupportedTouch; i++) {
|
||||
this._gameTouchs.push(new TouchState());
|
||||
}
|
||||
}
|
||||
|
||||
private static touchBegin(evt: egret.TouchEvent){
|
||||
if (this._touchIndex < this.maxSupportedTouch){
|
||||
private static touchBegin(evt: egret.TouchEvent) {
|
||||
if (this._touchIndex < this.maxSupportedTouch) {
|
||||
this._gameTouchs[this._touchIndex].touchPoint = evt.touchPointID;
|
||||
this._gameTouchs[this._touchIndex].touchDown = evt.touchDown;
|
||||
this._gameTouchs[this._touchIndex].x = evt.stageX;
|
||||
this._gameTouchs[this._touchIndex].y = evt.stageY;
|
||||
if (this._touchIndex == 0){
|
||||
if (this._touchIndex == 0) {
|
||||
this.setpreviousTouchState(this._gameTouchs[0]);
|
||||
}
|
||||
this._touchIndex ++;
|
||||
this._totalTouchCount ++;
|
||||
this._touchIndex++;
|
||||
this._totalTouchCount++;
|
||||
}
|
||||
}
|
||||
|
||||
private static touchMove(evt: egret.TouchEvent){
|
||||
if (evt.touchPointID == this._gameTouchs[0].touchPoint){
|
||||
private static touchMove(evt: egret.TouchEvent) {
|
||||
if (evt.touchPointID == this._gameTouchs[0].touchPoint) {
|
||||
this.setpreviousTouchState(this._gameTouchs[0]);
|
||||
}
|
||||
|
||||
let touchIndex = this._gameTouchs.findIndex(touch => touch.touchPoint == evt.touchPointID);
|
||||
if (touchIndex != -1){
|
||||
if (touchIndex != -1) {
|
||||
let touchData = this._gameTouchs[touchIndex];
|
||||
touchData.x = evt.stageX;
|
||||
touchData.y = evt.stageY;
|
||||
}
|
||||
}
|
||||
|
||||
private static touchEnd(evt: egret.TouchEvent){
|
||||
private static touchEnd(evt: egret.TouchEvent) {
|
||||
let touchIndex = this._gameTouchs.findIndex(touch => touch.touchPoint == evt.touchPointID);
|
||||
if (touchIndex != -1){
|
||||
if (touchIndex != -1) {
|
||||
let touchData = this._gameTouchs[touchIndex];
|
||||
touchData.reset();
|
||||
if (touchIndex == 0)
|
||||
this._previousTouchState.reset();
|
||||
this._totalTouchCount --;
|
||||
if (this.totalTouchCount == 0){
|
||||
this._totalTouchCount--;
|
||||
if (this.totalTouchCount == 0) {
|
||||
this._touchIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static setpreviousTouchState(touchState: TouchState){
|
||||
private static setpreviousTouchState(touchState: TouchState) {
|
||||
this._previousTouchState = new TouchState();
|
||||
this._previousTouchState.x = touchState.position.x;
|
||||
this._previousTouchState.y = touchState.position.y;
|
||||
this._previousTouchState.touchPoint = touchState.touchPoint;
|
||||
this._previousTouchState.touchDown = touchState.touchDown;
|
||||
}
|
||||
|
||||
public static scaledPosition(position: Vector2){
|
||||
let scaledPos = new Vector2(position.x - this._resolutionOffset.x, position.y - this._resolutionOffset.y);
|
||||
return Vector2.multiply(scaledPos, this.resolutionScale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,6 @@ class KeyboardUtils {
|
||||
*/
|
||||
public static TYPE_KEY_DOWN: number = 0;
|
||||
public static TYPE_KEY_UP: number = 1;
|
||||
|
||||
//存放按下注册数据的字典
|
||||
private static keyDownDict: Object;
|
||||
//存放按起注册数据的字典
|
||||
private static keyUpDict: Object;
|
||||
|
||||
/**
|
||||
* 键值字符串枚举
|
||||
*/
|
||||
@@ -39,7 +33,6 @@ class KeyboardUtils {
|
||||
public static X: string = "X";
|
||||
public static Y: string = "Y";
|
||||
public static Z: string = "Z";
|
||||
|
||||
public static ESC: string = "Esc";
|
||||
public static F1: string = "F1";
|
||||
public static F2: string = "F2";
|
||||
@@ -53,7 +46,6 @@ class KeyboardUtils {
|
||||
public static F10: string = "F10";
|
||||
public static F11: string = "F11";
|
||||
public static F12: string = "F12";
|
||||
|
||||
public static NUM_1: string = "1";
|
||||
public static NUM_2: string = "2";
|
||||
public static NUM_3: string = "3";
|
||||
@@ -64,7 +56,6 @@ class KeyboardUtils {
|
||||
public static NUM_8: string = "8";
|
||||
public static NUM_9: string = "9";
|
||||
public static NUM_0: string = "0";
|
||||
|
||||
public static TAB: string = "Tab";
|
||||
public static CTRL: string = "Ctrl";
|
||||
public static ALT: string = "Alt";
|
||||
@@ -73,25 +64,24 @@ class KeyboardUtils {
|
||||
public static ENTER: string = "Enter";
|
||||
public static SPACE: string = "Space";
|
||||
public static BACK_SPACE: string = "Back Space";
|
||||
|
||||
public static INSERT: string = "Insert";
|
||||
public static DELETE: string = "Page Down";
|
||||
public static HOME: string = "Home";
|
||||
public static END: string = "Page Down";
|
||||
public static PAGE_UP: string = "Page Up";
|
||||
public static PAGE_DOWN: string = "Page Down";
|
||||
|
||||
public static LEFT: string = "Left";
|
||||
public static RIGHT: string = "Right";
|
||||
public static UP: string = "Up";
|
||||
public static DOWN: string = "Down";
|
||||
|
||||
public static PAUSE_BREAK: string = "Pause Break";
|
||||
public static NUM_LOCK: string = "Num Lock";
|
||||
public static SCROLL_LOCK: string = "Scroll Lock";
|
||||
|
||||
public static WINDOWS: string = "Windows";
|
||||
|
||||
//存放按下注册数据的字典
|
||||
private static keyDownDict: Object;
|
||||
//存放按起注册数据的字典
|
||||
private static keyUpDict: Object;
|
||||
|
||||
public static init(): void {
|
||||
this.keyDownDict = {};
|
||||
@@ -100,6 +90,37 @@ class KeyboardUtils {
|
||||
document.addEventListener("keyup", this.onKeyUpHander);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册按键
|
||||
* @param key 键值
|
||||
* @param fun 回调方法
|
||||
* @param type 按键类型 TYPE_KEY_DOWN、TYPE_KEY_UP
|
||||
*/
|
||||
public static registerKey(key: string, fun: Function, thisObj: any, type: number = 0, ...args): void {
|
||||
var keyDict: Object = type ? this.keyUpDict : this.keyDownDict;
|
||||
keyDict[key] = {"fun": fun, args: args, "thisObj": thisObj};
|
||||
}
|
||||
|
||||
/**
|
||||
* 注销按键
|
||||
* @param key 键值
|
||||
* @param type 注销的类型
|
||||
*/
|
||||
public static unregisterKey(key: string, type: number = 0): void {
|
||||
var keyDict: Object = type ? this.keyUpDict : this.keyDownDict;
|
||||
delete keyDict[key];
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁方法
|
||||
*/
|
||||
public static destroy(): void {
|
||||
this.keyDownDict = null;
|
||||
this.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);
|
||||
@@ -112,7 +133,6 @@ class KeyboardUtils {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static onKeyUpHander(event: KeyboardEvent): void {
|
||||
if (!this.keyUpDict) return;
|
||||
var key: string = this.keyCodeToString(event.keyCode);
|
||||
@@ -125,33 +145,10 @@ class KeyboardUtils {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 注册按键
|
||||
* @param key 键值
|
||||
* @param fun 回调方法
|
||||
* @param type 按键类型 TYPE_KEY_DOWN、TYPE_KEY_UP
|
||||
*/
|
||||
public static registerKey(key: string, fun: Function, thisObj: any, type: number = 0, ...args): void {
|
||||
var keyDict: Object = type ? this.keyUpDict : this.keyDownDict;
|
||||
keyDict[key] = { "fun": fun, args: args, "thisObj": thisObj };
|
||||
}
|
||||
|
||||
/**
|
||||
* 注销按键
|
||||
* @param key 键值
|
||||
* @param type 注销的类型
|
||||
*/
|
||||
public static unregisterKey(key: string, type: number = 0): void {
|
||||
var keyDict: Object = type ? this.keyUpDict : this.keyDownDict;
|
||||
delete keyDict[key];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据keyCode或charCode获取相应的字符串代号
|
||||
* @param keyCode
|
||||
* @return 键盘所指字符串代号
|
||||
* @param keyCode
|
||||
* @return 键盘所指字符串代号
|
||||
*/
|
||||
private static keyCodeToString(keyCode: number): string {
|
||||
switch (keyCode) {
|
||||
@@ -225,15 +222,4 @@ class KeyboardUtils {
|
||||
return String.fromCharCode(keyCode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 销毁方法
|
||||
*/
|
||||
public static destroy(): void {
|
||||
this.keyDownDict = null;
|
||||
this.keyUpDict = null;
|
||||
document.removeEventListener("keydown", this.onKeyDonwHander);
|
||||
document.removeEventListener("keyup", this.onKeyUpHander);
|
||||
}
|
||||
}
|
||||
@@ -9,10 +9,10 @@ module es {
|
||||
* 预热缓存,使用最大的cacheCount对象填充缓存
|
||||
* @param cacheCount
|
||||
*/
|
||||
public static warmCache(cacheCount: number){
|
||||
public static warmCache(cacheCount: number) {
|
||||
cacheCount -= this._objectQueue.length;
|
||||
if (cacheCount > 0){
|
||||
for (let i = 0; i < cacheCount; i ++){
|
||||
if (cacheCount > 0) {
|
||||
for (let i = 0; i < cacheCount; i++) {
|
||||
this._objectQueue.unshift([]);
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ module es {
|
||||
* 将缓存修剪为cacheCount项目
|
||||
* @param cacheCount
|
||||
*/
|
||||
public static trimCache(cacheCount){
|
||||
public static trimCache(cacheCount) {
|
||||
while (cacheCount > this._objectQueue.length)
|
||||
this._objectQueue.shift();
|
||||
}
|
||||
@@ -30,7 +30,7 @@ module es {
|
||||
/**
|
||||
* 清除缓存
|
||||
*/
|
||||
public static clearCache(){
|
||||
public static clearCache() {
|
||||
this._objectQueue.length = 0;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ module es {
|
||||
* 将项推回堆栈
|
||||
* @param obj
|
||||
*/
|
||||
public static free<T>(obj: Array<T>){
|
||||
public static free<T>(obj: Array<T>) {
|
||||
this._objectQueue.unshift(obj);
|
||||
obj.length = 0;
|
||||
}
|
||||
|
||||
@@ -13,24 +13,25 @@ const nextTick = fn => {
|
||||
class LockUtils {
|
||||
private _keyX: string;
|
||||
private _keyY: string;
|
||||
constructor(key){
|
||||
|
||||
constructor(key) {
|
||||
this._keyX = `mutex_key_${key}_X`;
|
||||
this._keyY = `mutex_key_${key}_Y`;
|
||||
}
|
||||
|
||||
public lock(){
|
||||
public lock() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const fn = () => {
|
||||
setItem(this._keyX, THREAD_ID);
|
||||
if (!getItem(this._keyY) === null){
|
||||
if (!getItem(this._keyY) === null) {
|
||||
// restart
|
||||
nextTick(fn);
|
||||
}
|
||||
setItem(this._keyY, THREAD_ID);
|
||||
if (getItem(this._keyX) !== THREAD_ID){
|
||||
if (getItem(this._keyX) !== THREAD_ID) {
|
||||
// delay
|
||||
setTimeout(()=>{
|
||||
if (getItem(this._keyY) !== THREAD_ID){
|
||||
setTimeout(() => {
|
||||
if (getItem(this._keyY) !== THREAD_ID) {
|
||||
// restart
|
||||
nextTick(fn);
|
||||
return;
|
||||
|
||||
@@ -6,16 +6,16 @@ module es {
|
||||
public first: T;
|
||||
public second: T;
|
||||
|
||||
constructor(first: T, second: T){
|
||||
constructor(first: T, second: T) {
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
public clear(){
|
||||
public clear() {
|
||||
this.first = this.second = null;
|
||||
}
|
||||
|
||||
public equals(other: Pair<T>){
|
||||
public equals(other: Pair<T>) {
|
||||
return this.first == other.first && this.second == other.second;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,36 +43,32 @@ class RandomUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回 a - b之间的随机数,不包括 Math.max(a, b)
|
||||
* @param a
|
||||
* @param b
|
||||
* @return 假设 a < b, [a, b)
|
||||
*/
|
||||
* 返回 a - b之间的随机数,不包括 Math.max(a, b)
|
||||
* @param a
|
||||
* @param b
|
||||
* @return 假设 a < b, [a, b)
|
||||
*/
|
||||
public static randnum(a: number, b: number): number {
|
||||
return this.random() * (b - a) + a;
|
||||
}
|
||||
|
||||
/**
|
||||
* 打乱数组
|
||||
* @param array
|
||||
* @return
|
||||
*/
|
||||
* 打乱数组
|
||||
* @param array
|
||||
* @return
|
||||
*/
|
||||
public static shuffle(array: any[]): any[] {
|
||||
array.sort(this._randomCompare);
|
||||
return array;
|
||||
}
|
||||
|
||||
private static _randomCompare(a: Object, b: Object): number {
|
||||
return (this.random() > .5) ? 1 : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从序列中随机取一个元素
|
||||
* @param sequence 可以是 数组、 vector,等只要是有length属性,并且可以用数字索引获取元素的对象,
|
||||
* 另外,字符串也是允许的。
|
||||
* @return 序列中的某一个元素
|
||||
*
|
||||
*/
|
||||
* 从序列中随机取一个元素
|
||||
* @param sequence 可以是 数组、 vector,等只要是有length属性,并且可以用数字索引获取元素的对象,
|
||||
* 另外,字符串也是允许的。
|
||||
* @return 序列中的某一个元素
|
||||
*
|
||||
*/
|
||||
public static choice(sequence: any): any {
|
||||
if (!sequence.hasOwnProperty("length"))
|
||||
throw new Error('无法对此对象执行此操作');
|
||||
@@ -83,7 +79,6 @@ class RandomUtils {
|
||||
return sequence[index];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 对列表中的元素进行随机采æ ?
|
||||
* <pre>
|
||||
@@ -125,10 +120,14 @@ class RandomUtils {
|
||||
|
||||
/**
|
||||
* 计算概率
|
||||
* @param chance 概率
|
||||
* @param chance 概率
|
||||
* @return
|
||||
*/
|
||||
public static boolean(chance: number = .5): boolean {
|
||||
return (this.random() < chance) ? true : false;
|
||||
}
|
||||
|
||||
private static _randomCompare(a: Object, b: Object): number {
|
||||
return (this.random() > .5) ? 1 : -1;
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ module es {
|
||||
* @param first
|
||||
* @param point
|
||||
*/
|
||||
public static union(first: Rectangle, point: Vector2){
|
||||
public static union(first: Rectangle, point: Vector2) {
|
||||
let rect = new Rectangle(point.x, point.y, 0, 0);
|
||||
// let rectResult = first.union(rect);
|
||||
let result = new Rectangle();
|
||||
|
||||
@@ -11,12 +11,25 @@ module es {
|
||||
private _triPrev: number[] = new Array<number>(12);
|
||||
private _triNext: number[] = new Array<number>(12);
|
||||
|
||||
public static testPointTriangle(point: Vector2, a: Vector2, b: Vector2, c: Vector2): boolean {
|
||||
if (Vector2Ext.cross(Vector2.subtract(point, a), Vector2.subtract(b, a)) < 0)
|
||||
return false;
|
||||
|
||||
if (Vector2Ext.cross(Vector2.subtract(point, b), Vector2.subtract(c, b)) < 0)
|
||||
return false;
|
||||
|
||||
if (Vector2Ext.cross(Vector2.subtract(point, c), Vector2.subtract(a, c)) < 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算一个三角形列表,该列表完全覆盖给定点集所包含的区域。如果点不是CCW,则将arePointsCCW参数传递为false
|
||||
* @param points 定义封闭路径的点列表
|
||||
* @param arePointsCCW
|
||||
*/
|
||||
public triangulate(points: Vector2[], arePointsCCW: boolean = true){
|
||||
public triangulate(points: Vector2[], arePointsCCW: boolean = true) {
|
||||
let count = points.length;
|
||||
|
||||
// 设置前一个链接和下一个链接
|
||||
@@ -29,29 +42,29 @@ module es {
|
||||
let index = 0;
|
||||
|
||||
// 继续移除所有的三角形,直到只剩下一个三角形
|
||||
while (count > 3 && iterations < 500){
|
||||
iterations ++;
|
||||
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]];
|
||||
|
||||
if (Vector2Ext.isTriangleCCW(a, b, c)){
|
||||
if (Vector2Ext.isTriangleCCW(a, b, c)) {
|
||||
let k = this._triNext[this._triNext[index]];
|
||||
do {
|
||||
if (Triangulator.testPointTriangle(points[k], a, b, c)){
|
||||
if (Triangulator.testPointTriangle(points[k], a, b, c)) {
|
||||
isEar = false;
|
||||
break;
|
||||
}
|
||||
|
||||
k = this._triNext[k];
|
||||
} while (k != this._triPrev[index]);
|
||||
}else{
|
||||
} else {
|
||||
isEar = false;
|
||||
}
|
||||
|
||||
if (isEar){
|
||||
if (isEar) {
|
||||
this.triangleIndices.push(this._triPrev[index]);
|
||||
this.triangleIndices.push(index);
|
||||
this.triangleIndices.push(this._triNext[index]);
|
||||
@@ -59,11 +72,11 @@ module es {
|
||||
// 删除vert通过重定向相邻vert的上一个和下一个链接,从而减少vertext计数
|
||||
this._triNext[this._triPrev[index]] = this._triNext[index];
|
||||
this._triPrev[this._triNext[index]] = this._triPrev[index];
|
||||
count --;
|
||||
count--;
|
||||
|
||||
// 接下来访问前一个vert
|
||||
index = this._triPrev[index];
|
||||
}else{
|
||||
} else {
|
||||
index = this._triNext[index];
|
||||
}
|
||||
}
|
||||
@@ -76,19 +89,19 @@ module es {
|
||||
this.triangleIndices.reverse();
|
||||
}
|
||||
|
||||
private initialize(count: number){
|
||||
private initialize(count: number) {
|
||||
this.triangleIndices.length = 0;
|
||||
|
||||
if (this._triNext.length < count){
|
||||
if (this._triNext.length < count) {
|
||||
this._triNext.reverse();
|
||||
this._triNext = new Array<number>(Math.max(this._triNext.length * 2, count));
|
||||
}
|
||||
if (this._triPrev.length < count){
|
||||
if (this._triPrev.length < count) {
|
||||
this._triPrev.reverse();
|
||||
this._triPrev = new Array<number>(Math.max(this._triPrev.length * 2, count));
|
||||
}
|
||||
|
||||
for (let i = 0; i < count;i ++){
|
||||
for (let i = 0; i < count; i++) {
|
||||
this._triPrev[i] = i - 1;
|
||||
this._triNext[i] = i + 1;
|
||||
}
|
||||
@@ -96,18 +109,5 @@ module es {
|
||||
this._triPrev[0] = count - 1;
|
||||
this._triNext[count - 1] = 0;
|
||||
}
|
||||
|
||||
public static testPointTriangle(point: Vector2, a: Vector2, b: Vector2, c: Vector2): boolean{
|
||||
if (Vector2Ext.cross(Vector2.subtract(point, a), Vector2.subtract(b, a)) < 0)
|
||||
return false;
|
||||
|
||||
if (Vector2Ext.cross(Vector2.subtract(point, b), Vector2.subtract(c, b)) < 0)
|
||||
return false;
|
||||
|
||||
if (Vector2Ext.cross(Vector2.subtract(point, c), Vector2.subtract(a, c)) < 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ module es {
|
||||
*/
|
||||
public static transformA(sourceArray: Vector2[], sourceIndex: number, matrix: Matrix2D,
|
||||
destinationArray: Vector2[], destinationIndex: number, length: number) {
|
||||
for (let i = 0; i < length; i ++){
|
||||
for (let i = 0; i < length; i++) {
|
||||
let position = sourceArray[sourceIndex + i];
|
||||
let destination = destinationArray[destinationIndex + i];
|
||||
destination.x = (position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m31;
|
||||
@@ -64,7 +64,7 @@ module es {
|
||||
}
|
||||
}
|
||||
|
||||
public static transformR(position: Vector2, matrix: Matrix2D){
|
||||
public static transformR(position: Vector2, matrix: Matrix2D) {
|
||||
let x = (position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m31;
|
||||
let y = (position.x * matrix.m12) + (position.y * matrix.m22) + matrix.m32;
|
||||
return new Vector2(x, y);
|
||||
@@ -80,7 +80,7 @@ module es {
|
||||
this.transformA(sourceArray, 0, matrix, destinationArray, 0, sourceArray.length);
|
||||
}
|
||||
|
||||
public static round(vec: Vector2){
|
||||
public static round(vec: Vector2) {
|
||||
return new Vector2(Math.round(vec.x), Math.round(vec.y));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ class WebGLUtils {
|
||||
/**
|
||||
* 获取webgl context
|
||||
*/
|
||||
public static getContext(){
|
||||
public static getContext() {
|
||||
const canvas = document.getElementsByTagName('canvas')[0];
|
||||
return canvas.getContext('2d');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user