Merge pull request #13 from esengine/develop_collider

整理ecs框架
This commit is contained in:
YHH
2020-07-28 11:08:46 +08:00
committed by GitHub
123 changed files with 25567 additions and 19739 deletions
+2
View File
@@ -1,3 +1,5 @@
/source/node_modules /source/node_modules
/demo/bin-debug /demo/bin-debug
/demo/bin-release /demo/bin-release
/.idea
/.vscode
-15
View File
@@ -1,15 +0,0 @@
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "pwa-chrome",
"request": "launch",
"name": "Launch Chrome against localhost",
"url": "http://localhost:8080",
"webRoot": "${workspaceFolder}"
}
]
}
+2
View File
@@ -0,0 +1,2 @@
# Default ignored files
/workspace.xml
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
</project>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/demo.iml" filepath="$PROJECT_DIR$/.idea/demo.iml" />
</modules>
</component>
</project>
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>
+764 -419
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+1 -2
View File
@@ -11,12 +11,11 @@
"libs/long/long.js" "libs/long/long.js"
], ],
"game": [ "game": [
"bin-debug/game/CoreEmitterType.js",
"bin-debug/AssetAdapter.js", "bin-debug/AssetAdapter.js",
"bin-debug/LoadingUI.js",
"bin-debug/Main.js", "bin-debug/Main.js",
"bin-debug/Platform.js", "bin-debug/Platform.js",
"bin-debug/ThemeAdapter.js", "bin-debug/ThemeAdapter.js",
"bin-debug/LoadingUI.js",
"bin-debug/game/MainScene.js", "bin-debug/game/MainScene.js",
"bin-debug/game/PlayerController.js", "bin-debug/game/PlayerController.js",
"bin-debug/game/SimplePooled.js", "bin-debug/game/SimplePooled.js",
+15 -61
View File
@@ -27,71 +27,29 @@
// //
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
class Main extends es.Core {
class Main extends eui.UILayer { protected initialize() {
public static emitter: Emitter<CoreEmitterType>;
public static manager: SceneManager;
protected createChildren(): void {
super.createChildren();
egret.lifecycle.addLifecycleListener((context) => {
// custom lifecycle plugin
})
egret.lifecycle.onPause = () => {
egret.ticker.pause();
}
egret.lifecycle.onResume = () => {
egret.ticker.resume();
}
//inject the custom material parser
//注入自定义的素材解析器
let assetAdapter = new AssetAdapter();
egret.registerImplementation("eui.IAssetAdapter", assetAdapter);
egret.registerImplementation("eui.IThemeAdapter", new ThemeAdapter());
Main.manager = new SceneManager(this.stage);
Main.emitter = new Emitter<CoreEmitterType>();
this.addEventListener(egret.Event.ENTER_FRAME, this.updateFrame, this);
this.runGame(); this.runGame();
} }
private updateFrame(evt: egret.Event){ private runGame() {
Main.emitter.emit(CoreEmitterType.Update, evt); this.loadResource();
} }
private async runGame() {
await this.loadResource();
this.createGameScene();
}
private async loadResource() { private loadResource() {
try {
const loadingView = new LoadingUI(); const loadingView = new LoadingUI();
this.stage.addChild(loadingView); this.stage.addChild(loadingView);
await RES.loadConfig("resource/default.res.json", "resource/"); RES.loadConfig("resource/default.res.json", "resource/").then(()=>{
await this.loadTheme(); RES.loadGroup("preload", 0, loadingView).then(()=>{
await RES.loadGroup("preload", 0, loadingView);
this.stage.removeChild(loadingView); this.stage.removeChild(loadingView);
} this.createGameScene();
catch (e) { }).catch(err => {
console.error(e); console.error(err);
} });
} }).catch(err =>{
console.error(err);
private loadTheme() { });
return new Promise((resolve, reject) => {
// load skin theme configuration file, you can manually modify the file. And replace the default skin.
//加载皮肤主题配置文件,可以手动修改这个文件。替换默认皮肤。
let theme = new eui.Theme("resource/default.thm.json", this.stage);
theme.addEventListener(eui.UIEvent.COMPLETE, () => {
resolve();
}, this);
})
} }
/** /**
@@ -99,10 +57,6 @@ class Main extends eui.UILayer {
* Create scene interface * Create scene interface
*/ */
protected createGameScene(): void { protected createGameScene(): void {
SceneManager.scene = new MainScene(); es.Core.scene = new scene.MainScene();
// Main.emitter.addObserver(CoreEmitterType.Update, ()=>{
// console.log("update emitter");
// });
} }
} }
-3
View File
@@ -1,3 +0,0 @@
enum CoreEmitterType {
Update,
}
+28 -33
View File
@@ -1,4 +1,5 @@
class MainScene extends Scene { module scene {
export class MainScene extends es.Scene {
constructor() { constructor() {
super(); super();
@@ -9,26 +10,26 @@ class MainScene extends Scene {
} }
public async onStart() { public async onStart() {
let sprite = new Sprite(RES.getRes("checkbox_select_disabled_png")); let sprite = new es.Sprite(RES.getRes("checkbox_select_disabled_png"));
let bg = this.createEntity("bg"); let bg = this.createEntity("bg");
bg.addComponent(new SpriteRenderer()).setSprite(sprite).setColor(0xff0000); bg.addComponent(new es.SpriteRenderer()).setSprite(sprite).setColor(0xff0000);
bg.addComponent(new PlayerController()); bg.addComponent(new component.PlayerController());
bg.addComponent(new Mover()); bg.addComponent(new es.Mover());
bg.addComponent(new ScrollingSpriteRenderer(sprite)); bg.addComponent(new es.ScrollingSpriteRenderer(sprite));
bg.addComponent(new BoxCollider()); bg.addComponent(new es.BoxCollider());
bg.position = new Vector2(Math.random() * 200, Math.random() * 200); bg.position = new es.Vector2(Math.random() * 200, Math.random() * 200);
for (let i = 0; i < 20; i++) { for (let i = 0; i < 1; i++) {
let sprite = new Sprite(RES.getRes("checkbox_select_disabled_png")); let sprite = new es.Sprite(RES.getRes("checkbox_select_disabled_png"));
let player2 = this.createEntity("player2"); let player2 = this.createEntity("player2");
player2.addComponent(new SpriteRenderer()).setSprite(sprite); player2.addComponent(new es.SpriteRenderer()).setSprite(sprite);
player2.position = new Vector2(Math.random() * 1000, Math.random() * 1000); player2.position = new es.Vector2(Math.random() * 100, Math.random() * 100);
player2.addComponent(new BoxCollider()); player2.addComponent(new es.BoxCollider());
} }
this.camera.follow(bg, CameraStyle.lockOn); this.camera.follow(bg, es.CameraStyle.lockOn);
let pool = new ComponentPool<SimplePooled>(SimplePooled); let pool = new es.ComponentPool<component.SimplePooled>(component.SimplePooled);
let c1 = pool.obtain(); let c1 = pool.obtain();
let c2 = pool.obtain(); let c2 = pool.obtain();
pool.free(c1); pool.free(c1);
@@ -41,21 +42,14 @@ class MainScene extends Scene {
button.label = "切换场景"; button.label = "切换场景";
this.addChild(button); this.addChild(button);
button.addEventListener(egret.TouchEvent.TOUCH_TAP, () => { button.addEventListener(egret.TouchEvent.TOUCH_TAP, () => {
SceneManager.startSceneTransition(new FadeTransition(() => { es.Core.startSceneTransition(new es.FadeTransition(() => {
return new MainScene(); return new MainScene();
})); }));
}, this); }, this);
Main.emitter.addObserver(CoreEmitterType.Update, this.handleFuncTest, this);
}
/** 测试Emitter */
private handleFuncTest(){
Main.emitter.removeObserver(CoreEmitterType.Update, this.handleFuncTest);
} }
public breadthfirstTest() { public breadthfirstTest() {
let graph = new UnweightedGraph<string>(); let graph = new es.UnweightedGraph<string>();
graph.addEdgesForNode("a", ["b"]); // a->b graph.addEdgesForNode("a", ["b"]); // a->b
graph.addEdgesForNode("b", ["a", "c", "d"]); // b->a b->c b->d graph.addEdgesForNode("b", ["a", "c", "d"]); // b->a b->c b->d
@@ -64,24 +58,24 @@ class MainScene extends Scene {
graph.addEdgesForNode("e", ["b"]); // e->b graph.addEdgesForNode("e", ["b"]); // e->b
// 计算从c到e的路径 // 计算从c到e的路径
let path = BreadthFirstPathfinder.search(graph, "c", "e"); let path = es.BreadthFirstPathfinder.search(graph, "c", "e");
console.log(path); console.log(path);
} }
public dijkstraTest() { public dijkstraTest() {
let graph = new WeightedGridGraph(20, 20); let graph = new es.WeightedGridGraph(20, 20);
graph.weightedNodes.push(new Vector2(3, 3)); graph.weightedNodes.push(new es.Vector2(3, 3));
graph.weightedNodes.push(new Vector2(3, 4)); graph.weightedNodes.push(new es.Vector2(3, 4));
graph.weightedNodes.push(new Vector2(4, 3)); graph.weightedNodes.push(new es.Vector2(4, 3));
graph.weightedNodes.push(new Vector2(4, 4)); graph.weightedNodes.push(new es.Vector2(4, 4));
let path = graph.search(new Vector2(3, 4), new Vector2(15, 17)); let path = graph.search(new es.Vector2(3, 4), new es.Vector2(15, 17));
console.log(path); console.log(path);
} }
public astarTest() { public astarTest() {
let graph = new AstarGridGraph(30, 30); let graph = new es.AstarGridGraph(30, 30);
// graph.weightedNodes.push(new Vector2(3, 3)); // graph.weightedNodes.push(new Vector2(3, 3));
// graph.weightedNodes.push(new Vector2(3, 4)); // graph.weightedNodes.push(new Vector2(3, 4));
@@ -89,7 +83,8 @@ class MainScene extends Scene {
// graph.weightedNodes.push(new Vector2(4, 4)); // graph.weightedNodes.push(new Vector2(4, 4));
let startTime = egret.getTimer(); let startTime = egret.getTimer();
let path = graph.search(new Vector2(1, 1), new Vector2(29, 29)); let path = graph.search(new es.Vector2(1, 1), new es.Vector2(29, 29));
console.log(egret.getTimer() - startTime); console.log(egret.getTimer() - startTime);
} }
}
} }
+18 -8
View File
@@ -1,4 +1,13 @@
class PlayerController extends Component { module component {
import Component = es.Component;
import Vector2 = es.Vector2;
import Mover = es.Mover;
import SpriteRenderer = es.SpriteRenderer;
import Time = es.Time;
import Input = es.Input;
import CollisionResult = es.CollisionResult;
export class PlayerController extends Component {
private down: boolean = false; private down: boolean = false;
private touchPoint: Vector2 = Vector2.zero; private touchPoint: Vector2 = Vector2.zero;
private mover: Mover; private mover: Mover;
@@ -34,23 +43,24 @@ class PlayerController extends Component {
return; return;
if (this.down){ if (this.down){
let camera = SceneManager.scene.camera;
let moveLeft: number = 0; let moveLeft: number = 0;
let moveRight: number = 0; let moveRight: number = 0;
let speed = 100; let speed = 100;
let worldPos = Input.touchPosition; let worldPos = this.entity.scene.camera.mouseToWorldPoint();
if (worldPos.x < this.spriteRenderer.localPosition.x){ if (worldPos.x < this.spriteRenderer.transform.position.x){
moveLeft = -1; moveLeft = -1;
} else if(worldPos.x > this.spriteRenderer.localPosition.x){ } else if(worldPos.x > this.spriteRenderer.transform.position.x){
moveLeft = 1; moveLeft = 1;
} }
if (worldPos.y < this.spriteRenderer.localPosition.y){ if (worldPos.y < this.spriteRenderer.transform.position.y){
moveRight = -1; moveRight = -1;
} else if(worldPos.y > this.spriteRenderer.localPosition.y){ } else if(worldPos.y > this.spriteRenderer.transform.position.y){
moveRight = 1; moveRight = 1;
} }
this.mover.move(new Vector2(moveLeft * speed * Time.deltaTime, moveRight * speed * Time.deltaTime)); let collisionResult = new CollisionResult();
this.mover.move(new Vector2(moveLeft * speed * Time.deltaTime, moveRight * speed * Time.deltaTime), collisionResult);
}
} }
} }
} }
+5 -1
View File
@@ -1,5 +1,9 @@
class SimplePooled extends PooledComponent { module component {
import PooledComponent = es.PooledComponent;
export class SimplePooled extends PooledComponent {
public reset(){ public reset(){
} }
}
} }
+8 -6
View File
@@ -1,4 +1,5 @@
class SpawnComponent extends Component implements ITriggerListener { module component {
export class SpawnComponent extends es.Component implements es.ITriggerListener {
public cooldown = -1; public cooldown = -1;
public minInterval = 2; public minInterval = 2;
public maxInterval = 60; public maxInterval = 60;
@@ -19,17 +20,18 @@ class SpawnComponent extends Component implements ITriggerListener {
// console.log("update"); // console.log("update");
} }
public onTriggerEnter(other: Collider, local: Collider){ public onTriggerEnter(other: es.Collider, local: es.Collider){
if (other == local) if (other == local)
console.log("repeat collider") console.log("repeat collider");
console.log("enter collider"); console.log("enter collider");
} }
public onTriggerExit(other: Collider, local: Collider){ public onTriggerExit(other: es.Collider, local: es.Collider){
console.log("exit collider"); console.log("exit collider");
} }
} }
enum EnemyType { export enum EnemyType {
worm worm
}
} }
+7 -5
View File
@@ -1,10 +1,11 @@
class SpawnerSystem extends EntityProcessingSystem { module system {
constructor(matcher: Matcher){ export class SpawnerSystem extends es.EntityProcessingSystem {
constructor(matcher: es.Matcher){
super(matcher); super(matcher);
} }
public processEntity(entity: Entity){ public processEntity(entity: es.Entity){
let spawner = entity.getComponent<SpawnComponent>(SpawnComponent); let spawner = entity.getComponent<component.SpawnComponent>(component.SpawnComponent);
if (!spawner) if (!spawner)
return; return;
@@ -20,7 +21,7 @@ class SpawnerSystem extends EntityProcessingSystem {
spawner.cooldown /= 4; spawner.cooldown /= 4;
} }
spawner.cooldown -= Time.deltaTime; spawner.cooldown -= es.Time.deltaTime;
if (spawner.cooldown <= 0){ if (spawner.cooldown <= 0){
spawner.cooldown = Math.random() * 60; spawner.cooldown = Math.random() * 60;
// CreateEnemy // CreateEnemy
@@ -31,4 +32,5 @@ class SpawnerSystem extends EntityProcessingSystem {
spawner.enabled = false; spawner.enabled = false;
} }
} }
}
} }
+1
View File
@@ -2,6 +2,7 @@
"compilerOptions": { "compilerOptions": {
"target": "es5", "target": "es5",
"outDir": "bin-debug", "outDir": "bin-debug",
"sourceMap": true,
"experimentalDecorators": true, "experimentalDecorators": true,
"emitDecoratorMetadata": true, "emitDecoratorMetadata": true,
"lib": [ "lib": [
+764 -419
View File
File diff suppressed because it is too large Load Diff
+2993 -1595
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
File diff suppressed because one or more lines are too long
+122
View File
@@ -1008,7 +1008,129 @@ declare class Video {
*/ */
exitFullScreen(): Promise<void>; exitFullScreen(): Promise<void>;
} }
/**
*
*/
declare class Camera {
/**
*
*/
x: number;
/**
*
*/
y: number;
/**
*
*/
width: number;
/**
*
*/
height: number;
/**
*
*/
devicePosition: "front" | "back";
/**
*
*/
flash: "auto" | "on" | "off";
/**
*
*/
size: "small" | "medium" | "large";
/**
*
* @param quality
*/
takePhoto(quality?: "high" | "normal" | "low"): Promise<{
/**
*
*/
tempImagePath: string,
/**
*
*/
width: string,
/**
*
*/
height: string
}>;
/**
*
*/
startRecord(): Promise<void>;
/**
*
* @param compressed
*/
stopRecord(compressed: boolean): Promise<{
/**
*
*/
tempThumbPath: string,
/**
*
*/
tempVideoPath: string
}>;
/**
* 使
* @param callback
*/
onAuthCancel(callback: () => void): void;
/**
* 退
* @param callback
*/
onStop(callback: () => void): void;
/**
*
*/
onCameraFrame(callback: (res: {
/**
*
*/
width: number,
/**
*
*/
height: number,
/**
* rgba
*/
data: ArrayBuffer
}) => void): void;
/**
*
*/
listenFrameChange(): void;
/**
*
*/
closeFrameChange(): void;
/**
*
*/
destroy(): void;
}
/** /**
* banner 广banner 广 Canvas Canvas banner 广 BannerAd.show() banner 广 BannerAd.onResize() * banner 广banner 广 Canvas Canvas banner 广 BannerAd.show() banner 广 BannerAd.onResize()
*/ */
@@ -1,8 +1,9 @@
///<reference path="./PriorityQueueNode.ts" /> ///<reference path="./PriorityQueueNode.ts" />
/** module es {
/**
* IAstarGraph和开始/ * IAstarGraph和开始/
*/ */
class AStarPathfinder { export class AStarPathfinder {
/** /**
* null * null
* @param graph * @param graph
@@ -86,16 +87,17 @@ class AStarPathfinder {
return path; return path;
} }
} }
/** /**
* 使PriorityQueue需要的额外字段将原始数据封装在一个小类中 * 使PriorityQueue需要的额外字段将原始数据封装在一个小类中
*/ */
class AStarNode<T> extends PriorityQueueNode { export class AStarNode<T> extends PriorityQueueNode {
public data: T; public data: T;
constructor(data: T){ constructor(data: T){
super(); super();
this.data = data; this.data = data;
} }
}
} }
@@ -1,8 +1,9 @@
/** module es {
/**
* A*使 * A*使
* walls添加到walls HashSetweightedNodes * walls添加到walls HashSetweightedNodes
*/ */
class AstarGridGraph implements IAstarGraph<Vector2> { export class AstarGridGraph implements IAstarGraph<Vector2> {
public dirs: Vector2[] = [ public dirs: Vector2[] = [
new Vector2(1, 0), new Vector2(1, 0),
new Vector2(0, -1), new Vector2(0, -1),
@@ -69,4 +70,5 @@ class AstarGridGraph implements IAstarGraph<Vector2> {
return Math.abs(node.x - goal.x) + Math.abs(node.y - goal.y); return Math.abs(node.x - goal.x) + Math.abs(node.y - goal.y);
} }
}
} }
@@ -1,7 +1,8 @@
/** module es {
/**
* graph的接口AstarPathfinder.search方法 * graph的接口AstarPathfinder.search方法
*/ */
interface IAstarGraph<T> { export interface IAstarGraph<T> {
/** /**
* getNeighbors方法应该返回从传入的节点可以到达的任何相邻节点 * getNeighbors方法应该返回从传入的节点可以到达的任何相邻节点
* @param node * @param node
@@ -19,4 +20,5 @@ interface IAstarGraph<T> {
* @param goal * @param goal
*/ */
heuristic(node: T, goal: T); heuristic(node: T, goal: T);
}
} }
@@ -1,9 +1,10 @@
/** module es {
/**
* 使 O(1) * 使 O(1)
* 使5-10 * 使5-10
* IPriorityQueue.contains() * IPriorityQueue.contains()
*/ */
class PriorityQueue<T extends PriorityQueueNode> { export class PriorityQueue<T extends PriorityQueueNode> {
private _numNodes: number; private _numNodes: number;
private _nodes: T[]; private _nodes: T[];
private _numNodesEverEnqueued; private _numNodesEverEnqueued;
@@ -231,4 +232,5 @@ class PriorityQueue<T extends PriorityQueueNode> {
return (higher.priority < lower.priority || return (higher.priority < lower.priority ||
(higher.priority == lower.priority && higher.insertionIndex < lower.insertionIndex)); (higher.priority == lower.priority && higher.insertionIndex < lower.insertionIndex));
} }
}
} }
@@ -1,4 +1,5 @@
class PriorityQueueNode { module es {
export class PriorityQueueNode {
/** /**
* *
*/ */
@@ -11,4 +12,5 @@ class PriorityQueueNode {
* 使- * 使-
*/ */
public queueIndex: number = 0; public queueIndex: number = 0;
}
} }
@@ -1,7 +1,8 @@
/** module es {
/**
* IUnweightedGraph和开始/ * IUnweightedGraph和开始/
*/ */
class BreadthFirstPathfinder { 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 foundPath = false;
let frontier = []; let frontier = [];
@@ -38,4 +39,5 @@ class BreadthFirstPathfinder {
return false; return false;
} }
}
} }
@@ -1,7 +1,9 @@
interface IUnweightedGraph<T>{ module es {
export interface IUnweightedGraph<T>{
/** /**
* getNeighbors方法应该返回从传入的节点可以到达的任何相邻节点 * getNeighbors方法应该返回从传入的节点可以到达的任何相邻节点
* @param node * @param node
*/ */
getNeighbors(node: T): T[]; getNeighbors(node: T): T[];
}
} }
@@ -1,8 +1,9 @@
/** module es {
/**
* *
* *
*/ */
class UnweightedGraph<T> implements IUnweightedGraph<T> { export class UnweightedGraph<T> implements IUnweightedGraph<T> {
public edges: Map<T, T[]> = new Map<T, T[]>(); public edges: Map<T, T[]> = new Map<T, T[]>();
public addEdgesForNode(node: T, edges: T[]){ public addEdgesForNode(node: T, edges: T[]){
@@ -13,4 +14,5 @@ class UnweightedGraph<T> implements IUnweightedGraph<T> {
public getNeighbors(node: T){ public getNeighbors(node: T){
return this.edges.get(node); return this.edges.get(node);
} }
}
} }
@@ -1,8 +1,9 @@
///<reference path="../../../Math/Vector2.ts" /> ///<reference path="../../../Math/Vector2.ts" />
/** module es {
/**
* BreadthFirstPathfinder * BreadthFirstPathfinder
*/ */
class UnweightedGridGraph implements IUnweightedGraph<Vector2> { export class UnweightedGridGraph implements IUnweightedGraph<Vector2> {
private static readonly CARDINAL_DIRS: Vector2[] = [ private static readonly CARDINAL_DIRS: Vector2[] = [
new Vector2(1, 0), new Vector2(1, 0),
new Vector2(0, -1), new Vector2(0, -1),
@@ -58,4 +59,5 @@ class UnweightedGridGraph implements IUnweightedGraph<Vector2> {
public search(start: Vector2, goal: Vector2): Vector2[] { public search(start: Vector2, goal: Vector2): Vector2[] {
return BreadthFirstPathfinder.search(this, start, goal); return BreadthFirstPathfinder.search(this, start, goal);
} }
}
} }
@@ -1,4 +1,5 @@
interface IWeightedGraph<T>{ module es {
export interface IWeightedGraph<T>{
/** /**
* *
* @param node * @param node
@@ -11,4 +12,5 @@ interface IWeightedGraph<T>{
* @param to * @param to
*/ */
cost(from: T, to: T): number; cost(from: T, to: T): number;
}
} }
@@ -1,8 +1,9 @@
///<reference path="../../../Math/Vector2.ts" /> ///<reference path="../../../Math/Vector2.ts" />
/** module es {
/**
* *
*/ */
class WeightedGridGraph implements IWeightedGraph<Vector2> { export class WeightedGridGraph implements IWeightedGraph<Vector2> {
public static readonly CARDINAL_DIRS = [ public static readonly CARDINAL_DIRS = [
new Vector2(1, 0), new Vector2(1, 0),
new Vector2(0, -1), new Vector2(0, -1),
@@ -64,4 +65,5 @@ class WeightedGridGraph implements IWeightedGraph<Vector2> {
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; return this.weightedNodes.find(t => JSON.stringify(t) == JSON.stringify(to)) ? this.weightedNodeWeight : this.defaultWeight;
} }
}
} }
@@ -1,13 +1,14 @@
class WeightedNode<T> extends PriorityQueueNode { module es {
export class WeightedNode<T> extends PriorityQueueNode {
public data: T; public data: T;
constructor(data: T){ constructor(data: T){
super(); super();
this.data = data; this.data = data;
} }
} }
class WeightedPathfinder { 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 foundPath = false;
@@ -80,4 +81,5 @@ class WeightedPathfinder {
return path; return path;
} }
}
} }
+5 -3
View File
@@ -1,4 +1,5 @@
class Debug { module es {
export class Debug {
private static _debugDrawItems: DebugDrawItem[] = []; private static _debugDrawItems: DebugDrawItem[] = [];
public static drawHollowRect(rectanle: Rectangle, color: number, duration = 0){ public static drawHollowRect(rectanle: Rectangle, color: number, duration = 0){
@@ -8,8 +9,8 @@ class Debug {
public static render(){ public static render(){
if (this._debugDrawItems.length > 0){ if (this._debugDrawItems.length > 0){
let debugShape = new egret.Shape(); let debugShape = new egret.Shape();
if (SceneManager.scene){ if (Core.scene){
SceneManager.scene.addChild(debugShape); Core.scene.addChild(debugShape);
} }
for (let i = this._debugDrawItems.length - 1; i >= 0; i --){ for (let i = this._debugDrawItems.length - 1; i >= 0; i --){
@@ -19,4 +20,5 @@ class Debug {
} }
} }
} }
}
} }
+3 -1
View File
@@ -1,4 +1,6 @@
class DebugDefaults { module es {
export class DebugDefaults {
public static verletParticle = 0xDC345E; public static verletParticle = 0xDC345E;
public static verletConstraintEdge = 0x433E36; public static verletConstraintEdge = 0x433E36;
}
} }
+6 -3
View File
@@ -1,11 +1,12 @@
enum DebugDrawType { module es {
export enum DebugDrawType {
line, line,
hollowRectangle, hollowRectangle,
pixel, pixel,
text text
} }
class DebugDrawItem { export class DebugDrawItem {
public rectangle: Rectangle; public rectangle: Rectangle;
public color: number; public color: number;
public duration: number; public duration: number;
@@ -42,5 +43,7 @@ class DebugDrawItem {
this.duration -= Time.deltaTime; this.duration -= Time.deltaTime;
return this.duration < 0; return this.duration < 0;
} }
}
} }
+105 -64
View File
@@ -1,30 +1,114 @@
abstract class Component extends egret.DisplayObjectContainer { module es {
/**
*
* - onAddedToEntity
* - OnEnabled
*
*
* - onRemovedFromEntity
*/
export abstract class Component {
/**
*
*/
public entity: Entity; public entity: Entity;
private _enabled: boolean = true;
public updateInterval: number = 1;
/** 允许用户为实体存入信息 */
public userData: any;
private _updateOrder = 0;
public get enabled(){ /**
* 访 this.entity.transform
*/
public get transform(): Transform {
return this.entity.transform;
}
/**
* onEnabled/onDisable
*/
public get enabled() {
return this.entity ? this.entity.enabled && this._enabled : this._enabled; return this.entity ? this.entity.enabled && this._enabled : this._enabled;
} }
public set enabled(value: boolean){ /**
* onEnabled/onDisable
* @param value
*/
public set enabled(value: boolean) {
this.setEnabled(value); this.setEnabled(value);
} }
public get localPosition(){ /** 更新此实体上组件的顺序 */
return new Vector2(this.entity.x + this.x, this.entity.y + this.y); public get updateOrder() {
return this._updateOrder;
} }
public setEnabled(isEnabled: boolean){ /** 更新此实体上组件的顺序 */
if (this._enabled != isEnabled){ public set updateOrder(value: number) {
this.setUpdateOrder(value);
}
/**
*
*/
public updateInterval: number = 1;
private _enabled: boolean = true;
private _updateOrder = 0;
/**
* 西访
*/
public initialize() {
}
/**
*
*/
public onAddedToEntity() {
}
/**
*
*/
public onRemovedFromEntity() {
}
/**
*
* @param comp
*/
public onEntityTransformChanged(comp: transform.Component) {
}
/**
*
*/
public debugRender() {
}
/**
*
*/
public onEnabled() {
}
/**
*
*/
public onDisabled() {
}
/**
*
*/
public update() {
}
public setEnabled(isEnabled: boolean) {
if (this._enabled != isEnabled) {
this._enabled = isEnabled; this._enabled = isEnabled;
if (this._enabled){ if (this._enabled) {
this.onEnabled(); this.onEnabled();
}else{ } else {
this.onDisabled(); this.onDisabled();
} }
} }
@@ -32,65 +116,22 @@ abstract class Component extends egret.DisplayObjectContainer {
return this; return this;
} }
/** 更新此实体上组件的顺序 */ public setUpdateOrder(updateOrder: number) {
public get updateOrder(){ if (this._updateOrder != updateOrder) {
return this._updateOrder;
}
/** 更新此实体上组件的顺序 */
public set updateOrder(value: number){
this.setUpdateOrder(value);
}
public setUpdateOrder(updateOrder: number){
if (this._updateOrder != updateOrder){
this._updateOrder = updateOrder; this._updateOrder = updateOrder;
} }
return this; return this;
} }
public initialize(){
}
public onAddedToEntity(){
}
public onRemovedFromEntity(){
}
public onEnabled(){
}
public onDisabled(){
}
public debugRender(){
}
public update(){
}
/** /**
* *
* @param comp
*/ */
public onEntityTransformChanged(comp: TransformComponent){ public clone(): Component {
let component = ObjectUtils.clone<Component>(this);
component.entity = null;
return component;
} }
/** 内部使用 运行时不应该调用 */
public registerComponent(){
this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this), false);
this.entity.scene.entityProcessors.onComponentAdded(this.entity);
}
public deregisterComponent(){
this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this));
this.entity.scene.entityProcessors.onComponentRemoved(this.entity);
} }
} }
+363 -117
View File
@@ -1,32 +1,52 @@
class Camera extends Component { module es {
private _zoom; export enum CameraStyle {
private _origin: Vector2 = Vector2.zero; lockOn,
cameraWindow,
}
private _minimumZoom = 0.3; export class CameraInset {
private _maximumZoom = 3; public left: number = 0;
public right: number = 0;
public top: number = 0;
public bottom: number = 0;
}
private _position: Vector2 = Vector2.zero; export class Camera extends Component {
/** /**
* cameraWindow * entity.transform.position的快速访问
*
*/ */
public followLerp = 0.1; public get position() {
public deadzone: Rectangle = new Rectangle(); return this.entity.transform.position;
/** 锁定偏移量 默认中心 */ }
public focusOffset: Vector2 = new Vector2();
/** 是否地图锁定 如果锁定则需要设置mapSize属性 */
public mapLockEnabled: boolean = false;
/** 设置地图大小 默认从0 0左上角开始 只需要输入地图宽高 */
public mapSize: Vector2 = new Vector2();
/** 跟随的实体 设置后镜头将锁定目标为中心 */
public targetEntity: Entity;
private _worldSpaceDeadZone: Rectangle = new Rectangle();
private _desiredPositionDelta: Vector2 = new Vector2();
private _targetCollider: Collider;
/** 相机模式 */
public cameraStyle: CameraStyle = CameraStyle.lockOn;
public get zoom(){ /**
* entity.transform.position的快速访问
* @param value
*/
public set position(value: Vector2) {
this.entity.transform.position = value;
}
/**
* entity.transform.rotation的快速访问
*/
public get rotation(): number {
return this.entity.transform.rotation;
}
/**
* entity.transform.rotation的快速访问
* @param value
*/
public set rotation(value: number) {
this.entity.transform.rotation = value;
}
/**
* -11minimumZoom转换为maximumZoom
* /使-11
*/
public get zoom() {
if (this._zoom == 0) if (this._zoom == 0)
return 1; return 1;
@@ -36,73 +56,267 @@ class Camera extends Component {
return MathHelper.map(this._zoom, 1, this._maximumZoom, 0, 1); return MathHelper.map(this._zoom, 1, this._maximumZoom, 0, 1);
} }
public set zoom(value: number){ /**
* -11minimumZoom转换为maximumZoom
* /使-11
* @param value
*/
public set zoom(value: number) {
this.setZoom(value); this.setZoom(value);
} }
public get minimumZoom(){ /**
* 0-number.max0.3
*/
public get minimumZoom() {
return this._minimumZoom; return this._minimumZoom;
} }
public set minimumZoom(value: number){ /**
* 0-number.max0.3
* @param value
*/
public set minimumZoom(value: number) {
this.setMinimumZoom(value); this.setMinimumZoom(value);
} }
public get maximumZoom(){ /**
* 0-number.max3
*/
public get maximumZoom() {
return this._maximumZoom; return this._maximumZoom;
} }
public set maximumZoom(value: number){ /**
* 0-number.max3
* @param value
*/
public set maximumZoom(value: number) {
this.setMaximumZoom(value); this.setMaximumZoom(value);
} }
public get origin(){ /**
* -
*/
public get bounds(){
if (this._areMatrixedDirty)
this.updateMatrixes();
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){
// 特别注意旋转的边界。我们需要找到绝对的最小/最大值并从中创建边界
let topRight = this.screenToWorldPoint(new Vector2(Core.graphicsDevice.viewport.width - this._inset.right,
this._inset.top));
let bottomLeft = this.screenToWorldPoint(new Vector2(this._inset.left,
Core.graphicsDevice.viewport.height - this._inset.bottom));
let minX = Math.min(topLeft.x, bottomRight.x, topRight.x, bottomLeft.x);
let maxX = Math.max(topLeft.x, bottomRight.x, topRight.x, bottomLeft.x);
let minY = Math.min(topLeft.y, bottomRight.y, topRight.y, bottomLeft.y);
let maxY = Math.max(topLeft.y, bottomRight.y, topRight.y, bottomLeft.y);
this._bounds.location = new Vector2(minX, minY);
this._bounds.width = maxX - minX;
this._bounds.height = maxY - minY;
} else {
this._bounds.location = topLeft;
this._bounds.width = bottomRight.x - topLeft.x;
this._bounds.height = bottomRight.y - topLeft.y;
}
this._areBoundsDirty = false;
}
return this._bounds;
}
/**
*
*/
public get transformMatrix(): Matrix2D {
if (this._areMatrixedDirty)
this.updateMatrixes();
return this._transformMatrix;
}
/**
*
*/
public get inverseTransformMatrix(): Matrix2D {
if (this._areMatrixedDirty)
this.updateMatrixes();
return this._inverseTransformMatrix;
}
public get origin() {
return this._origin; return this._origin;
} }
public set origin(value: Vector2){ public set origin(value: Vector2) {
if (this._origin != value){ if (this._origin != value) {
this._origin = value; this._origin = value;
this._areMatrixedDirty = true;
} }
} }
public get position(){ public _zoom;
return this._position; 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 set position(value: Vector2){ public _areMatrixedDirty: boolean = true;
this._position = value; public _areBoundsDirty: boolean = true;
} public _isProjectionMatrixDirty = true;
public get x(){ /**
return this._position.x; * cameraWindow
} *
public set x(value: number){ */
this._position.x = value; public followLerp = 0.1;
} /**
public get y(){ * cameraWindow模式下/
return this._position.y; * lockOn模式下使deadZone的x/y值 setCenteredDeadzone重写它来自定义deadZone
} */
public set y(value: number){ public deadzone: Rectangle = new Rectangle();
this._position.y = value; /**
} *
*/
public focusOffset: Vector2 = Vector2.zero;
/**
* true 0, 0, mapwidth, mapheight
*/
public mapLockEnabled: boolean = false;
/**
*
*/
public mapSize: Vector2 = Vector2.zero;
constructor() { 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(); super();
this.width = SceneManager.stage.stageWidth; this._targetEntity = targetEntity;
this.height = SceneManager.stage.stageHeight; this._cameraStyle = cameraStyle;
this.setZoom(0); this.setZoom(0);
} }
public onSceneSizeChanged(newWidth: number, newHeight: number){ /**
*
* @param newWidth
* @param newHeight
*/
public onSceneSizeChanged(newWidth: number, newHeight: number) {
let oldOrigin = this._origin; let oldOrigin = this._origin;
this.origin = new Vector2(newWidth / 2, newHeight / 2); this.origin = new Vector2(newWidth / 2, newHeight / 2);
this.entity.position = Vector2.add(this.entity.position, Vector2.subtract(this._origin, oldOrigin)); 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
* @param right
* @param top
* @param bottom
*/
public setInset(left: number, right: number, top: number, bottom: number): Camera {
this._inset = new CameraInset();
this._inset.left = left;
this._inset.right = right;
this._inset.top = top;
this._inset.bottom = bottom;
this._areBoundsDirty = true;
return this;
}
/**
* entity.transform.setPosition快速访问
* @param position
*/
public setPosition(position: Vector2) {
this.entity.transform.setPosition(position.x, position.y);
return this;
}
/**
* entity.transform.setRotation的快速访问
* @param rotation
*/
public setRotation(rotation: number): Camera {
this.entity.transform.setRotation(rotation);
return this;
}
/**
* -11minimumZoom转换为maximumZoom
* /使-11
* @param zoom
*/
public setZoom(zoom: number): Camera {
let newZoom = MathHelper.clamp(zoom, -1, 1);
if (newZoom == 0) {
this._zoom = 1;
} else if (newZoom < 0) {
this._zoom = MathHelper.map(newZoom, -1, 0, this._minimumZoom, 1);
} else {
this._zoom = MathHelper.map(newZoom, 0, 1, 1, this._maximumZoom);
}
this._areMatrixedDirty = true;
return this;
}
/**
* 0-number.max 0.3
* @param minZoom
*/
public setMinimumZoom(minZoom: number): Camera {
if (minZoom <= 0) {
console.error("minimumZoom must be greater than zero");
return;
} }
public setMinimumZoom(minZoom: number): Camera{
if (this._zoom < minZoom) if (this._zoom < minZoom)
this._zoom = this.minimumZoom; this._zoom = this.minimumZoom;
@@ -110,7 +324,16 @@ class Camera extends Component {
return this; return this;
} }
/**
* 0-number.max 3
* @param maxZoom
*/
public setMaximumZoom(maxZoom: number): Camera { public setMaximumZoom(maxZoom: number): Camera {
if (maxZoom <= 0) {
console.error("maximumZoom must be greater than zero");
return;
}
if (this._zoom > maxZoom) if (this._zoom > maxZoom)
this._zoom = maxZoom; this._zoom = maxZoom;
@@ -118,117 +341,140 @@ class Camera extends Component {
return this; return this;
} }
public setZoom(zoom: number): Camera{ public onEntityTransformChanged(comp: transform.Component) {
let newZoom = MathHelper.clamp(zoom, -1, 1); this._areMatrixedDirty = true;
if (newZoom == 0){
this._zoom = 1;
} else if(newZoom < 0){
this._zoom = MathHelper.map(newZoom, -1, 0, this._minimumZoom, 1);
} else {
this._zoom = MathHelper.map(newZoom, 0, 1, 1, this._maximumZoom);
} }
SceneManager.scene.scaleX = this._zoom; public zoomIn(deltaZoom: number) {
SceneManager.scene.scaleY = this._zoom; this.zoom += deltaZoom;
return this;
} }
public setRotation(rotation: number): Camera { public zoomOut(deltaZoom: number) {
SceneManager.scene.rotation = rotation; this.zoom -= deltaZoom;
return this;
} }
public setPosition(position: Vector2){ /**
this.entity.position = position; *
* @param worldPosition
return this; */
public worldToScreenPoint(worldPosition: Vector2): Vector2{
this.updateMatrixes();
worldPosition = Vector2.transform(worldPosition, this._transformMatrix);
return worldPosition;
} }
public follow(targetEntity: Entity, cameraStyle: CameraStyle = CameraStyle.cameraWindow){ /**
this.targetEntity = targetEntity; *
this.cameraStyle = cameraStyle; * @param screenPosition
let cameraBounds = new Rectangle(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); */
public screenToWorldPoint(screenPosition: Vector2): Vector2{
switch (this.cameraStyle){ this.updateMatrixes();
case CameraStyle.cameraWindow: screenPosition = Vector2.transform(screenPosition, this._inverseTransformMatrix);
let w = cameraBounds.width / 6; return screenPosition;
let h = cameraBounds.height / 3;
this.deadzone = new Rectangle((cameraBounds.width - w) / 2, (cameraBounds.height - h) / 2, w, h);
break;
case CameraStyle.lockOn:
this.deadzone = new Rectangle(cameraBounds.width / 2, cameraBounds.height / 2, 10, 10);
break;
}
} }
public update(){ /**
let cameraBounds = new Rectangle(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); *
let halfScreen = Vector2.multiply(new Vector2(cameraBounds.width, cameraBounds.height), new Vector2(0.5)); */
this._worldSpaceDeadZone.x = this.position.x - halfScreen.x * SceneManager.scene.scaleX + this.deadzone.x + this.focusOffset.x; public mouseToWorldPoint(): Vector2{
this._worldSpaceDeadZone.y = this.position.y - halfScreen.y * SceneManager.scene.scaleY + this.deadzone.y + this.focusOffset.y; return this.screenToWorldPoint(Input.touchPosition);
}
public onAddedToEntity() {
this.follow(this._targetEntity, this._cameraStyle);
}
public update() {
let halfScreen = Vector2.multiply(new Vector2(this.bounds.width, this.bounds.height), new Vector2(0.5));
this._worldSpaceDeadZone.x = this.position.x - halfScreen.x * Core.scene.scaleX + this.deadzone.x + this.focusOffset.x;
this._worldSpaceDeadZone.y = this.position.y - halfScreen.y * Core.scene.scaleY + this.deadzone.y + this.focusOffset.y;
this._worldSpaceDeadZone.width = this.deadzone.width; this._worldSpaceDeadZone.width = this.deadzone.width;
this._worldSpaceDeadZone.height = this.deadzone.height; this._worldSpaceDeadZone.height = this.deadzone.height;
if (this.targetEntity) if (this._targetEntity)
this.updateFollow(); this.updateFollow();
this.position = Vector2.lerp(this.position, Vector2.add(this.position, this._desiredPositionDelta), this.followLerp); this.position = Vector2.lerp(this.position, Vector2.add(this.position, this._desiredPositionDelta), this.followLerp);
this.entity.roundPosition(); this.entity.transform.roundPosition();
if (this.mapLockEnabled){ if (this.mapLockEnabled) {
this.position = this.clampToMapSize(this.position); this.position = this.clampToMapSize(this.position);
this.entity.roundPosition(); this.entity.transform.roundPosition();
} }
} }
private clampToMapSize(position: Vector2){ /**
let cameraBounds = new Rectangle(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); *
let halfScreen = Vector2.multiply(new Vector2(cameraBounds.width, cameraBounds.height), new Vector2(0.5)); * @param position
*/
public clampToMapSize(position: Vector2) {
let halfScreen = Vector2.multiply(new Vector2(this.bounds.width, this.bounds.height), new Vector2(0.5));
let cameraMax = new Vector2(this.mapSize.x - halfScreen.x, this.mapSize.y - halfScreen.y); let cameraMax = new Vector2(this.mapSize.x - halfScreen.x, this.mapSize.y - halfScreen.y);
return Vector2.clamp(position, halfScreen, cameraMax); return Vector2.clamp(position, halfScreen, cameraMax);
} }
private updateFollow(){ public updateFollow() {
this._desiredPositionDelta.x = this._desiredPositionDelta.y = 0; this._desiredPositionDelta.x = this._desiredPositionDelta.y = 0;
if (this.cameraStyle == CameraStyle.lockOn){ if (this._cameraStyle == CameraStyle.lockOn) {
let targetX = this.targetEntity.position.x; let targetX = this._targetEntity.transform.position.x;
let targetY = this.targetEntity.position.y; let targetY = this._targetEntity.transform.position.y;
if (this._worldSpaceDeadZone.x > targetX) if (this._worldSpaceDeadZone.x > targetX)
this._desiredPositionDelta.x = targetX - this._worldSpaceDeadZone.x; this._desiredPositionDelta.x = targetX - this._worldSpaceDeadZone.x;
else if(this._worldSpaceDeadZone.x < targetX) else if (this._worldSpaceDeadZone.x < targetX)
this._desiredPositionDelta.x = targetX - this._worldSpaceDeadZone.x; this._desiredPositionDelta.x = targetX - this._worldSpaceDeadZone.x;
if (this._worldSpaceDeadZone.y < targetY) if (this._worldSpaceDeadZone.y < targetY)
this._desiredPositionDelta.y = targetY - this._worldSpaceDeadZone.y; this._desiredPositionDelta.y = targetY - this._worldSpaceDeadZone.y;
else if(this._worldSpaceDeadZone.y > targetY) else if (this._worldSpaceDeadZone.y > targetY)
this._desiredPositionDelta.y = targetY - this._worldSpaceDeadZone.y; this._desiredPositionDelta.y = targetY - this._worldSpaceDeadZone.y;
} else { } else {
if (!this._targetCollider){ if (!this._targetCollider) {
this._targetCollider = this.targetEntity.getComponent<Collider>(Collider); this._targetCollider = this._targetEntity.getComponent<Collider>(Collider);
if (!this._targetCollider) if (!this._targetCollider)
return; return;
} }
let targetBounds = this.targetEntity.getComponent<Collider>(Collider).bounds; let targetBounds = this._targetEntity.getComponent<Collider>(Collider).bounds;
if (!this._worldSpaceDeadZone.containsRect(targetBounds)){ if (!this._worldSpaceDeadZone.containsRect(targetBounds)) {
if (this._worldSpaceDeadZone.left > targetBounds.left) if (this._worldSpaceDeadZone.left > targetBounds.left)
this._desiredPositionDelta.x = targetBounds.left - this._worldSpaceDeadZone.left; this._desiredPositionDelta.x = targetBounds.left - this._worldSpaceDeadZone.left;
else if(this._worldSpaceDeadZone.right < targetBounds.right) else if (this._worldSpaceDeadZone.right < targetBounds.right)
this._desiredPositionDelta.x = targetBounds.right - this._worldSpaceDeadZone.right; this._desiredPositionDelta.x = targetBounds.right - this._worldSpaceDeadZone.right;
if (this._worldSpaceDeadZone.bottom < targetBounds.bottom) if (this._worldSpaceDeadZone.bottom < targetBounds.bottom)
this._desiredPositionDelta.y = targetBounds.bottom - this._worldSpaceDeadZone.bottom; this._desiredPositionDelta.y = targetBounds.bottom - this._worldSpaceDeadZone.bottom;
else if(this._worldSpaceDeadZone.top > targetBounds.top) else if (this._worldSpaceDeadZone.top > targetBounds.top)
this._desiredPositionDelta.y = targetBounds.top - this._worldSpaceDeadZone.top; this._desiredPositionDelta.y = targetBounds.top - this._worldSpaceDeadZone.top;
} }
} }
} }
}
enum CameraStyle { public follow(targetEntity: Entity, cameraStyle: CameraStyle = CameraStyle.cameraWindow) {
lockOn, this._targetEntity = targetEntity;
cameraWindow, this._cameraStyle = cameraStyle;
switch (this._cameraStyle) {
case CameraStyle.cameraWindow:
let w = this.bounds.width / 6;
let h = this.bounds.height / 3;
this.deadzone = new Rectangle((this.bounds.width - w) / 2, (this.bounds.height - h) / 2, w, h);
break;
case CameraStyle.lockOn:
this.deadzone = new Rectangle(this.bounds.width / 2, this.bounds.height / 2, 10, 10);
break;
}
}
/**
*
* @param width
* @param height
*/
public setCenteredDeadzone(width: number, height: number) {
this.deadzone = new Rectangle((this.bounds.width - width) / 2, (this.bounds.height - height) / 2, width, height);
}
}
} }
+3 -1
View File
@@ -1,4 +1,5 @@
class ComponentPool<T extends PooledComponent>{ module es {
export class ComponentPool<T extends PooledComponent>{
private _cache: T[]; private _cache: T[];
private _type: any; private _type: any;
@@ -19,4 +20,5 @@ class ComponentPool<T extends PooledComponent>{
component.reset(); component.reset();
this._cache.push(component); this._cache.push(component);
} }
}
} }
@@ -0,0 +1,10 @@
module es {
/**
*
*/
export class IUpdatableComparer {
public compare(a: Component, b: Component){
return a.updateOrder - b.updateOrder;
}
}
}
+6 -14
View File
@@ -1,5 +1,6 @@
///<reference path="./RenderableComponent.ts" /> ///<reference path="./RenderableComponent.ts" />
class Mesh extends RenderableComponent { module es {
export class Mesh extends RenderableComponent {
private _mesh: egret.Mesh; private _mesh: egret.Mesh;
constructor(){ constructor(){
@@ -14,19 +15,10 @@ class Mesh extends RenderableComponent {
return this; return this;
} }
public onAddedToEntity(){
this.addChild(this._mesh);
}
public onRemovedFromEntity(){
this.removeChild(this._mesh);
}
public render(camera: Camera){
this.x = this.entity.position.x - camera.position.x + camera.origin.x;
this.y = this.entity.position.y - camera.position.y + camera.origin.y;
}
public reset() { public reset() {
} }
render(camera: es.Camera) {
}
}
} }
@@ -1,5 +1,6 @@
///<reference path="./Collider.ts" /> ///<reference path="./Collider.ts" />
class BoxCollider extends Collider { module es {
export class BoxCollider extends Collider {
public get width(){ public get width(){
return (this.shape as Box).width; return (this.shape as Box).width;
} }
@@ -8,6 +9,43 @@ class BoxCollider extends Collider {
this.setWidth(value); this.setWidth(value);
} }
public get height(){
return (this.shape as Box).height;
}
public set height(value: number){
this.setHeight(value);
}
/**
* RenderableComponent在实体上
*/
constructor(){
super();
// 我们在这里插入一个1x1框作为占位符,直到碰撞器在下一阵被添加到实体并可以获得更精确的自动调整大小数据
this.shape = new Box(1, 1);
this._colliderRequiresAutoSizing = true;
}
/**
* BoxCollider的大小
* @param width
* @param height
*/
public setSize(width: number, height: number){
this._colliderRequiresAutoSizing = false;
let box = this.shape as Box;
if (width != box.width || height != box.height){
// 更新框,改变边界,如果我们需要更新物理系统中的边界
box.updateBox(width, height);
if (this.entity && this._isParentEntityAddedToScene)
Physics.updateCollider(this);
}
return this;
}
/** /**
* BoxCollider的宽度 * BoxCollider的宽度
* @param width * @param width
@@ -25,14 +63,6 @@ class BoxCollider extends Collider {
return this; return this;
} }
public get height(){
return (this.shape as Box).height;
}
public set height(value: number){
this.setHeight(value);
}
/** /**
* BoxCollider的高度 * BoxCollider的高度
* @param height * @param height
@@ -48,27 +78,8 @@ class BoxCollider extends Collider {
} }
} }
/** public toString(){
* RenderableComponent在实体上 return `[BoxCollider: bounds: ${this.bounds}]`;
*/
constructor(){
super();
// 我们在这里插入一个1x1框作为占位符,直到碰撞器在下一阵被添加到实体并可以获得更精确的自动调整大小数据
this.shape = new Box(1, 1);
this._colliderRequiresAutoSizing = true;
} }
public setSize(width: number, height: number){
this._colliderRequiresAutoSizing = false;
let box = this.shape as Box;
if (width != box.width || height != box.height){
// 更新框,改变边界,如果我们需要更新物理系统中的边界
box.updateBox(width, height);
if (this.entity && this._isParentEntityAddedToScene)
Physics.updateCollider(this);
}
return this;
} }
} }
@@ -1,8 +1,10 @@
class CircleCollider extends Collider { module es {
public get radius(): number{ export class CircleCollider extends Collider {
public get radius(): number {
return (this.shape as Circle).radius; return (this.shape as Circle).radius;
} }
public set radius(value: number){
public set radius(value: number) {
this.setRadius(value); this.setRadius(value);
} }
@@ -11,7 +13,7 @@ class CircleCollider extends Collider {
* *
* @param radius * @param radius
*/ */
constructor(radius?: number){ constructor(radius?: number) {
super(); super();
if (radius) if (radius)
@@ -25,10 +27,10 @@ class CircleCollider extends Collider {
* *
* @param radius * @param radius
*/ */
public setRadius(radius: number): CircleCollider{ public setRadius(radius: number): CircleCollider {
this._colliderRequiresAutoSizing = false; this._colliderRequiresAutoSizing = false;
let circle = this.shape as Circle; let circle = this.shape as Circle;
if (radius != circle.radius){ if (radius != circle.radius) {
circle.radius = radius; circle.radius = radius;
circle._originalRadius = radius; circle._originalRadius = radius;
@@ -38,4 +40,9 @@ class CircleCollider extends Collider {
return this; return this;
} }
public toString() {
return `[CircleCollider: bounds: ${this.bounds}, radius: ${(this.shape as Circle).radius}]`
}
}
} }
@@ -1,51 +1,182 @@
abstract class Collider extends Component { module es {
/** 对撞机的基本形状 */ export abstract class Collider extends Component {
public shape: Shape;
/** 在处理冲突时,physicsLayer可以用作过滤器。Flags类有帮助位掩码的方法。 */
public physicsLayer = 1 << 0;
/** 如果这个碰撞器是一个触发器,它将不会引起碰撞,但它仍然会触发事件 */
public isTrigger: boolean;
/** /**
* *
* 使
*/ */
public registeredPhysicsBounds: Rectangle = new Rectangle(); public shape: Shape;
/** 如果为true,碰撞器将根据附加的变换缩放和旋转 */
public shouldColliderScaleAndRotateWithTransform = true;
/** 默认为所有层。 */
public collidesWithLayers = Physics.allLayers;
public _localOffsetLength: number; /**
/** 标记来跟踪我们的实体是否被添加到场景中 */ * localOffset添加到实体
protected _isParentEntityAddedToScene; * /
protected _colliderRequiresAutoSizing; */
protected _localOffset: Vector2 = new Vector2(0, 0); public get localOffset(): Vector2 {
/** 标记来记录我们是否注册了物理系统 */
protected _isColliderRegistered;
public get bounds(): Rectangle {
this.shape.recalculateBounds(this);
return this.shape.bounds;
}
public get localOffset() {
return this._localOffset; return this._localOffset;
} }
/** /**
* localOffset添加到实体 * localOffset添加到实体
* /
* @param value
*/ */
public set localOffset(value: Vector2) { public set localOffset(value: Vector2) {
this.setLocalOffset(value); this.setLocalOffset(value);
} }
public setLocalOffset(offset: Vector2) { /**
*
*/
public get absolutePosition(): Vector2 {
return Vector2.add(this.entity.transform.position, this._localOffset);
}
/**
* transform.rotation
*/
public get rotation(): number {
if (this.shouldColliderScaleAndRotateWithTransform && this.entity)
return this.entity.transform.rotation;
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){
this.shape.recalculateBounds(this);
this._isPositionDirty = this._isRotationDirty = false;
}
return this.shape.bounds;
}
/**
*
* 使
*/
public registeredPhysicsBounds: Rectangle = new Rectangle();
protected _colliderRequiresAutoSizing;
protected _localOffset: Vector2 = Vector2.zero;
public _localOffsetLength: number;
/**
*
*/
protected _isParentEntityAddedToScene;
/**
*
*/
protected _isColliderRegistered;
public _isPositionDirty: boolean = true;
public _isRotationDirty: boolean = true;
/**
* localOffset添加到实体
*
* @param offset
*/
public setLocalOffset(offset: Vector2): Collider {
if (this._localOffset != offset) { if (this._localOffset != offset) {
this.unregisterColliderWithPhysicsSystem(); this.unregisterColliderWithPhysicsSystem();
this._localOffset = offset; this._localOffset = offset;
this._localOffsetLength = this._localOffset.length(); this._localOffsetLength = this._localOffset.length();
this._isPositionDirty = true;
this.registerColliderWithPhysicsSystem(); this.registerColliderWithPhysicsSystem();
} }
return this;
}
/**
* true
* @param shouldColliderScaleAndRotationWithTransform
*/
public setShouldColliderScaleAndRotateWithTransform(shouldColliderScaleAndRotationWithTransform: boolean): Collider {
this.shouldColliderScaleAndRotateWithTransform = shouldColliderScaleAndRotationWithTransform;
this._isPositionDirty = this._isRotationDirty = true;
return this;
}
public onAddedToEntity() {
if (this._colliderRequiresAutoSizing) {
if (!(this instanceof BoxCollider || this instanceof CircleCollider)) {
console.error("Only box and circle colliders can be created automatically");
return;
}
let renderable = this.entity.getComponent<RenderableComponent>(RenderableComponent);
if (renderable) {
let renderableBounds = renderable.bounds;
// 这里我们需要大小*反尺度,因为当我们自动调整碰撞器的大小时,它需要没有缩放的渲染
let width = renderableBounds.width / this.entity.scale.x;
let height = renderableBounds.height / this.entity.scale.y;
// 圆碰撞器需要特别注意原点
if (this instanceof CircleCollider) {
this.radius = Math.max(width, height) * 0.5;
} else {
this.width = width;
this.height = height;
}
// 获取渲染的中心,将其转移到本地坐标,并使用它作为碰撞器的localOffset
this.localOffset = Vector2.subtract(renderableBounds.center, this.entity.transform.position);
} else {
console.warn("Collider has no shape and no RenderableComponent. Can't figure out how to size it.");
}
}
this._isParentEntityAddedToScene = true;
this.registerColliderWithPhysicsSystem();
}
public onRemovedFromEntity() {
this.unregisterColliderWithPhysicsSystem();
this._isParentEntityAddedToScene = false;
}
public onEntityTransformChanged(comp: transform.Component) {
switch (comp) {
case transform.Component.position:
this._isPositionDirty = true;
break;
case transform.Component.scale:
this._isPositionDirty = true;
break;
case transform.Component.rotation:
this._isRotationDirty = true;
break;
}
if (this._isColliderRegistered)
Physics.updateCollider(this);
}
public onEnabled() {
this.registerColliderWithPhysicsSystem();
this._isPositionDirty = this._isRotationDirty = true;
}
public onDisabled() {
this.unregisterColliderWithPhysicsSystem();
} }
/** /**
@@ -73,7 +204,7 @@ abstract class Collider extends Component {
* *
* @param other * @param other
*/ */
public overlaps(other: Collider) { public overlaps(other: Collider): boolean {
return this.shape.overlaps(other.shape); return this.shape.overlaps(other.shape);
} }
@@ -81,81 +212,31 @@ abstract class Collider extends Component {
* ()true * ()true
* @param collider * @param collider
* @param motion * @param motion
* @param result
*/ */
public collidesWith(collider: Collider, motion: Vector2) { public collidesWith(collider: Collider, motion: Vector2, result: CollisionResult): boolean {
// 改变形状的位置,使它在移动后的位置,这样我们可以检查重叠 // 改变形状的位置,使它在移动后的位置,这样我们可以检查重叠
let oldPosition = this.shape.position; let oldPosition = this.entity.position;
this.shape.position = Vector2.add(this.shape.position, motion); this.entity.position = this.entity.position.add(motion);
let result = this.shape.collidesWithShape(collider.shape); let didCollide = this.shape.collidesWithShape(collider.shape, result);
if (result) if (didCollide)
result.collider = collider; result.collider = collider;
// 将图形位置返回到检查前的位置 // 将图形位置返回到检查前的位置
this.shape.position = oldPosition; this.entity.position = oldPosition;
return result; return didCollide;
} }
public onAddedToEntity() { public clone(): Component{
if (this._colliderRequiresAutoSizing) { let collider = ObjectUtils.clone<Collider>(this);
if (!(this instanceof BoxCollider || this instanceof CircleCollider)) { collider.entity = null;
console.error("Only box and circle colliders can be created automatically");
}
let renderable = this.entity.getComponent<RenderableComponent>(RenderableComponent); if (this.shape)
if (renderable) { collider.shape = this.shape.clone();
let bounds = renderable.bounds;
// 这里我们需要大小*反尺度,因为当我们自动调整碰撞器的大小时,它需要没有缩放的渲染 return collider;
let width = bounds.width / this.entity.scale.x;
let height = bounds.height / this.entity.scale.y;
// 圆碰撞器需要特别注意原点
if (this instanceof CircleCollider){
let circleCollider = this as CircleCollider;
circleCollider.radius = Math.max(width, height) * 0.5;
this.localOffset = bounds.location;
} else {
let boxCollider = this;
boxCollider.width = width;
boxCollider.height = height;
this.localOffset = bounds.location;
}
} else {
console.warn("Collider has no shape and no RenderableComponent. Can't figure out how to size it.");
}
}
this._isParentEntityAddedToScene = true;
this.registerColliderWithPhysicsSystem();
}
public onRemovedFromEntity() {
this.unregisterColliderWithPhysicsSystem();
this._isParentEntityAddedToScene = false;
}
public onEnabled() {
this.registerColliderWithPhysicsSystem();
}
public onDisabled() {
this.unregisterColliderWithPhysicsSystem();
}
public onEntityTransformChanged(comp: TransformComponent) {
if (this._isColliderRegistered)
Physics.updateCollider(this);
}
public update(){
let renderable = this.entity.getComponent<RenderableComponent>(RenderableComponent);
if (renderable){
this.$setX(renderable.x + this.localOffset.x);
this.$setY(renderable.y + this.localOffset.y);
} }
} }
} }
@@ -1,12 +1,13 @@
/** module es {
/**
* *
*/ */
class PolygonCollider extends Collider { export class PolygonCollider extends Collider {
/** /**
* localOffset的差异为居中 * localOffset的差异为居中
* @param points * @param points
*/ */
constructor(points: Vector2[]){ constructor(points: Vector2[]) {
super(); super();
// 第一点和最后一点决不能相同。我们想要一个开放的多边形 // 第一点和最后一点决不能相同。我们想要一个开放的多边形
@@ -21,4 +22,5 @@ class PolygonCollider extends Collider {
Polygon.recenterPolygonVerts(points); Polygon.recenterPolygonVerts(points);
this.shape = new Polygon(points); this.shape = new Polygon(points);
} }
}
} }
@@ -1,4 +1,23 @@
interface ITriggerListener { module es{
/**
* /退
* ITriggerListener方法将在实现接口的触发器实体上的任何组件上调用
* Mover类一起工作
*/
export interface ITriggerListener {
/**
*
* Mover/ProjectileMover方法处理使
* @param other
* @param local
*/
onTriggerEnter(other: Collider, local: Collider); onTriggerEnter(other: Collider, local: Collider);
/**
*
* @param other
* @param local
*/
onTriggerExit(other: Collider, local: Collider); onTriggerExit(other: Collider, local: Collider);
}
} }
+17 -21
View File
@@ -1,11 +1,12 @@
/** module es {
/**
* *
* ITriggerListener接口用于管理对移动过程中违反的任何触发器的回调 * ITriggerListener接口用于管理对移动过程中违反的任何触发器的回调
* move方法 * move方法
* *
* ITriggerListener * ITriggerListener
*/ */
class Mover extends Component { export class Mover extends Component {
private _triggerHelper: ColliderTriggerHelper; private _triggerHelper: ColliderTriggerHelper;
public onAddedToEntity(){ public onAddedToEntity(){
@@ -15,12 +16,11 @@ class Mover extends Component {
/** /**
* *
* @param motion * @param motion
* @param collisionResult
*/ */
public calculateMovement(motion: Vector2){ public calculateMovement(motion: Vector2, collisionResult: CollisionResult): boolean{
let collisionResult = new CollisionResult();
if (!this.entity.getComponent(Collider) || !this._triggerHelper){ if (!this.entity.getComponent(Collider) || !this._triggerHelper){
return null; return false;
} }
// 移动所有的非触发碰撞器并获得最近的碰撞 // 移动所有的非触发碰撞器并获得最近的碰撞
@@ -36,9 +36,7 @@ class Mover extends Component {
let bounds = collider.bounds; let bounds = collider.bounds;
bounds.x += motion.x; bounds.x += motion.x;
bounds.y += motion.y; bounds.y += motion.y;
let boxcastResult = Physics.boxcastBroadphaseExcludingSelf(collider, bounds, collider.collidesWithLayers); let neighbors = Physics.boxcastBroadphaseExcludingSelf(collider, bounds, collider.collidesWithLayers);
bounds = boxcastResult.bounds;
let neighbors = boxcastResult.tempHashSet;
for (let j = 0; j < neighbors.length; j ++){ for (let j = 0; j < neighbors.length; j ++){
let neighbor = neighbors[j]; let neighbor = neighbors[j];
@@ -46,13 +44,13 @@ class Mover extends Component {
if (neighbor.isTrigger) if (neighbor.isTrigger)
continue; continue;
let _internalcollisionResult = collider.collidesWith(neighbor, motion); let _internalcollisionResult: CollisionResult = new CollisionResult();
if (_internalcollisionResult){ if (collider.collidesWith(neighbor, motion, _internalcollisionResult)){
// 如果碰撞 则退回之前的移动量 // 如果碰撞 则退回之前的移动量
motion = Vector2.subtract(motion, _internalcollisionResult.minimumTranslationVector); motion = motion.subtract(_internalcollisionResult.minimumTranslationVector);
// 如果我们碰到多个对象,为了简单起见,只取第一个。 // 如果我们碰到多个对象,为了简单起见,只取第一个。
if (_internalcollisionResult.collider){ if (_internalcollisionResult.collider != null){
collisionResult = _internalcollisionResult; collisionResult = _internalcollisionResult;
} }
} }
@@ -61,7 +59,7 @@ class Mover extends Component {
ListPool.free(colliders); ListPool.free(colliders);
return {collisionResult: collisionResult, motion: motion}; return collisionResult.collider != null;
} }
/** /**
@@ -80,14 +78,12 @@ class Mover extends Component {
/** /**
* calculateMovement和applyMovement来移动考虑碰撞的实体; * calculateMovement和applyMovement来移动考虑碰撞的实体;
* @param motion * @param motion
* @param collisionResult
*/ */
public move(motion: Vector2){ public move(motion: Vector2, collisionResult: CollisionResult){
let movementResult = this.calculateMovement(motion); this.calculateMovement(motion, collisionResult);
let collisionResult = movementResult.collisionResult;
motion = movementResult.motion;
this.applyMovement(motion); this.applyMovement(motion);
return collisionResult.collider != null;
return collisionResult; }
} }
} }
@@ -1,8 +1,9 @@
/** module es {
/**
* itriggerlistener报告冲突的移动器 * itriggerlistener报告冲突的移动器
* *
*/ */
class ProjectileMover extends Component { export class ProjectileMover extends Component {
private _tempTriggerList: ITriggerListener[] = []; private _tempTriggerList: ITriggerListener[] = [];
private _collider: Collider; private _collider: Collider;
@@ -27,8 +28,8 @@ class ProjectileMover extends Component {
// 获取任何可能在新位置发生碰撞的东西 // 获取任何可能在新位置发生碰撞的东西
let neighbors = Physics.boxcastBroadphase(this._collider.bounds, this._collider.collidesWithLayers); let neighbors = Physics.boxcastBroadphase(this._collider.bounds, this._collider.collidesWithLayers);
for (let i = 0; i < neighbors.colliders.length; i ++){ for (let i = 0; i < neighbors.length; i ++){
let neighbor = neighbors.colliders[i]; let neighbor = neighbors[i];
if (this._collider.overlaps(neighbor) && neighbor.enabled){ if (this._collider.overlaps(neighbor) && neighbor.enabled){
didCollide = true; didCollide = true;
this.notifyTriggerListeners(this._collider, neighbor); this.notifyTriggerListeners(this._collider, neighbor);
@@ -53,4 +54,5 @@ class ProjectileMover extends Component {
} }
this._tempTriggerList.length = 0; this._tempTriggerList.length = 0;
} }
}
} }
+4 -2
View File
@@ -1,4 +1,6 @@
/** 回收实例的组件类型。 */ module es {
abstract class PooledComponent extends Component { /** 回收实例的组件类型。 */
export abstract class PooledComponent extends Component {
public abstract reset(); public abstract reset();
}
} }
+160 -27
View File
@@ -1,28 +1,86 @@
///<reference path="./PooledComponent.ts" /> ///<reference path="./PooledComponent.ts" />
/** module es {
/**
* *
*/ */
abstract class RenderableComponent extends PooledComponent implements IRenderable { export abstract class RenderableComponent extends Component implements IRenderable {
private _isVisible: boolean; /**
protected _areBoundsDirty = true; * egret显示对象
protected _bounds: Rectangle = new Rectangle(); */
protected _localOffset: Vector2 = Vector2.zero; public displayObject: egret.DisplayObject = new egret.DisplayObject();
/**
* renderableComponent的宽度
* bounds属性则需要实现这个
*/
public get width() {
return this.bounds.width;
}
/**
* renderableComponent的高度
* bounds属性则需要实现这个
*/
public get height() {
return this.bounds.height;
}
/**
* AABB,
*/
public get bounds(): Rectangle {
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;
}
return this._bounds;
}
/**
*
*/
public get renderLayer(): number{
return this._renderLayer;
}
public set renderLayer(value: number){
}
/**
*
*/
public color: number = 0x000000; public color: number = 0x000000;
public get width(){ /**
return this.getWidth(); *
*/
public get localOffset(): Vector2{
return this._localOffset;
} }
public get height(){ /**
return this.getHeight(); *
* @param value
*/
public set localOffset(value: Vector2){
this.setLocalOffset(value);
} }
public get isVisible(){ /**
* onBecameVisible/onBecameInvisible方法
*/
public get isVisible() {
return this._isVisible; return this._isVisible;
} }
public set isVisible(value: boolean){ /**
* onBecameVisible/onBecameInvisible方法
* @param value
*/
public set isVisible(value: boolean) {
if (this._isVisible != value){
this._isVisible = value; this._isVisible = value;
if (this._isVisible) if (this._isVisible)
@@ -30,27 +88,102 @@ abstract class RenderableComponent extends PooledComponent implements IRenderabl
else else
this.onBecameInvisible(); this.onBecameInvisible();
} }
public get bounds(): Rectangle{
return new Rectangle(this.getBounds().x, this.getBounds().y, this.getBounds().width, this.getBounds().height);
} }
protected getWidth(){ protected _localOffset: Vector2 = Vector2.zero;
return this.bounds.width; protected _renderLayer: number = 0;
protected _bounds: Rectangle = new Rectangle();
private _isVisible: boolean;
protected _areBoundsDirty = true;
public onEntityTransformChanged(comp: transform.Component) {
this._areBoundsDirty = true;
} }
protected getHeight(){ /**
return this.bounds.height; * 使
} * @param camera
*/
protected onBecameVisible(){}
protected onBecameInvisible(){}
public abstract render(camera: Camera); public abstract render(camera: Camera);
public isVisibleFromCamera(camera: Camera): boolean{ /**
this.isVisible = camera.getBounds().intersects(this.getBounds()); * renderableComponent进入相机框架时调用
* isVisibleFromCamera进行剔除检查
*/
protected onBecameVisible() {
this.displayObject.visible = this.isVisible;
}
/**
* renderableComponent离开相机框架时调用
* isVisibleFromCamera进行剔除检查
*/
protected onBecameInvisible() {
this.displayObject.visible = this.isVisible;
}
/**
* renderableComponent的边界与camera.bounds相交 true
* isVisible标志的状态开关
* 使
* @param camera
*/
public isVisibleFromCamera(camera: Camera): boolean {
this.isVisible = camera.bounds.intersects(this.bounds);
return this.isVisible; return this.isVisible;
} }
/**
*
* @param renderLayer
*/
public setRenderLayer(renderLayer: number): RenderableComponent{
if (renderLayer != this._renderLayer){
let oldRenderLayer = this._renderLayer;
this._renderLayer = renderLayer;
// 如果该组件拥有一个实体,那么是由ComponentList管理,需要通知它改变了渲染层
if (this.entity && this.entity.scene)
this.entity.scene.renderableComponents.updateRenderableRenderLayer(this, oldRenderLayer, this._renderLayer);
}
return this;
}
/**
*
* @param color
*/
public setColor(color: number): RenderableComponent{
this.color = color;
return this;
}
/**
*
* @param offset
*/
public setLocalOffset(offset: Vector2): RenderableComponent{
if (this._localOffset != offset){
this._localOffset = offset;
}
return this;
}
/**
*
*/
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;
this.displayObject.scaleY = this.entity.scale.y;
this.displayObject.rotation = this.entity.rotation;
}
public toString(){
return `[RenderableComponent] renderLayer: ${this.renderLayer}`;
}
}
} }
@@ -1,5 +1,6 @@
///<reference path="./TiledSpriteRenderer.ts"/> ///<reference path="./TiledSpriteRenderer.ts"/>
class ScrollingSpriteRenderer extends TiledSpriteRenderer { module es {
export class ScrollingSpriteRenderer extends TiledSpriteRenderer {
public scrollSpeedX = 15; public scrollSpeedX = 15;
public scroolSpeedY = 0; public scroolSpeedY = 0;
private _scrollX = 0; private _scrollX = 0;
@@ -31,7 +32,6 @@ class ScrollingSpriteRenderer extends TiledSpriteRenderer {
cacheBitmap.cacheAsBitmap = true; cacheBitmap.cacheAsBitmap = true;
renderTexture.drawToTexture(cacheBitmap, new egret.Rectangle(0, 0, this.sourceRect.width, this.sourceRect.height)); renderTexture.drawToTexture(cacheBitmap, new egret.Rectangle(0, 0, this.sourceRect.width, this.sourceRect.height));
}
this.bitmap.texture = renderTexture;
} }
} }
+4 -2
View File
@@ -1,4 +1,5 @@
class Sprite { module es {
export class Sprite {
public texture2D: egret.Texture; public texture2D: egret.Texture;
public readonly sourceRect: Rectangle; public readonly sourceRect: Rectangle;
public readonly center: Vector2; public readonly center: Vector2;
@@ -14,11 +15,12 @@ class Sprite {
this.origin = origin; this.origin = origin;
let inverseTexW = 1 / texture.textureWidth; let inverseTexW = 1 / texture.textureWidth;
let inverseTexH = 1 / texture.textureHeight let inverseTexH = 1 / texture.textureHeight;
this.uvs.x = sourceRect.x * inverseTexW; this.uvs.x = sourceRect.x * inverseTexW;
this.uvs.y = sourceRect.y * inverseTexH; this.uvs.y = sourceRect.y * inverseTexH;
this.uvs.width = sourceRect.width * inverseTexW; this.uvs.width = sourceRect.width * inverseTexW;
this.uvs.height = sourceRect.height * inverseTexH; this.uvs.height = sourceRect.height * inverseTexH;
} }
}
} }
+3 -1
View File
@@ -1,4 +1,5 @@
class SpriteAnimation { module es {
export class SpriteAnimation {
public readonly sprites: Sprite[]; public readonly sprites: Sprite[];
public readonly frameRate: number; public readonly frameRate: number;
@@ -6,4 +7,5 @@ class SpriteAnimation {
this.sprites = sprites; this.sprites = sprites;
this.frameRate = frameRate; this.frameRate = frameRate;
} }
}
} }
+92 -74
View File
@@ -1,34 +1,103 @@
///<reference path="./SpriteRenderer.ts" /> ///<reference path="./SpriteRenderer.ts" />
class SpriteAnimator extends SpriteRenderer { module es {
/** 在动画完成时触发,包括动画名称; */ export enum LoopMode {
public onAnimationCompletedEvent: Function; /** 在一个循环序列[A][B][C][A][B][C][A][B][C]... */
/** 动画播放速度 */ loop,
/** [A][B][C]然后暂停,设置时间为0 [A] */
once,
/** [A][B][C]。当它到达终点时,它会继续播放最后一帧,并且不会停止播放 */
clampForever,
/** 以一个乒乓循环的方式永远播放这个序列 [A][B][C][B][A][B][C][B]... */
pingPong,
/** 将顺序向前播放一次,然后返回到开始[A][B][C][B][A],然后暂停并设置时间为0 */
pingPongOnce,
}
export enum State {
none,
running,
paused,
completed,
}
export class SpriteAnimator extends SpriteRenderer {
/**
*
*/
public onAnimationCompletedEvent: (string) => {};
/**
*
*/
public speed = 1; public speed = 1;
/** 动画的当前状态 */ /**
*
*/
public animationState = State.none; public animationState = State.none;
/** 当前动画 */ /**
*
*/
public currentAnimation: SpriteAnimation; public currentAnimation: SpriteAnimation;
/** 当前动画的名称 */ /**
*
*/
public currentAnimationName: string; public currentAnimationName: string;
/** 当前动画的精灵数组中当前帧的索引 */ /**
*
*/
public currentFrame: number; public currentFrame: number;
/** 检查当前动画是否正在运行 */
public get isRunning(): boolean{ /**
*
*/
public get isRunning(): boolean {
return this.animationState == State.running; return this.animationState == State.running;
} }
/** 提供对可用动画列表的访问 */ /** 提供对可用动画列表的访问 */
public get animations(){ public get animations() {
return this._animations; return this._animations;
} }
private _animations: Map<string, SpriteAnimation> = new Map<string, SpriteAnimation>(); private _animations: Map<string, SpriteAnimation> = new Map<string, SpriteAnimation>();
private _elapsedTime: number = 0; public _elapsedTime: number = 0;
private _loopMode: LoopMode; public _loopMode: LoopMode;
constructor(sprite?: Sprite){ constructor(sprite?: Sprite) {
super(); super(sprite);
}
if (sprite) this.setSprite(sprite); public update() {
if (this.animationState != State.running || !this.currentAnimation) return;
let animation = this.currentAnimation;
let secondsPerFrame = 1 / (animation.frameRate * this.speed);
let iterationDuration = secondsPerFrame * animation.sprites.length;
this._elapsedTime += Time.deltaTime;
let time = Math.abs(this._elapsedTime);
// Once和PingPongOnce完成后重置为Time = 0
if (this._loopMode == LoopMode.once && time > iterationDuration ||
this._loopMode == LoopMode.pingPongOnce && time > iterationDuration * 2) {
this.animationState = State.completed;
this._elapsedTime = 0;
this.currentFrame = 0;
this.sprite = animation.sprites[this.currentFrame];
return;
}
// 弄清楚我们在哪个坐标系上
let i = Math.floor(time / secondsPerFrame);
let n = animation.sprites.length;
if (n > 2 && (this._loopMode == LoopMode.pingPong || this._loopMode == LoopMode.pingPongOnce)) {
// pingpong
let maxIndex = n - 1;
this.currentFrame = maxIndex - Math.abs(maxIndex - i % (maxIndex * 2));
} else {
this.currentFrame = i % n;
}
this.sprite = animation.sprites[this.currentFrame];
} }
/** /**
@@ -36,7 +105,8 @@ class SpriteAnimator extends SpriteRenderer {
* @param name * @param name
* @param animation * @param animation
*/ */
public addAnimation(name: string, animation: SpriteAnimation): SpriteAnimator{ public addAnimation(name: string, animation: SpriteAnimation): SpriteAnimator {
// 如果我们没有精灵,使用我们找到的第一帧
if (!this.sprite && animation.sprites.length > 0) if (!this.sprite && animation.sprites.length > 0)
this.setSprite(animation.sprites[0]); this.setSprite(animation.sprites[0]);
this._animations[name] = animation; this._animations[name] = animation;
@@ -48,7 +118,7 @@ class SpriteAnimator extends SpriteRenderer {
* @param name * @param name
* @param loopMode * @param loopMode
*/ */
public play(name: string, loopMode: LoopMode = null){ public play(name: string, loopMode: LoopMode = null) {
this.currentAnimation = this._animations[name]; this.currentAnimation = this._animations[name];
this.currentAnimationName = name; this.currentAnimationName = name;
this.currentFrame = 0; this.currentFrame = 0;
@@ -63,84 +133,32 @@ class SpriteAnimator extends SpriteRenderer {
* ()) * ())
* @param name * @param name
*/ */
public isAnimationActive(name: string): boolean{ public isAnimationActive(name: string): boolean {
return this.currentAnimation && this.currentAnimationName == name; return this.currentAnimation && this.currentAnimationName == name;
} }
/** /**
* *
*/ */
public pause(){ public pause() {
this.animationState = State.paused; this.animationState = State.paused;
} }
/** /**
* *
*/ */
public unPause(){ public unPause() {
this.animationState = State.running; this.animationState = State.running;
} }
/** /**
* null * null
*/ */
public stop(){ public stop() {
this.currentAnimation = null; this.currentAnimation = null;
this.currentAnimationName = null; this.currentAnimationName = null;
this.currentFrame = 0; this.currentFrame = 0;
this.animationState = State.none; this.animationState = State.none;
} }
public update(){
if (this.animationState != State.running || !this.currentAnimation) return;
let animation = this.currentAnimation;
let secondsPerFrame = 1 / (animation.frameRate * this.speed);
let iterationDuration = secondsPerFrame * animation.sprites.length;
this._elapsedTime += Time.deltaTime;
let time = Math.abs(this._elapsedTime);
if (this._loopMode == LoopMode.once && time > iterationDuration ||
this._loopMode == LoopMode.pingPongOnce && time > iterationDuration * 2){
this.animationState = State.completed;
this._elapsedTime = 0;
this.currentFrame = 0;
this.sprite = animation.sprites[this.currentFrame];
return;
}
// 弄清楚我们在哪个坐标系上
let i = Math.floor(time / secondsPerFrame);
let n = animation.sprites.length;
if (n > 2 && (this._loopMode == LoopMode.pingPong || this._loopMode == LoopMode.pingPongOnce)){
// pingpong
let maxIndex = n - 1;
this.currentFrame = maxIndex - Math.abs(maxIndex - i % (maxIndex * 2));
}else{
this.currentFrame = i % n;
}
this.sprite = animation.sprites[this.currentFrame];
} }
} }
enum LoopMode {
/** 在一个循环序列[A][B][C][A][B][C][A][B][C]... */
loop,
/** [A][B][C]然后暂停,设置时间为0 [A] */
once,
/** [A][B][C]。当它到达终点时,它会继续播放最后一帧,并且不会停止播放 */
clampForever,
/** 以一个乒乓循环的方式永远播放这个序列 [A][B][C][B][A][B][C][B]... */
pingPong,
/** 将顺序向前播放一次,然后返回到开始[A][B][C][B][A],然后暂停并设置时间为0 */
pingPongOnce,
}
enum State {
none,
running,
paused,
completed,
}
+107 -39
View File
@@ -1,62 +1,130 @@
class SpriteRenderer extends RenderableComponent{ module es {
private _sprite: Sprite; import Bitmap = egret.Bitmap;
protected bitmap: egret.Bitmap;
/** 应该由这个精灵显示的精灵 */ export class SpriteRenderer extends RenderableComponent {
public get sprite(): Sprite{ public get bounds() {
if (this._areBoundsDirty) {
if (this._sprite) {
this._bounds.calculateBounds(this.entity.transform.position, this._localOffset, this._origin,
this.entity.transform.scale, this.entity.transform.rotation, this._sprite.sourceRect.width,
this._sprite.sourceRect.height);
this._areBoundsDirty = false;
}
}
return this._bounds;
}
/**
*
*/
public get origin(): Vector2 {
return this._origin;
}
/**
*
* @param value
*/
public set origin(value: Vector2) {
this.setOrigin(value);
}
/**
*
* x/y 0-1
*/
public get originNormalized(): Vector2 {
return new Vector2(this._origin.x / this.width * this.entity.transform.scale.x,
this._origin.y / this.height * this.entity.transform.scale.y);
}
/**
*
* x/y 0-1
* @param value
*/
public set originNormalized(value: Vector2) {
this.setOrigin(new Vector2(value.x * this.width / this.entity.transform.scale.x,
value.y * this.height / this.entity.transform.scale.y));
}
/**
*
* origin
*/
public get sprite(): Sprite {
return this._sprite; return this._sprite;
} }
/** 应该由这个精灵显示的精灵 */
public set sprite(value: Sprite){ /**
*
* origin
* @param value
*/
public set sprite(value: Sprite) {
this.setSprite(value); this.setSprite(value);
} }
public setSprite(sprite: Sprite): SpriteRenderer{ protected _origin: Vector2;
this.removeChildren(); 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
*/
public setSprite(sprite: Sprite): SpriteRenderer {
this._sprite = sprite; this._sprite = sprite;
if (this._sprite) { if (this._sprite) {
this.anchorOffsetX = this._sprite.origin.x / this._sprite.sourceRect.width; this._origin = this._sprite.origin;
this.anchorOffsetY = this._sprite.origin.y / this._sprite.sourceRect.height; this.displayObject.anchorOffsetX = this._origin.x;
this.displayObject.anchorOffsetY = this._origin.y;
} }
this.bitmap = new egret.Bitmap(sprite.texture2D); this.displayObject = new Bitmap(sprite.texture2D);
this.addChild(this.bitmap);
return this; return this;
} }
public setColor(color: number): SpriteRenderer{ /**
let colorMatrix = [ *
1, 0, 0, 0, 0, * @param origin
0, 1, 0, 0, 0, */
0, 0, 1, 0, 0, public setOrigin(origin: Vector2): SpriteRenderer {
0, 0, 0, 1, 0 if (this._origin != origin) {
]; this._origin = origin;
colorMatrix[0] = Math.floor(color / 256 / 256) / 255; this.displayObject.anchorOffsetX = this._origin.x;
colorMatrix[6] = Math.floor(color / 256 % 256) / 255; this.displayObject.anchorOffsetY = this._origin.y;
colorMatrix[12] = color % 256 / 255; this._areBoundsDirty = true;
let colorFilter = new egret.ColorMatrixFilter(colorMatrix); }
this.filters = [colorFilter];
return this; return this;
} }
public isVisibleFromCamera(camera: Camera): boolean{ /**
this.isVisible = new Rectangle(0, 0, this.stage.stageWidth, this.stage.stageHeight).intersects(this.bounds); *
this.visible = this.isVisible; * x/y 0-1
return this.isVisible; * @param value
*/
public setOriginNormalized(value: Vector2): SpriteRenderer {
this.setOrigin(new Vector2(value.x * this.width / this.entity.transform.scale.x,
value.y * this.height / this.entity.transform.scale.y));
return this;
} }
/** 渲染处理 在每个模块中处理各自的渲染逻辑 */ public render(camera: Camera) {
public render(camera: Camera){ this.sync(camera);
this.x = -camera.position.x + camera.origin.x;
this.y = -camera.position.y + camera.origin.y;
}
public onRemovedFromEntity(){ this.displayObject.x = this.entity.position.x - this.origin.x + this.localOffset.x - camera.position.x + camera.origin.x;
if (this.parent) this.displayObject.y = this.entity.position.y - this.origin.y + this.localOffset.y - camera.position.y + camera.origin.y;
this.parent.removeChild(this);
} }
public reset(){
} }
} }
@@ -1,8 +1,9 @@
///<reference path="./SpriteRenderer.ts" /> ///<reference path="./SpriteRenderer.ts" />
/** module es {
/**
* *
*/ */
class TiledSpriteRenderer extends SpriteRenderer { export class TiledSpriteRenderer extends SpriteRenderer {
protected sourceRect: Rectangle; protected sourceRect: Rectangle;
protected leftTexture: egret.Bitmap; protected leftTexture: egret.Bitmap;
protected rightTexture: egret.Bitmap; protected rightTexture: egret.Bitmap;
@@ -21,7 +22,7 @@ class TiledSpriteRenderer extends SpriteRenderer {
} }
constructor(sprite: Sprite) { constructor(sprite: Sprite) {
super(); super(sprite);
this.leftTexture = new egret.Bitmap(); this.leftTexture = new egret.Bitmap();
this.rightTexture = new egret.Bitmap(); this.rightTexture = new egret.Bitmap();
@@ -32,7 +33,7 @@ class TiledSpriteRenderer extends SpriteRenderer {
this.sourceRect = sprite.sourceRect; this.sourceRect = sprite.sourceRect;
} }
public render(camera: Camera) { public render(camera: es.Camera) {
if (!this.sprite) if (!this.sprite)
return; return;
@@ -51,7 +52,6 @@ class TiledSpriteRenderer extends SpriteRenderer {
cacheBitmap.cacheAsBitmap = true; cacheBitmap.cacheAsBitmap = true;
renderTexture.drawToTexture(cacheBitmap, new egret.Rectangle(0, 0, this.sourceRect.width, this.sourceRect.height)); renderTexture.drawToTexture(cacheBitmap, new egret.Rectangle(0, 0, this.sourceRect.width, this.sourceRect.height));
}
this.bitmap.texture = renderTexture;
} }
} }
+230
View File
@@ -0,0 +1,230 @@
module es {
/**
*
*/
export class Core extends egret.DisplayObjectContainer {
/**
*
*/
public static emitter: Emitter<CoreEvents>;
/**
* 访
*/
public static graphicsDevice: GraphicsDevice;
/**
*
*/
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;
/**
* 访
*/
public _globalManagers: GlobalManager[] = [];
/**
*
*/
public static get scene() {
if (!this._instance)
return null;
return this._instance._scene;
}
/**
*
* @param value
*/
public static set scene(value: Scene) {
if (!value){
console.error("场景不能为空");
return;
}
if (this._instance._scene == null) {
this._instance._scene = value;
this._instance.addChild(value);
this._instance._scene.begin();
Core.Instance.onSceneChanged();
} else {
this._instance._nextScene = value;
}
}
constructor() {
super();
Core._instance = this;
Core.emitter = new Emitter<CoreEvents>();
Core.content = new ContentManager();
this.addEventListener(egret.Event.ADDED_TO_STAGE, this.onAddToStage, this);
}
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();
}
public onOrientationChanged(){
Core.emitter.emit(CoreEvents.OrientationChanged);
}
/**
*
*/
protected onGraphicsDeviceReset(){
Core.emitter.emit(CoreEvents.GraphicsDeviceReset);
}
protected initialize(){
}
protected async update() {
// this.startDebugUpdate();
// 更新我们所有的系统管理器
Time.update(egret.getTimer());
if (this._scene) {
for (let i = this._globalManagers.length - 1; i >= 0; i--) {
if (this._globalManagers[i].enabled)
this._globalManagers[i].update();
}
// 仔细阅读:
// 当场景转换发生时,我们不会更新场景
// -除非是不改变场景的场景转换(没有理由不更新)
// -或者它是一个已经切换到新场景的场景转换(新场景需要做它自己的事情)
if (!this._sceneTransition ||
(this._sceneTransition && (!this._sceneTransition.loadsNewScene || this._sceneTransition.isNewSceneLoaded))) {
this._scene.update();
}
if (this._nextScene) {
this.removeChild(this._scene);
this._scene.end();
this._scene = this._nextScene;
this._nextScene = null;
this.onSceneChanged();
this.addChild(this._scene);
await this._scene.begin();
}
}
// this.endDebugUpdate();
await this.draw();
}
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();
}
/**
* 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;
}
}
}
+14 -2
View File
@@ -1,4 +1,16 @@
enum CoreEvents{ module es {
/** 当场景发生变化时触发 */ export enum CoreEvents{
/**
* VRAM将被擦除
*/
GraphicsDeviceReset,
/**
*
*/
SceneChanged, SceneChanged,
/**
*
*/
OrientationChanged,
}
} }
+350 -152
View File
@@ -1,188 +1,410 @@
class Entity extends egret.DisplayObjectContainer { module es {
private static _idGenerator: number; export class Entity {
public static _idGenerator: number;
public name: string; /**
public readonly id: number; *
/** 当前实体所属的场景 */ */
public scene: Scene; public scene: Scene;
/** 当前附加到此实体的所有组件的列表 */ /**
*
*/
public name: string;
/**
*
*/
public readonly id: number;
/**
* //
*/
public readonly transform: Transform;
/**
*
*/
public readonly components: ComponentList; public readonly components: ComponentList;
private _updateOrder: number = 0;
private _enabled: boolean = true;
public _isDestoryed: boolean;
private _tag: number = 0;
public componentBits: BitSet; /**
* 使使
public get isDestoryed(){ */
return this._isDestoryed; public get tag(): number {
}
public get position(){
return new Vector2(this.x, this.y);
}
public set position(value: Vector2){
this.$setX(value.x);
this.$setY(value.y);
this.onEntityTransformChanged(TransformComponent.position);
}
public get scale(){
return new Vector2(this.scaleX, this.scaleY);
}
public set scale(value: Vector2){
this.$setScaleX(value.x);
this.$setScaleY(value.y);
this.onEntityTransformChanged(TransformComponent.scale);
}
public set rotation(value: number){
this.$setRotation(value);
this.onEntityTransformChanged(TransformComponent.rotation);
}
public get rotation(){
return this.$getRotation();
}
public get enabled(){
return this._enabled;
}
public set enabled(value: boolean){
this.setEnabled(value);
}
public setEnabled(isEnabled: boolean){
if (this._enabled != isEnabled){
this._enabled = isEnabled;
}
return this;
}
public get tag(){
return this._tag; return this._tag;
} }
public set tag(value: number){ /**
* 使使
* @param value
*/
public set tag(value: number) {
this.setTag(value); this.setTag(value);
} }
public get stage(){ /**
if (!this.scene) * entity update方法的频率12
return null; */
public updateInterval: number = 1;
return this.scene.stage; /**
* /
*/
public get enabled() {
return this._enabled;
} }
constructor(name: string){ /**
super(); * /
this.name = name; * @param value
this.components = new ComponentList(this); */
this.id = Entity._idGenerator ++; public set enabled(value: boolean) {
this.setEnabled(value);
this.componentBits = new BitSet();
this.addEventListener(egret.Event.ADDED_TO_STAGE, this.onAddToStage, this);
} }
private onAddToStage(){ /**
this.onEntityTransformChanged(TransformComponent.position); * updateOrder还用于对scene.entities上的标签列表进行排序
} */
public get updateOrder() {
public get updateOrder(){
return this._updateOrder; return this._updateOrder;
} }
public set updateOrder(value: number){ /**
* updateOrder还用于对scene.entities上的标签列表进行排序
* @param value
*/
public set updateOrder(value: number) {
this.setUpdateOrder(value); this.setUpdateOrder(value);
} }
public roundPosition(){ public _isDestroyed: boolean;
this.position = Vector2Ext.round(this.position); /**
* destroytrue
*/
public get isDestroyed() {
return this._isDestroyed;
} }
public setUpdateOrder(updateOrder: number){ public componentBits: BitSet;
if (this._updateOrder != updateOrder){
this._updateOrder = updateOrder;
if (this.scene){
private _tag: number = 0;
private _enabled: boolean = true;
private _updateOrder: number = 0;
public get parent(): Transform {
return this.transform.parent;
} }
return this; public set parent(value: Transform) {
} this.transform.setParent(value);
} }
public setTag(tag: number): Entity{ public get childCount() {
if (this._tag != tag){ return this.transform.childCount;
if (this.scene){ }
public get position(): Vector2 {
return this.transform.position;
}
public set position(value: Vector2) {
this.transform.setPosition(value.x, value.y);
}
public get localPosition(): Vector2 {
return this.transform.localPosition;
}
public set localPosition(value: Vector2){
this.transform.setLocalPosition(value);
}
public get rotation(): number {
return this.transform.rotation;
}
public set rotation(value: number) {
this.transform.setRotation(value);
}
public get rotationDegrees(): number {
return this.transform.rotationDegrees;
}
public set rotationDegrees(value: number){
this.transform.setRotationDegrees(value);
}
public get localRotation(): number {
return this.transform.localRotation;
}
public set localRotation(value: number){
this.transform.setLocalRotation(value);
}
public get localRotationDegrees(): number {
return this.transform.localRotationDegrees;
}
public set localRotationDegrees(value: number){
this.transform.setLocalRotationDegrees(value);
}
public get scale(): Vector2 {
return this.transform.scale;
}
public set scale(value: Vector2) {
this.transform.setScale(value);
}
public get localScale(): Vector2 {
return this.transform.localScale;
}
public set localScale(value: Vector2){
this.transform.setLocalScale(value);
}
public get worldInverseTransform(): Matrix2D {
return this.transform.worldInverseTransform;
}
public get localToWorldTransform(): Matrix2D {
return this.transform.localToWorldTransform;
}
public get worldToLocalTransform(): Matrix2D {
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);
}
/**
*
* @param tag
*/
public setTag(tag: number): Entity {
if (this._tag != tag) {
// 我们只有在已经有场景的情况下才会调用entityTagList。如果我们还没有场景,我们会被添加到entityTagList
if (this.scene)
this.scene.entities.removeFromTagList(this); this.scene.entities.removeFromTagList(this);
}
this._tag = tag; this._tag = tag;
if (this.scene){ if (this.scene)
this.scene.entities.addToTagList(this); this.scene.entities.addToTagList(this);
} }
return this;
}
/**
*
* @param isEnabled
*/
public setEnabled(isEnabled: boolean) {
if (this._enabled != isEnabled) {
this._enabled = isEnabled;
if (this._enabled)
this.components.onEntityEnabled();
else
this.components.onEntityDisabled();
} }
return this; return this;
} }
public attachToScene(newScene: Scene){ /**
* updateOrder还用于对scene.entities上的标签列表进行排序
* @param updateOrder
*/
public setUpdateOrder(updateOrder: number) {
if (this._updateOrder != updateOrder) {
this._updateOrder = updateOrder;
if (this.scene) {
this.scene.entities.markEntityListUnsorted();
this.scene.entities.markTagUnsorted(this.tag);
}
return this;
}
}
/**
*
*/
public destroy() {
this._isDestroyed = true;
this.scene.entities.remove(this);
this.transform.parent = null;
// 销毁所有子项
for (let i = this.transform.childCount - 1; i >= 0; i--) {
let child = this.transform.getChild(i);
child.entity.destroy();
}
}
/**
* 下面的生命周期方法将被调用在组件上:OnRemovedFromEntity
*/
public detachFromScene() {
this.scene.entities.remove(this);
this.components.deregisterAllComponents();
for (let i = 0; i < this.transform.childCount; i++)
this.transform.getChild(i).entity.detachFromScene();
}
/**
*
* @param newScene
*/
public attachToScene(newScene: Scene) {
this.scene = newScene; this.scene = newScene;
newScene.entities.add(this); newScene.entities.add(this);
this.components.registerAllComponents(); this.components.registerAllComponents();
for (let i = 0; i < this.numChildren; i ++){ for (let i = 0; i < this.transform.childCount; i++) {
(this.getChildAt(i) as Component).entity.attachToScene(newScene); this.transform.getChild(i).entity.attachToScene(newScene);
} }
} }
public detachFromScene(){ /**
this.scene.entities.remove(this); *
this.components.deregisterAllComponents(); * CopyFrom方法
* !!
* @param position
*/
public clone(position: Vector2 = new Vector2()): Entity {
let entity = new Entity(this.name + "(clone)");
entity.copyFrom(this);
entity.transform.position = position;
for (let i = 0; i < this.numChildren; i ++) return entity;
(this.getChildAt(i) as Component).entity.detachFromScene();
} }
public addComponent<T extends Component>(component: T): T{ /**
*
* @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;
}
}
/**
*
*/
public onAddedToScene() {
}
/**
*
*/
public onRemovedFromScene() {
// 如果已经被销毁了,移走我们的组件。如果我们只是分离,我们需要保持我们的组件在实体上。
if (this._isDestroyed)
this.components.removeAllComponents();
}
/**
*
*/
public update() {
this.components.update();
}
/**
*
* @param component
*/
public addComponent<T extends Component>(component: T): T {
component.entity = this; component.entity = this;
this.components.add(component); this.components.add(component);
this.addChild(component);
component.initialize(); component.initialize();
return component; return component;
} }
public hasComponent<T extends Component>(type){ /**
* T的第一个组件并返回它null
* @param type
*/
public getComponent<T extends Component>(type): T {
return this.components.getComponent(type, false) as T;
}
/**
*
* @param type
*/
public hasComponent<T extends Component>(type) {
return this.components.getComponent<T>(type, false) != null; return this.components.getComponent<T>(type, false) != null;
} }
public getOrCreateComponent<T extends Component>(type: T){ /**
* T的第一个组件并返回它
* @param type
*/
public getOrCreateComponent<T extends Component>(type: T) {
let comp = this.components.getComponent<T>(type, true); let comp = this.components.getComponent<T>(type, true);
if (!comp){ if (!comp) {
comp = this.addComponent<T>(type); comp = this.addComponent<T>(type);
} }
return comp; return comp;
} }
public getComponent<T extends Component>(type): T{ /**
return this.components.getComponent(type, false) as T; * typeName类型的所有组件使
} * @param typeName
* @param componentList
public getComponents(typeName: string | any, componentList?){ */
public getComponents(typeName: string | any, componentList?) {
return this.components.getComponents(typeName, componentList); return this.components.getComponents(typeName, componentList);
} }
private onEntityTransformChanged(comp: TransformComponent){ /**
this.components.onEntityTransformChanged(comp); *
* @param component
*/
public removeComponent(component: Component) {
this.components.remove(component);
} }
public removeComponentForType<T extends Component>(type){ /**
* T的第一个组件
* @param type
*/
public removeComponentForType<T extends Component>(type) {
let comp = this.getComponent<T>(type); let comp = this.getComponent<T>(type);
if (comp){ if (comp) {
this.removeComponent(comp); this.removeComponent(comp);
return true; return true;
} }
@@ -190,48 +412,24 @@ class Entity extends egret.DisplayObjectContainer {
return false; return false;
} }
public removeComponent(component: Component){ /**
this.components.remove(component); *
} */
public removeAllComponents() {
public removeAllComponents(){ for (let i = 0; i < this.components.count; i++) {
for (let i = 0; i < this.components.count; i ++){
this.removeComponent(this.components.buffer[i]); this.removeComponent(this.components.buffer[i]);
} }
} }
public update(){ public compareTo(other: Entity): number {
this.components.update(); let compare = this._updateOrder - other._updateOrder;
if (compare == 0)
compare = this.id - other.id;
return compare;
} }
public onAddedToScene(){ public toString(): string {
return `[Entity: name: ${this.name}, tag: ${this.tag}, enabled: ${this.enabled}, depth: ${this.updateOrder}]`;
}
public onRemovedFromScene(){
if (this._isDestoryed)
this.components.removeAllComponents();
}
public destroy(){
this._isDestoryed = true;
this.removeEventListener(egret.Event.ADDED_TO_STAGE, this.onAddToStage, this);
this.scene.entities.remove(this);
this.removeChildren();
if (this.parent)
this.parent.removeChild(this);
for (let i = this.numChildren - 1; i >= 0; i --){
let child = this.getChildAt(i);
(child as Component).entity.destroy();
} }
} }
} }
enum TransformComponent {
rotation,
scale,
position
}
+249 -112
View File
@@ -1,110 +1,88 @@
/** 场景 */ module es {
class Scene extends egret.DisplayObjectContainer { /** 场景 */
export class Scene extends egret.DisplayObjectContainer {
/**
*
*/
public camera: Camera; public camera: Camera;
public readonly entities: EntityList; /**
public readonly renderableComponents: RenderableComponentList; * 使/使SceneManager.content
* contentManager来加载它们Nez不会卸载它们
*/
public readonly content: ContentManager; public readonly content: ContentManager;
/**
*
*/
public enablePostProcessing = true; public enablePostProcessing = true;
/**
private _renderers: Renderer[] = []; *
private _postProcessors: PostProcessor[] = []; */
private _didSceneBegin; public readonly entities: EntityList;
/**
*
*/
public readonly renderableComponents: RenderableComponentList;
/**
*
*/
public readonly entityProcessors: EntityProcessorList; public readonly entityProcessors: EntityProcessorList;
public _renderers: Renderer[] = [];
public readonly _postProcessors: PostProcessor[] = [];
public _didSceneBegin;
/**
* DefaultRenderer附加并准备使用
*/
public static createWithDefaultRenderer(){
let scene = new Scene();
scene.addRenderer(new DefaultRenderer());
return scene;
}
constructor() { constructor() {
super(); super();
this.entityProcessors = new EntityProcessorList();
this.renderableComponents = new RenderableComponentList();
this.entities = new EntityList(this); this.entities = new EntityList(this);
this.renderableComponents = new RenderableComponentList();
this.content = new ContentManager(); this.content = new ContentManager();
this.width = SceneManager.stage.stageWidth;
this.height = SceneManager.stage.stageHeight;
this.addEventListener(egret.Event.ACTIVATE, this.onActive, this); this.entityProcessors = new EntityProcessorList();
this.addEventListener(egret.Event.DEACTIVATE, this.onDeactive, this);
}
public createEntity(name: string) { this.initialize();
let entity = new Entity(name);
entity.position = new Vector2(0, 0);
return this.addEntity(entity);
}
public addEntity(entity: Entity) {
this.entities.add(entity);
entity.scene = this;
this.addChild(entity);
for (let i = 0; i < entity.numChildren; i++)
this.addEntity((entity.getChildAt(i) as Component).entity);
return entity;
}
public destroyAllEntities() {
for (let i = 0; i < this.entities.count; i++) {
this.entities.buffer[i].destroy();
}
}
public findEntity(name: string): Entity {
return this.entities.findEntity(name);
} }
/** /**
* EntitySystem处理器 * begin之前
* @param processor
*/ */
public addEntityProcessor(processor: EntitySystem) { public initialize(){}
processor.scene = this;
this.entityProcessors.add(processor);
return processor;
}
public removeEntityProcessor(processor: EntitySystem) { /**
this.entityProcessors.remove(processor); * SceneManager将此场景设置为活动场景时
} */
public async onStart() {}
public getEntityProcessor<T extends EntitySystem>(): T { /**
return this.entityProcessors.getProcessor<T>(); * SceneManager从活动槽中删除此场景时调用
} */
public unload() { }
public addRenderer<T extends Renderer>(renderer: T) {
this._renderers.push(renderer);
this._renderers.sort();
renderer.onAddedToScene(this); /**
*
*/
public onActive() {}
return renderer; /**
} *
*/
public getRenderer<T extends Renderer>(type): T { public onDeactive() {}
for (let i = 0; i < this._renderers.length; i++) {
if (this._renderers[i] instanceof type)
return this._renderers[i] as T;
}
return null;
}
public removeRenderer(renderer: Renderer) {
this._renderers.remove(renderer);
renderer.unload();
}
public begin() {
if (SceneManager.sceneTransition){
SceneManager.stage.addChildAt(this, SceneManager.stage.numChildren - 1);
}else{
SceneManager.stage.addChild(this);
}
public async begin() {
if (this._renderers.length == 0) { if (this._renderers.length == 0) {
this.addRenderer(new DefaultRenderer()); this.addRenderer(new DefaultRenderer());
console.warn("场景开始时没有渲染器 自动添加DefaultRenderer以保证能够正常渲染"); console.warn("场景开始时没有渲染器 自动添加DefaultRenderer以保证能够正常渲染");
} }
/** 初始化默认相机 */
this.camera = this.createEntity("camera").getOrCreateComponent(new Camera()); this.camera = this.createEntity("camera").getOrCreateComponent(new Camera());
Physics.reset(); Physics.reset();
@@ -112,6 +90,8 @@ class Scene extends egret.DisplayObjectContainer {
if (this.entityProcessors) if (this.entityProcessors)
this.entityProcessors.begin(); 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.camera.onSceneSizeChanged(this.stage.stageWidth, this.stage.stageHeight);
this._didSceneBegin = true; this._didSceneBegin = true;
@@ -135,70 +115,102 @@ class Scene extends egret.DisplayObjectContainer {
this.entities.removeAllEntities(); this.entities.removeAllEntities();
this.removeChildren(); this.removeChildren();
Physics.clear();
this.camera = null; this.camera = null;
this.content.dispose(); this.content.dispose();
if (this.entityProcessors) if (this.entityProcessors)
this.entityProcessors.end(); this.entityProcessors.end();
this.unload();
if (this.parent) if (this.parent)
this.parent.removeChild(this); this.parent.removeChild(this);
this.unload();
} }
protected async onStart() {
}
/** 场景激活 */
protected onActive() {
}
/** 场景失去焦点 */
protected onDeactive() {
}
protected unload() { }
public update() { public update() {
// 更新我们的列表,以防它们有任何变化
this.entities.updateLists(); this.entities.updateLists();
// 更新我们的实体解析器
if (this.entityProcessors) if (this.entityProcessors)
this.entityProcessors.update() this.entityProcessors.update();
// 更新我们的实体组
this.entities.update(); this.entities.update();
if (this.entityProcessors) if (this.entityProcessors)
this.entityProcessors.lateUpdate(); this.entityProcessors.lateUpdate();
// 我们在实体之后更新我们的呈现。如果添加了任何新的渲染,请进行更新
this.renderableComponents.updateList(); 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() { public postRender() {
let enabledCounter = 0;
if (this.enablePostProcessing) { if (this.enablePostProcessing) {
for (let i = 0; i < this._postProcessors.length; i++) { for (let i = 0; i < this._postProcessors.length; i++) {
if (this._postProcessors[i].enable) { if (this._postProcessors[i].enabled) {
let isEven = MathHelper.isEven(enabledCounter);
enabledCounter ++;
this._postProcessors[i].process(); this._postProcessors[i].process();
} }
} }
} }
} }
public render() { /**
for (let i = 0; i < this._renderers.length; i++) { *
this._renderers[i].render(this); * @param renderer
} */
public addRenderer<T extends Renderer>(renderer: T) {
this._renderers.push(renderer);
this._renderers.sort();
renderer.onAddedToScene(this);
return renderer;
} }
/**
* 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{ public addPostProcessor<T extends PostProcessor>(postProcessor: T): T{
this._postProcessors.push(postProcessor); this._postProcessors.push(postProcessor);
this._postProcessors.sort(); this._postProcessors.sort();
@@ -210,4 +222,129 @@ class Scene extends egret.DisplayObjectContainer {
return postProcessor; 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;
}
/**
* unloadPostProcessorunload来释放资源
* @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>();
}
}
} }
-131
View File
@@ -1,131 +0,0 @@
/** 运行时的场景管理。 */
class SceneManager {
private static _scene: Scene;
private static _nextScene: Scene;
public static sceneTransition: SceneTransition;
public static stage: egret.Stage;
/** 订阅此事件以在活动场景发生更改时得到通知。 */
public static activeSceneChanged: Function;
/** 核心发射器。只发出核心级别的事件 */
public static emitter: Emitter<CoreEvents>;
/** 全局内容管理器加载任何应该停留在场景之间的资产 */
public static content: ContentManager;
/** 简化对内部类的全局内容实例的访问 */
private static _instnace: SceneManager;
public static get Instance(){
return this._instnace;
}
constructor(stage: egret.Stage) {
stage.addEventListener(egret.Event.ENTER_FRAME, SceneManager.update, this);
SceneManager._instnace = this;
SceneManager.emitter = new Emitter<CoreEvents>();
SceneManager.content = new ContentManager();
SceneManager.stage = stage;
SceneManager.initialize(stage);
}
public static get scene() {
return this._scene;
}
public static set scene(value: Scene) {
if (!value)
throw new Error("场景不能为空");
if (this._scene == null) {
this._scene = value;
this._scene.begin();
SceneManager.Instance.onSceneChanged();
} else {
this._nextScene = value;
}
this.registerActiveSceneChanged(this._scene, this._nextScene);
}
public static initialize(stage: egret.Stage) {
Input.initialize(stage);
}
public static update() {
Time.update(egret.getTimer());
if (SceneManager._scene) {
for (let i = GlobalManager.globalManagers.length - 1; i >= 0; i--) {
if (GlobalManager.globalManagers[i].enabled)
GlobalManager.globalManagers[i].update();
}
if (!SceneManager.sceneTransition ||
(SceneManager.sceneTransition && (!SceneManager.sceneTransition.loadsNewScene || SceneManager.sceneTransition.isNewSceneLoaded))) {
SceneManager._scene.update();
}
if (SceneManager._nextScene) {
SceneManager._scene.end();
SceneManager._scene = SceneManager._nextScene;
SceneManager._nextScene = null;
SceneManager._instnace.onSceneChanged();
SceneManager._scene.begin();
}
}
SceneManager.render();
}
public static render() {
if (this.sceneTransition){
this.sceneTransition.preRender();
if (this._scene && !this.sceneTransition.hasPreviousSceneRender){
this._scene.render();
this._scene.postRender();
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();
}
}
/**
* SceneTransition
* @param sceneTransition
*/
public static startSceneTransition<T extends SceneTransition>(sceneTransition: T): T {
if (this.sceneTransition) {
console.warn("在前一个场景完成之前,不能开始一个新的场景转换。");
return;
}
this.sceneTransition = sceneTransition;
return sceneTransition;
}
public static registerActiveSceneChanged(current: Scene, next: Scene){
if (this.activeSceneChanged)
this.activeSceneChanged(current, next);
}
/**
*
*/
public onSceneChanged(){
SceneManager.emitter.emit(CoreEvents.SceneChanged);
Time.sceneChanged();
}
}
@@ -1,8 +1,9 @@
///<reference path="./EntitySystem.ts" /> ///<reference path="./EntitySystem.ts" />
/** module es {
/**
* *
*/ */
abstract class EntityProcessingSystem extends EntitySystem { export abstract class EntityProcessingSystem extends EntitySystem {
constructor(matcher: Matcher) { constructor(matcher: Matcher) {
super(matcher); super(matcher);
} }
@@ -29,4 +30,5 @@ abstract class EntityProcessingSystem extends EntitySystem {
protected lateProcess(entities: Entity[]) { protected lateProcess(entities: Entity[]) {
entities.forEach(entity => this.lateProcessEntity(entity)); entities.forEach(entity => this.lateProcessEntity(entity));
} }
}
} }
+3 -1
View File
@@ -1,4 +1,5 @@
class EntitySystem { module es {
export class EntitySystem {
private _scene: Scene; private _scene: Scene;
private _entities: Entity[] = []; private _entities: Entity[] = [];
private _matcher: Matcher; private _matcher: Matcher;
@@ -76,4 +77,5 @@ class EntitySystem {
protected end(){ protected end(){
} }
}
} }
+3 -1
View File
@@ -1,4 +1,5 @@
abstract class PassiveSystem extends EntitySystem { module es {
export abstract class PassiveSystem extends EntitySystem {
public onChanged(entity: Entity){ public onChanged(entity: Entity){
} }
@@ -8,4 +9,5 @@ abstract class PassiveSystem extends EntitySystem {
this.begin(); this.begin();
this.end(); this.end();
} }
}
} }
+3 -1
View File
@@ -1,5 +1,6 @@
/** 用于协调其他系统的通用系统基类 */ /** 用于协调其他系统的通用系统基类 */
abstract class ProcessingSystem extends EntitySystem { module es {
export abstract class ProcessingSystem extends EntitySystem {
public onChanged(entity: Entity){ public onChanged(entity: Entity){
} }
@@ -12,4 +13,5 @@ abstract class ProcessingSystem extends EntitySystem {
/** 处理我们的系统 每帧调用 */ /** 处理我们的系统 每帧调用 */
public abstract processSystem(); public abstract processSystem();
}
} }
+504
View File
@@ -0,0 +1,504 @@
module transform {
export enum Component {
position,
scale,
rotation,
}
}
module es {
import HashObject = egret.HashObject;
export enum DirtyType {
clean,
positionDirty,
scaleDirty,
rotationDirty,
}
export class Transform extends HashObject {
/** 与此转换关联的实体 */
public readonly entity: Entity;
/**
*
*/
public get parent() {
return this._parent;
}
/**
*
* @param value
*/
public set parent(value: Transform) {
this.setParent(value);
}
/**
*
*/
public get childCount() {
return this._children.length;
}
/**
*
*/
public get position(): Vector2 {
this.updateTransform();
if (this._positionDirty){
if (!this.parent){
this._position = this._localPosition;
}else{
this.parent.updateTransform();
this._position = Vector2Ext.transformR(this._localPosition, this.parent._worldTransform);
}
this._positionDirty = false;
}
return this._position;
}
/**
*
* @param value
*/
public set position(value: Vector2){
this.setPosition(value.x, value.y);
}
/**
* transform.position相同
*/
public get localPosition(): Vector2 {
this.updateTransform();
return this._localPosition;
}
/**
* transform.position相同
* @param value
*/
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);
}
/**
* transform.scale相同
*/
public get localScale(): Vector2 {
this.updateTransform();
return this._localScale;
}
/**
* transform.scale相同
* @param value
*/
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[];
constructor(entity: Entity) {
super();
this.entity = entity;
this.scale = Vector2.one;
this._children = [];
}
/**
*
* @param index
*/
public getChild(index: number): Transform {
return this._children[index];
}
/**
*
* @param parent
*/
public setParent(parent: Transform): Transform {
if (this._parent.equals(parent))
return this;
if (!this._parent) {
this._parent._children.remove(this);
this._parent._children.push(this);
}
this._parent = parent;
this.setDirty(DirtyType.positionDirty);
return this;
}
/**
*
* @param x
* @param y
*/
public setPosition(x: number, y: number): Transform {
let position = new Vector2(x, y);
if (position.equals(this._position))
return this;
this._position = position;
if (this.parent){
this.localPosition = Vector2Ext.transformR(this._position, this._worldToLocalTransform);
} else {
this.localPosition = position;
}
this._positionDirty = false;
return this;
}
/**
* transform.position相同
* @param localPosition
*/
public setLocalPosition(localPosition: Vector2): Transform {
if (localPosition.equals(this._localPosition))
return this;
this._localPosition = localPosition;
this._localDirty = this._positionDirty = this._localPositionDirty = this._localRotationDirty = this._localScaleDirty = true;
this.setDirty(DirtyType.positionDirty);
return this;
}
/**
*
* @param radians
*/
public setRotation(radians: number): Transform {
this._rotation = radians;
if (this.parent){
this.localRotation = this.parent.rotation + radians;
} else {
this.localRotation = radians;
}
return this;
}
/**
*
* @param degrees
*/
public setRotationDegrees(degrees: number): Transform {
return this.setRotation(MathHelper.toRadians(degrees));
}
/**
* 使
* @param pos
*/
public lookAt(pos: Vector2) {
let sign = this.position.x > pos.x ? -1 : 1;
let vectorToAlignTo = Vector2.normalize(Vector2.subtract(this.position, pos));
this.rotation = sign * Math.acos(Vector2.dot(vectorToAlignTo, Vector2.unitY));
}
/**
* transform.rotation相同
* @param radians
*/
public setLocalRotation(radians: number){
this._localRotation = radians;
this._localDirty = this._positionDirty = this._localPositionDirty = this._localRotationDirty = this._localScaleDirty = true;
this.setDirty(DirtyType.rotationDirty);
return this;
}
/**
* transform.rotation相同
* @param degrees
*/
public setLocalRotationDegrees(degrees: number): Transform {
return this.setLocalRotation(MathHelper.toRadians(degrees));
}
/**
*
* @param scale
*/
public setScale(scale: Vector2): Transform {
this._scale = scale;
if (this.parent){
this.localScale = Vector2.divide(scale, this.parent._scale);
}else{
this.localScale = scale;
}
return this;
}
/**
* transform.scale相同
* @param scale
*/
public setLocalScale(scale: Vector2): Transform {
this._localScale = scale;
this._localDirty = this._positionDirty = this._localScaleDirty = true;
this.setDirty(DirtyType.scaleDirty);
return this;
}
/**
*
*/
public roundPosition() {
this.position = this._position.round();
}
public updateTransform(){
if (this.hierarchyDirty != DirtyType.clean){
if (this.parent)
this.parent.updateTransform();
if (this._localDirty){
if (this._localPositionDirty){
this._translationMatrix = Matrix2D.create().translate(this._localPosition.x, this._localPosition.y);
this._localPositionDirty = false;
}
if (this._localRotationDirty){
this._rotationMatrix = Matrix2D.create().rotate(this._localRotation);
this._localRotationDirty = false;
}
if (this._localScaleDirty){
this._scaleMatrix = Matrix2D.create().scale(this._localScale.x, this._localScale.y);
this._localScaleDirty = false;
}
this._localTransform = this._scaleMatrix.multiply(this._rotationMatrix);
this._localTransform = this._localTransform.multiply(this._translationMatrix);
if (!this.parent){
this._worldTransform = this._localTransform;
this._rotation = this._localRotation;
this._scale = this._localScale;
this._worldInverseDirty = true;
}
this._localDirty = false;
}
if (this.parent){
this._worldTransform = this._localTransform.multiply(this.parent._worldTransform);
this._rotation = this._localRotation + this.parent._rotation;
this._scale = Vector2.multiply(this.parent._scale, this._localScale);
this._worldInverseDirty = true;
}
this._worldToLocalDirty = true;
this._positionDirty = true;
this.hierarchyDirty = DirtyType.clean;
}
}
public setDirty(dirtyFlagType: DirtyType){
if ((this.hierarchyDirty & dirtyFlagType) == 0){
this.hierarchyDirty |= dirtyFlagType;
switch (dirtyFlagType) {
case es.DirtyType.positionDirty:
this.entity.onTransformChanged(transform.Component.position);
break;
case es.DirtyType.rotationDirty:
this.entity.onTransformChanged(transform.Component.rotation);
break;
case es.DirtyType.scaleDirty:
this.entity.onTransformChanged(transform.Component.scale);
break;
}
if (!this._children)
this._children = [];
// 告诉子项发生了变换
for (let i = 0; i < this._children.length; i ++)
this._children[i].setDirty(dirtyFlagType);
}
}
/**
* transform属性进行拷贝
* @param transform
*/
public copyFrom(transform: Transform) {
this._position = transform.position;
this._localPosition = transform._localPosition;
this._rotation = transform._rotation;
this._localRotation = transform._localRotation;
this._scale = transform._scale;
this._localScale = transform._localScale;
this.setDirty(DirtyType.positionDirty);
this.setDirty(DirtyType.rotationDirty);
this.setDirty(DirtyType.scaleDirty);
}
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){
return other.hashCode == this.hashCode;
}
}
}
+4 -2
View File
@@ -1,9 +1,10 @@
/** module es {
/**
* *
* *
* ; * ;
*/ */
class BitSet{ export class BitSet{
private static LONG_MASK: number = 0x3f; private static LONG_MASK: number = 0x3f;
private _bits: number[]; private _bits: number[];
@@ -130,4 +131,5 @@ class BitSet{
this.clear(pos); this.clear(pos);
} }
} }
}
} }
+81 -34
View File
@@ -1,12 +1,29 @@
class ComponentList { ///<reference path="../Components/IUpdatableComparer.ts" />
private _entity: Entity; module es {
/** 添加到实体的组件列表 */ export class ComponentList {
private _components: Component[] = []; /**
/** 添加到此框架的组件列表。用来对组件进行分组,这样我们就可以同时进行加工 */ * updateOrder排序
private _componentsToAdd: Component[] = []; */
/** 标记要删除此框架的组件列表。用来对组件进行分组,这样我们就可以同时进行加工 */ public static compareUpdatableOrder: IUpdatableComparer = new IUpdatableComparer();
private _componentsToRemove: Component[] = []; public _entity: Entity;
private _tempBufferList: Component[] = [];
/**
*
*/
public _components: Component[] = [];
/**
*
*/
public _componentsToAdd: Component[] = [];
/**
*
*/
public _componentsToRemove: Component[] = [];
public _tempBufferList: Component[] = [];
/**
*
*/
public _isComponentListUnsorted: boolean;
constructor(entity: Entity) { constructor(entity: Entity) {
this._entity = entity; this._entity = entity;
@@ -20,13 +37,17 @@ class ComponentList {
return this._components; return this._components;
} }
public markEntityListUnsorted(){
this._isComponentListUnsorted = true;
}
public add(component: Component) { public add(component: Component) {
this._componentsToAdd.push(component); this._componentsToAdd.push(component);
} }
public remove(component: Component) { public remove(component: Component) {
if (this._componentsToRemove.contains(component)) if (this._componentsToRemove.contains(component))
console.warn(`You are trying to remove a Component (${component}) that you already removed`) console.warn(`You are trying to remove a Component (${component}) that you already removed`);
// 这可能不是一个活动的组件,所以我们必须注意它是否还没有被处理,它可能正在同一帧中被删除 // 这可能不是一个活动的组件,所以我们必须注意它是否还没有被处理,它可能正在同一帧中被删除
if (this._componentsToAdd.contains(component)) { if (this._componentsToAdd.contains(component)) {
@@ -55,8 +76,11 @@ class ComponentList {
let component = this._components[i]; 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); this._entity.scene.renderableComponents.remove(component);
}
this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component), false); this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component), false);
this._entity.scene.entityProcessors.onComponentRemoved(this._entity); this._entity.scene.entityProcessors.onComponentRemoved(this._entity);
@@ -67,8 +91,10 @@ class ComponentList {
for (let i = 0; i < this._components.length; i++) { for (let i = 0; i < this._components.length; i++) {
let component = this._components[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); this._entity.scene.renderableComponents.add(component);
}
this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component)); this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component));
this._entity.scene.entityProcessors.onComponentAdded(this._entity); this._entity.scene.entityProcessors.onComponentAdded(this._entity);
@@ -91,8 +117,11 @@ class ComponentList {
if (this._componentsToAdd.length > 0) { if (this._componentsToAdd.length > 0) {
for (let i = 0, count = this._componentsToAdd.length; i < count; i++) { for (let i = 0, count = this._componentsToAdd.length; i < count; i++) {
let component = this._componentsToAdd[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); this._entity.scene.renderableComponents.add(component);
}
this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component)); this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component));
this._entity.scene.entityProcessors.onComponentAdded(this._entity); this._entity.scene.entityProcessors.onComponentAdded(this._entity);
@@ -103,6 +132,7 @@ class ComponentList {
// 在调用onAddedToEntity之前清除,以防添加更多组件 // 在调用onAddedToEntity之前清除,以防添加更多组件
this._componentsToAdd.length = 0; this._componentsToAdd.length = 0;
this._isComponentListUnsorted = true;
// 现在所有的组件都添加到了场景中,我们再次循环并调用onAddedToEntity/onEnabled // 现在所有的组件都添加到了场景中,我们再次循环并调用onAddedToEntity/onEnabled
for (let i = 0; i < this._tempBufferList.length; i++) { for (let i = 0; i < this._tempBufferList.length; i++) {
@@ -117,23 +147,20 @@ class ComponentList {
this._tempBufferList.length = 0; this._tempBufferList.length = 0;
} }
}
public onEntityTransformChanged(comp: TransformComponent) { if (this._isComponentListUnsorted){
for (let i = 0; i < this._components.length; i++) { this._components.sort(ComponentList.compareUpdatableOrder.compare);
if (this._components[i].enabled) this._isComponentListUnsorted = false;
this._components[i].onEntityTransformChanged(comp);
}
for (let i = 0; i < this._componentsToAdd.length; i++) {
if (this._componentsToAdd[i].enabled)
this._componentsToAdd[i].onEntityTransformChanged(comp);
} }
} }
private handleRemove(component: Component) { public handleRemove(component: Component) {
if (component instanceof RenderableComponent) // 处理渲染层列表
if (component instanceof RenderableComponent){
this._entity.scene.removeChild(component.displayObject);
this._entity.scene.renderableComponents.remove(component); this._entity.scene.renderableComponents.remove(component);
}
this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component), false); this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component), false);
this._entity.scene.entityProcessors.onComponentRemoved(this._entity); this._entity.scene.entityProcessors.onComponentRemoved(this._entity);
@@ -142,6 +169,7 @@ class ComponentList {
component.entity = null; component.entity = null;
} }
/** /**
* T的第一个组件并返回它 * T的第一个组件并返回它
* (onAddedToEntity方法的组件) * (onAddedToEntity方法的组件)
@@ -209,16 +237,35 @@ class ComponentList {
public update() { public update() {
this.updateLists(); this.updateLists();
for (let i = 0; i < this._components.length; i++) { for (let i = 0; i < this._components.length; i++) {
let updatable = this._components[i]; let updatableComponent = this._components[i];
let updateableComponent;
if (updatable instanceof Component)
updateableComponent = updatable as Component;
if (updatable.enabled && if (updatableComponent.enabled &&
updateableComponent.enabled && (updatableComponent.updateInterval == 1 ||
(updateableComponent.updateInterval == 1 || Time.frameCount % updatableComponent.updateInterval == 0))
Time.frameCount % updateableComponent.updateInterval == 0)) updatableComponent.update();
updatable.update(); }
}
public onEntityTransformChanged(comp: transform.Component) {
for (let i = 0; i < this._components.length; i++) {
if (this._components[i].enabled)
this._components[i].onEntityTransformChanged(comp);
}
for (let i = 0; i < this._componentsToAdd.length; i++) {
if (this._componentsToAdd[i].enabled)
this._componentsToAdd[i].onEntityTransformChanged(comp);
}
}
public onEntityEnabled() {
for (let i = 0; i < this._components.length; i++)
this._components[i].onEnabled();
}
public onEntityDisabled() {
for (let i = 0; i < this._components.length; i++)
this._components[i].onDisabled();
} }
} }
} }
+3 -1
View File
@@ -1,4 +1,5 @@
class ComponentTypeManager{ module es {
export class ComponentTypeManager{
private static _componentTypesMask: Map<any, number> = new Map<any, number>(); private static _componentTypesMask: Map<any, number> = new Map<any, number>();
public static add(type){ public static add(type){
@@ -15,4 +16,5 @@ class ComponentTypeManager{
return v; return v;
} }
}
} }
+178 -27
View File
@@ -1,11 +1,31 @@
class EntityList{ module es {
export class EntityList{
public scene: Scene; public scene: Scene;
private _entitiesToRemove: Entity[] = []; /**
private _entitiesToAdded: Entity[] = []; *
private _tempEntityList: Entity[] = []; */
private _entities: Entity[] = []; public _entities: Entity[] = [];
private _entityDict: Map<number, Entity[]> = new Map<number, Entity[]>(); /**
private _unsortedTags: number[] = []; * 便
*/
public _entitiesToAdded: Entity[] = [];
/**
* 便
*/
public _entitiesToRemove: Entity[] = [];
/**
*
*/
public _isEntityListUnsorted: boolean;
/**
* 便
*/
public _entityDict: Map<number, Entity[]> = new Map<number, Entity[]>();
public _unsortedTags: number[] = [];
/**
* updateLists中用于双缓冲区便
*/
public _tempEntityList: Entity[] = [];
constructor(scene: Scene){ constructor(scene: Scene){
this.scene = scene; this.scene = scene;
@@ -19,12 +39,34 @@ class EntityList{
return this._entities; return this._entities;
} }
public markEntityListUnsorted(){
this._isEntityListUnsorted = true;
}
public markTagUnsorted(tag: number){
this._unsortedTags.push(tag);
}
/**
*
* @param entity
*/
public add(entity: Entity){ public add(entity: Entity){
if (this._entitiesToAdded.indexOf(entity) == -1) if (this._entitiesToAdded.indexOf(entity) == -1)
this._entitiesToAdded.push(entity); this._entitiesToAdded.push(entity);
} }
/**
*
* @param entity
*/
public remove(entity: 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); this._entitiesToAdded.remove(entity);
return; return;
@@ -34,13 +76,34 @@ class EntityList{
this._entitiesToRemove.push(entity); this._entitiesToRemove.push(entity);
} }
public findEntity(name: string){ /**
*
*/
public removeAllEntities(){
this._unsortedTags.length = 0;
this._entitiesToAdded.length = 0;
this._isEntityListUnsorted = false;
// 为什么我们要在这里更新列表?主要用于处理场景切换前分离的实体。
// 它们仍然在_entitiesToRemove列表中,该列表将由更新列表处理。
this.updateLists();
for (let i = 0; i < this._entities.length; i ++){ for (let i = 0; i < this._entities.length; i ++){
if (this._entities[i].name == name) this._entities[i]._isDestroyed = true;
return this._entities[i]; this._entities[i].onRemovedFromScene();
this._entities[i].scene = null;
} }
return this._entitiesToAdded.firstOrDefault(entity => entity.name == name); this._entities.length = 0;
this._entityDict.clear();
}
/**
* EntityList管理
* @param entity
*/
public contains(entity: Entity): boolean {
return this._entities.contains(entity) || this._entitiesToAdded.contains(entity);
} }
public getTagList(tag: number){ public getTagList(tag: number){
@@ -71,33 +134,21 @@ class EntityList{
public update(){ public update(){
for (let i = 0; i < this._entities.length; i++){ for (let i = 0; i < this._entities.length; i++){
let entity = this._entities[i]; let entity = this._entities[i];
if (entity.enabled) if (entity.enabled && (entity.updateInterval == 1 || Time.frameCount % entity.updateInterval == 0))
entity.update(); entity.update();
} }
} }
public removeAllEntities(){
this._entitiesToAdded.length = 0;
this.updateLists();
for (let i = 0; i < this._entities.length; i ++){
this._entities[i]._isDestoryed = true;
this._entities[i].onRemovedFromScene();
this._entities[i].scene = null;
}
this._entities.length = 0;
this._entityDict.clear();
}
public updateLists(){ public updateLists(){
if (this._entitiesToRemove.length > 0){ if (this._entitiesToRemove.length > 0){
let temp = this._entitiesToRemove; let temp = this._entitiesToRemove;
this._entitiesToRemove = this._tempEntityList; this._entitiesToRemove = this._tempEntityList;
this._tempEntityList = temp; this._tempEntityList = temp;
this._tempEntityList.forEach(entity => { this._tempEntityList.forEach(entity => {
this.removeFromTagList(entity);
this._entities.remove(entity); this._entities.remove(entity);
entity.onRemovedFromScene();
entity.scene = null; entity.scene = null;
this.scene.entityProcessors.onEntityRemoved(entity); this.scene.entityProcessors.onEntityRemoved(entity);
@@ -115,12 +166,21 @@ class EntityList{
this._entities.push(entity); this._entities.push(entity);
entity.scene = this.scene; entity.scene = this.scene;
this.addToTagList(entity);
this.scene.entityProcessors.onEntityAdded(entity) this.scene.entityProcessors.onEntityAdded(entity)
} }
}); });
// 现在所有实体都被添加到场景中,我们再次循环并调用onAddedToScene
this._tempEntityList.forEach(entity => entity.onAddedToScene()); this._tempEntityList.forEach(entity => entity.onAddedToScene());
this._tempEntityList.length = 0; this._tempEntityList.length = 0;
this._isEntityListUnsorted = true;
}
if (this._isEntityListUnsorted){
this._entities.sort();
this._isEntityListUnsorted = false;
} }
if (this._unsortedTags.length > 0){ if (this._unsortedTags.length > 0){
@@ -131,4 +191,95 @@ class EntityList{
this._unsortedTags.length = 0; this._unsortedTags.length = 0;
} }
} }
/**
* null
* @param name
*/
public findEntity(name: string){
for (let i = 0; i < this._entities.length; i ++){
if (this._entities[i].name == name)
return this._entities[i];
}
return this._entitiesToAdded.firstOrDefault(entity => entity.name == name);
}
/**
* ListPool.free将返回的列表放回池中
* @param tag
*/
public entitiesWithTag(tag: number){
let list = this.getTagList(tag);
let returnList = ListPool.obtain<Entity>();
for (let i = 0; i < list.length; i ++)
returnList.push(list[i]);
return returnList;
}
/**
* t类型的所有实体的列表ListPool.free放回池中
* @param type
*/
public entitiesOfType<T extends Entity>(type): T[]{
let list = ListPool.obtain<T>();
for (let i = 0; i < this._entities.length; i ++){
if (this._entities[i] instanceof type)
list.push(this._entities[i] as T);
}
this._entitiesToAdded.forEach(entity => {
if (entity instanceof type)
list.push(entity as T);
});
return list;
}
/**
* T的场景中找到的第一个组件
* @param type
*/
public findComponentOfType<T extends Component>(type): T {
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 ++){
let entity = this._entitiesToAdded[i];
if (entity.enabled){
let comp = entity.getComponent<T>(type);
if (comp)
return comp;
}
}
return null;
}
/**
* t的场景中找到的所有组件ListPool.free放回池中
* @param type
*/
public findComponentsOfType<T extends Component>(type): T[]{
let comps = ListPool.obtain<T>();
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 ++){
let entity = this._entitiesToAdded[i];
if (entity.enabled)
entity.getComponents(type,comps);
}
return comps;
}
}
} }
+3 -1
View File
@@ -1,4 +1,5 @@
class EntityProcessorList { module es {
export class EntityProcessorList {
private _processors: EntitySystem[] = []; private _processors: EntitySystem[] = [];
public add(processor: EntitySystem){ public add(processor: EntitySystem){
@@ -66,4 +67,5 @@ class EntityProcessorList {
return null; return null;
} }
}
} }
+3 -1
View File
@@ -1,4 +1,5 @@
class Matcher{ module es {
export class Matcher{
protected allSet = new BitSet(); protected allSet = new BitSet();
protected exclusionSet = new BitSet(); protected exclusionSet = new BitSet();
protected oneSet = new BitSet(); protected oneSet = new BitSet();
@@ -59,4 +60,5 @@ class Matcher{
return this; return this;
} }
}
} }
@@ -1,22 +1,101 @@
class RenderableComponentList { ///<reference path="../../Graphics/Renderers/IRenderable.ts" />
private _components: IRenderable[] = []; module es {
public get count(){ export class RenderableComponentList {
/**
* IRenderable列表的全局updatePrder排序
*/
public static compareUpdatableOrder = new RenderableComparer();
/**
*
*/
public _components: IRenderable[] = [];
/**
* 便
*/
public _componentsByRenderLayer: Map<number, IRenderable[]> = new Map<number, IRenderable[]>();
public _unsortedRenderLayers: number[] = [];
public _componentsNeedSort: boolean = true;
public get count() {
return this._components.length; return this._components.length;
} }
public get buffer(){ public get buffer() {
return this._components; return this._components;
} }
public add(component: IRenderable){ public add(component: IRenderable) {
this._components.push(component); this._components.push(component);
this.addToRenderLayerList(component, component.renderLayer);
} }
public remove(component: IRenderable){ public remove(component: IRenderable) {
this._components.remove(component); this._components.remove(component);
this._componentsByRenderLayer.get(component.renderLayer).remove(component);
} }
public updateList(){ public updateRenderableRenderLayer(component: IRenderable, oldRenderLayer: number, newRenderLayer: number) {
// 需要注意的是,如果渲染层在组件update之前发生了改变
if (this._componentsByRenderLayer.has(oldRenderLayer) && this._componentsByRenderLayer.get(oldRenderLayer).contains(component)) {
this._componentsByRenderLayer.get(oldRenderLayer).remove(component);
this.addToRenderLayerList(component, newRenderLayer);
}
}
/**
*
* @param renderLayer
*/
public setRenderLayerNeedsComponentSort(renderLayer: number) {
if (!this._unsortedRenderLayers.contains(renderLayer))
this._unsortedRenderLayers.push(renderLayer);
this._componentsNeedSort = true;
}
public setNeedsComponentSort() {
this._componentsNeedSort = true;
}
public addToRenderLayerList(component: IRenderable, renderLayer: number) {
let list = this.componentsWithRenderLayer(renderLayer);
if (!list.contains(component)) {
console.warn("Component renderLayer list already contains this component");
return;
}
list.push(component);
if (!this._unsortedRenderLayers.contains(renderLayer))
this._unsortedRenderLayers.push(renderLayer);
this._componentsNeedSort = true;
}
/**
* 使
* @param renderLayer
*/
public componentsWithRenderLayer(renderLayer: number): IRenderable[] {
if (!this._componentsByRenderLayer.get(renderLayer)) {
this._componentsByRenderLayer.set(renderLayer, []);
}
return this._componentsByRenderLayer.get(renderLayer);
}
public updateList() {
if (this._componentsNeedSort) {
this._components.sort(RenderableComponentList.compareUpdatableOrder.compare);
this._componentsNeedSort = false;
}
if (this._unsortedRenderLayers.length > 0) {
for (let i = 0, count = this._unsortedRenderLayers.length; i < count; i++) {
let renderLayerComponents = this._componentsByRenderLayer.get(this._unsortedRenderLayers[i]);
if (renderLayerComponents) {
renderLayerComponents.sort(RenderableComponentList.compareUpdatableOrder.compare);
}
}
this._unsortedRenderLayers.length = 0;
}
}
} }
} }
+5 -3
View File
@@ -1,7 +1,8 @@
/** module es {
/**
* *
*/ */
class TextureUtils { export class TextureUtils {
public static sharedCanvas: HTMLCanvasElement; public static sharedCanvas: HTMLCanvasElement;
public static sharedContext: CanvasRenderingContext2D; public static sharedContext: CanvasRenderingContext2D;
@@ -77,7 +78,7 @@ class TextureUtils {
let offsetY: number = Math.round(bitmapData.$offsetY); let offsetY: number = Math.round(bitmapData.$offsetY);
let bitmapWidth: number = bitmapData.$bitmapWidth; let bitmapWidth: number = bitmapData.$bitmapWidth;
let bitmapHeight: number = bitmapData.$bitmapHeight; let bitmapHeight: number = bitmapData.$bitmapHeight;
let $TextureScaleFactor = SceneManager.stage.textureScaleFactor; let $TextureScaleFactor = Core._instance.stage.textureScaleFactor;
this.sharedContext.drawImage(bitmapData.$bitmapData.source, bitmapData.$bitmapX + rect.x / $TextureScaleFactor, bitmapData.$bitmapY + rect.y / $TextureScaleFactor, this.sharedContext.drawImage(bitmapData.$bitmapData.source, bitmapData.$bitmapX + rect.x / $TextureScaleFactor, bitmapData.$bitmapY + rect.y / $TextureScaleFactor,
bitmapWidth * rect.width / w, bitmapHeight * rect.height / h, offsetX, offsetY, rect.width, rect.height); bitmapWidth * rect.width / w, bitmapHeight * rect.height / h, offsetX, offsetY, rect.width, rect.height);
return surface; return surface;
@@ -151,4 +152,5 @@ class TextureUtils {
egret.$error(1039); egret.$error(1039);
} }
} }
}
} }
+4 -2
View File
@@ -1,5 +1,6 @@
/** 提供帧定时信息 */ module es {
class Time { /** 提供帧定时信息 */
export class Time {
/** deltaTime的未缩放版本。不受时间尺度的影响 */ /** deltaTime的未缩放版本。不受时间尺度的影响 */
public static unscaledDeltaTime; public static unscaledDeltaTime;
/** 前一帧到当前帧的时间增量,按时间刻度进行缩放 */ /** 前一帧到当前帧的时间增量,按时间刻度进行缩放 */
@@ -35,4 +36,5 @@ class Time {
// 我们减去了delta,因为timeSinceSceneLoad已经包含了这个update ticks delta // 我们减去了delta,因为timeSinceSceneLoad已经包含了这个update ticks delta
return (this._timeSinceSceneLoad / interval) > ((this._timeSinceSceneLoad - this.deltaTime) / interval); return (this._timeSinceSceneLoad / interval) > ((this._timeSinceSceneLoad - this.deltaTime) / interval);
} }
}
} }
+54 -43
View File
@@ -4,84 +4,100 @@ declare interface Array<T> {
* @param predicate * @param predicate
*/ */
findIndex(predicate: Function): number; findIndex(predicate: Function): number;
/** /**
* *
* @param predicate * @param predicate
*/ */
any(predicate: Function): boolean; any(predicate: Function): boolean;
/** /**
* *
* @param predicate * @param predicate
*/ */
firstOrDefault(predicate: Function): T; firstOrDefault(predicate: Function): T;
/** /**
* *
* @param predicate * @param predicate
*/ */
find(predicate: Function): T; find(predicate: Function): T;
/** /**
* *
* @param predicate * @param predicate
*/ */
where(predicate: Function): Array<T>; where(predicate: Function): Array<T>;
/** /**
* *
* @param predicate * @param predicate
*/ */
count(predicate: Function): number; count(predicate: Function): number;
/** /**
* *
* @param predicate * @param predicate
*/ */
findAll(predicate: Function): Array<T>; findAll(predicate: Function): Array<T>;
/** /**
* *
* @param value * @param value
*/ */
contains(value): boolean; contains(value): boolean;
/** /**
* *
* @param predicate * @param predicate
*/ */
removeAll(predicate: Function): void; removeAll(predicate: Function): void;
/** /**
* *
* @param element * @param element
*/ */
remove(element: T): boolean; remove(element: T): boolean;
/** /**
* *
* @param index * @param index
*/ */
removeAt(index): void; removeAt(index): void;
/** /**
* *
* @param index * @param index
* @param count * @param count
*/ */
removeRange(index, count): void; removeRange(index, count): void;
/** /**
* *
* @param selector * @param selector
*/ */
select(selector: Function): Array<T>; select(selector: Function): Array<T>;
/** /**
* *
* @param keySelector key选择器 * @param keySelector key选择器
* @param comparer * @param comparer
*/ */
orderBy(keySelector: Function, comparer: Function): Array<T>; orderBy(keySelector: Function, comparer: Function): Array<T>;
/** /**
* *
* @param keySelector key选择器 * @param keySelector key选择器
* @param comparer * @param comparer
*/ */
orderByDescending(keySelector: Function, comparer: Function): Array<T>; orderByDescending(keySelector: Function, comparer: Function): Array<T>;
/** /**
* *
* @param keySelector key选择器 * @param keySelector key选择器
*/ */
groupBy(keySelector: Function): Array<T>; groupBy(keySelector: Function): Array<T>;
/** /**
* *
* @param selector * @param selector
@@ -101,7 +117,7 @@ Array.prototype.findIndex = function (predicate) {
} }
return findIndex(this, predicate); return findIndex(this, predicate);
} };
Array.prototype.any = function (predicate) { Array.prototype.any = function (predicate) {
function any(array, predicate) { function any(array, predicate) {
@@ -109,7 +125,7 @@ Array.prototype.any = function (predicate) {
} }
return any(this, predicate); return any(this, predicate);
} };
Array.prototype.firstOrDefault = function (predicate) { Array.prototype.firstOrDefault = function (predicate) {
function firstOrDefault(array, predicate) { function firstOrDefault(array, predicate) {
@@ -118,7 +134,7 @@ Array.prototype.firstOrDefault = function (predicate) {
} }
return firstOrDefault(this, predicate); return firstOrDefault(this, predicate);
} };
Array.prototype.find = function (predicate) { Array.prototype.find = function (predicate) {
function find(array, predicate) { function find(array, predicate) {
@@ -126,7 +142,7 @@ Array.prototype.find = function (predicate) {
} }
return find(this, predicate); return find(this, predicate);
} };
Array.prototype.where = function (predicate) { Array.prototype.where = function (predicate) {
function where(array, predicate) { function where(array, predicate) {
@@ -138,8 +154,7 @@ Array.prototype.where = function (predicate) {
return ret; return ret;
}, []); }, []);
} } else {
else {
let ret = []; let ret = [];
for (let i = 0, len = array.length; i < len; i++) { for (let i = 0, len = array.length; i < len; i++) {
let element = array[i]; let element = array[i];
@@ -153,7 +168,7 @@ Array.prototype.where = function (predicate) {
} }
return where(this, predicate); return where(this, predicate);
} };
Array.prototype.count = function (predicate) { Array.prototype.count = function (predicate) {
function count(array, predicate) { function count(array, predicate) {
@@ -161,7 +176,7 @@ Array.prototype.count = function (predicate) {
} }
return count(this, predicate); return count(this, predicate);
} };
Array.prototype.findAll = function (predicate) { Array.prototype.findAll = function (predicate) {
function findAll(array, predicate) { function findAll(array, predicate) {
@@ -169,7 +184,7 @@ Array.prototype.findAll = function (predicate) {
} }
return findAll(this, predicate); return findAll(this, predicate);
} };
Array.prototype.contains = function (value) { Array.prototype.contains = function (value) {
function contains(array, value) { function contains(array, value) {
@@ -183,7 +198,7 @@ Array.prototype.contains = function (value) {
} }
return contains(this, value); return contains(this, value);
} };
Array.prototype.removeAll = function (predicate) { Array.prototype.removeAll = function (predicate) {
function removeAll(array, predicate) { function removeAll(array, predicate) {
@@ -198,7 +213,7 @@ Array.prototype.removeAll = function (predicate) {
} }
removeAll(this, predicate); removeAll(this, predicate);
} };
Array.prototype.remove = function (element) { Array.prototype.remove = function (element) {
function remove(array, element) { function remove(array, element) {
@@ -209,14 +224,13 @@ Array.prototype.remove = function (element) {
if (index >= 0) { if (index >= 0) {
array.splice(index, 1); array.splice(index, 1);
return true; return true;
} } else {
else {
return false; return false;
} }
} }
return remove(this, element); return remove(this, element);
} };
Array.prototype.removeAt = function (index) { Array.prototype.removeAt = function (index) {
function removeAt(array, index) { function removeAt(array, index) {
@@ -224,7 +238,7 @@ Array.prototype.removeAt = function (index) {
} }
return removeAt(this, index); return removeAt(this, index);
} };
Array.prototype.removeRange = function (index, count) { Array.prototype.removeRange = function (index, count) {
function removeRange(array, index, count) { function removeRange(array, index, count) {
@@ -232,7 +246,7 @@ Array.prototype.removeRange = function (index, count) {
} }
return removeRange(this, index, count); return removeRange(this, index, count);
} };
Array.prototype.select = function (selector) { Array.prototype.select = function (selector) {
function select(array, selector) { function select(array, selector) {
@@ -241,8 +255,7 @@ Array.prototype.select = function (selector) {
ret.push(selector.call(arguments[2], element, index, array)); ret.push(selector.call(arguments[2], element, index, array));
return ret; return ret;
}, []); }, []);
} } else {
else {
let ret = []; let ret = [];
for (let i = 0, len = array.length; i < len; i++) { for (let i = 0, len = array.length; i < len; i++) {
ret.push(selector.call(arguments[2], array[i], i, array)) ret.push(selector.call(arguments[2], array[i], i, array))
@@ -253,17 +266,16 @@ Array.prototype.select = function (selector) {
} }
return select(this, selector); return select(this, selector);
} };
Array.prototype.orderBy = function (keySelector, comparer) { Array.prototype.orderBy = function (keySelector, comparer) {
function orderBy(array, keySelector, comparer) { function orderBy(array, keySelector, comparer) {
array.sort(function (x, y) { array.sort(function (x, y) {
let v1 = keySelector(x) let v1 = keySelector(x);
let v2 = keySelector(y) let v2 = keySelector(y);
if (comparer) { if (comparer) {
return comparer(v1, v2); return comparer(v1, v2);
} } else {
else {
return (v1 > v2) ? 1 : -1; return (v1 > v2) ? 1 : -1;
} }
}); });
@@ -272,17 +284,16 @@ Array.prototype.orderBy = function (keySelector, comparer) {
} }
return orderBy(this, keySelector, comparer); return orderBy(this, keySelector, comparer);
} };
Array.prototype.orderByDescending = function (keySelector, comparer) { Array.prototype.orderByDescending = function (keySelector, comparer) {
function orderByDescending(array, keySelector, comparer) { function orderByDescending(array, keySelector, comparer) {
array.sort(function (x, y) { array.sort(function (x, y) {
let v1 = keySelector(x) let v1 = keySelector(x);
let v2 = keySelector(y) let v2 = keySelector(y);
if (comparer) { if (comparer) {
return -comparer(v1, v2); return -comparer(v1, v2);
} } else {
else {
return (v1 < v2) ? 1 : -1; return (v1 < v2) ? 1 : -1;
} }
}); });
@@ -291,7 +302,7 @@ Array.prototype.orderByDescending = function (keySelector, comparer) {
} }
return orderByDescending(this, keySelector, comparer); return orderByDescending(this, keySelector, comparer);
} };
Array.prototype.groupBy = function (keySelector) { Array.prototype.groupBy = function (keySelector) {
function groupBy(array, keySelector) { function groupBy(array, keySelector) {
@@ -299,7 +310,9 @@ Array.prototype.groupBy = function (keySelector) {
let keys = []; let keys = [];
return array.reduce(function (groups, element, index) { 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 }); let index2 = keys.findIndex(function (x) {
return x === key;
});
if (index2 < 0) { if (index2 < 0) {
index2 = keys.push(key) - 1; index2 = keys.push(key) - 1;
@@ -312,13 +325,14 @@ Array.prototype.groupBy = function (keySelector) {
groups[index2].push(element); groups[index2].push(element);
return groups; return groups;
}, []); }, []);
} } else {
else {
let groups = []; let groups = [];
let keys = []; let keys = [];
for (let i = 0, len = array.length; i < len; i++) { for (let i = 0, len = array.length; i < len; i++) {
let key = JSON.stringify(keySelector.call(arguments[1], array[i], i, array)); let key = JSON.stringify(keySelector.call(arguments[1], array[i], i, array));
let index = keys.findIndex(function (x) { return x === key }); let index = keys.findIndex(function (x) {
return x === key;
});
if (index < 0) { if (index < 0) {
index = keys.push(key) - 1; index = keys.push(key) - 1;
@@ -336,7 +350,7 @@ Array.prototype.groupBy = function (keySelector) {
} }
return groupBy(this, keySelector); return groupBy(this, keySelector);
} };
Array.prototype.sum = function (selector) { Array.prototype.sum = function (selector) {
function sum(array, selector) { function sum(array, selector) {
@@ -345,17 +359,14 @@ Array.prototype.sum = function (selector) {
if (i == 0) { if (i == 0) {
if (selector) { if (selector) {
ret = selector.call(arguments[2], array[i], i, array); ret = selector.call(arguments[2], array[i], i, array);
} else {
ret = array[i];
} }
else { } else {
ret = array[i]
}
}
else {
if (selector) { if (selector) {
ret += selector.call(arguments[2], array[i], i, array); ret += selector.call(arguments[2], array[i], i, array);
} } else {
else { ret += array[i];
ret += array[i]
} }
} }
} }
@@ -364,4 +375,4 @@ Array.prototype.sum = function (selector) {
} }
return sum(this, selector); return sum(this, selector);
} };
@@ -1,4 +1,5 @@
class GaussianBlurEffect extends egret.CustomFilter { module es {
export class GaussianBlurEffect extends egret.CustomFilter {
// private static blur_frag = "precision mediump float;\n" + // private static blur_frag = "precision mediump float;\n" +
// "uniform vec2 blur;\n" + // "uniform vec2 blur;\n" +
// "uniform sampler2D uSampler;\n" + // "uniform sampler2D uSampler;\n" +
@@ -65,8 +66,9 @@ class GaussianBlurEffect extends egret.CustomFilter {
constructor(){ constructor(){
super(PostProcessor.default_vert, GaussianBlurEffect.blur_frag,{ super(PostProcessor.default_vert, GaussianBlurEffect.blur_frag,{
screenWidth: SceneManager.stage.stageWidth, screenWidth: Core.graphicsDevice.viewport.width,
screenHeight: SceneManager.stage.stageHeight screenHeight: Core.graphicsDevice.viewport.height
}); });
} }
}
} }
@@ -1,4 +1,5 @@
class PolygonLightEffect extends egret.CustomFilter { module es {
export class PolygonLightEffect extends egret.CustomFilter {
private static vertSrc = "attribute vec2 aVertexPosition;\n" + private static vertSrc = "attribute vec2 aVertexPosition;\n" +
"attribute vec2 aTextureCoord;\n" + "attribute vec2 aTextureCoord;\n" +
@@ -31,4 +32,5 @@ class PolygonLightEffect extends egret.CustomFilter {
constructor(){ constructor(){
super(PolygonLightEffect.vertSrc, PolygonLightEffect.fragmentSrc); super(PolygonLightEffect.vertSrc, PolygonLightEffect.fragmentSrc);
} }
}
} }
+5 -1
View File
@@ -1,10 +1,13 @@
class GraphicsCapabilities extends egret.Capabilities { module es {
export class GraphicsCapabilities extends egret.Capabilities {
public initialize(device: GraphicsDevice){ public initialize(device: GraphicsDevice){
this.platformInitialize(device); this.platformInitialize(device);
} }
private platformInitialize(device: GraphicsDevice){ private platformInitialize(device: GraphicsDevice){
if (GraphicsCapabilities.runtimeType != egret.RuntimeType.WXGAME)
return;
let capabilities = this; let capabilities = this;
capabilities["isMobile"] = true; capabilities["isMobile"] = true;
@@ -24,4 +27,5 @@ class GraphicsCapabilities extends egret.Capabilities {
} }
capabilities["language"] = language; capabilities["language"] = language;
} }
}
} }
+12 -2
View File
@@ -1,10 +1,20 @@
class GraphicsDevice { module es {
private viewport: Viewport; export class GraphicsDevice {
private _viewport: Viewport;
public get viewport(): Viewport{
return this._viewport;
}
public graphicsCapabilities: GraphicsCapabilities; public graphicsCapabilities: GraphicsCapabilities;
constructor(){ constructor(){
this.setup();
this.graphicsCapabilities = new GraphicsCapabilities(); this.graphicsCapabilities = new GraphicsCapabilities();
this.graphicsCapabilities.initialize(this); this.graphicsCapabilities.initialize(this);
} }
private setup(){
this._viewport = new Viewport(0, 0, Core._instance.stage.stageWidth, Core._instance.stage.stageHeight);
}
}
} }
@@ -1,5 +1,6 @@
class PostProcessor { module es {
public enable: boolean; export class PostProcessor {
public enabled: boolean;
public effect: egret.Filter; public effect: egret.Filter;
public scene: Scene; public scene: Scene;
public shape: egret.Shape; public shape: egret.Shape;
@@ -23,7 +24,7 @@ class PostProcessor {
"}"; "}";
constructor(effect: egret.Filter = null){ constructor(effect: egret.Filter = null){
this.enable = true; this.enabled = true;
this.effect = effect; this.effect = effect;
} }
@@ -31,7 +32,7 @@ class PostProcessor {
this.scene = scene; this.scene = scene;
this.shape = new egret.Shape(); this.shape = new egret.Shape();
this.shape.graphics.beginFill(0xFFFFFF, 1); this.shape.graphics.beginFill(0xFFFFFF, 1);
this.shape.graphics.drawRect(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); this.shape.graphics.drawRect(0, 0, Core.graphicsDevice.viewport.width, Core.graphicsDevice.viewport.height);
this.shape.graphics.endFill(); this.shape.graphics.endFill();
scene.addChild(this.shape); scene.addChild(this.shape);
} }
@@ -55,4 +56,5 @@ class PostProcessor {
this.scene.removeChild(this.shape); this.scene.removeChild(this.shape);
this.scene = null; this.scene = null;
} }
}
} }
@@ -1,6 +1,8 @@
class GaussianBlurPostProcessor extends PostProcessor { module es {
export class GaussianBlurPostProcessor extends PostProcessor {
public onAddedToScene(scene: Scene){ public onAddedToScene(scene: Scene){
super.onAddedToScene(scene); super.onAddedToScene(scene);
this.effect = new GaussianBlurEffect(); this.effect = new GaussianBlurEffect();
} }
}
} }
@@ -1,5 +1,10 @@
///<reference path="./Renderer.ts" /> ///<reference path="./Renderer.ts" />
class DefaultRenderer extends Renderer { module es {
export class DefaultRenderer extends Renderer {
constructor(){
super(0, null);
}
public render(scene: Scene) { public render(scene: Scene) {
let cam = this.camera ? this.camera : scene.camera; let cam = this.camera ? this.camera : scene.camera;
this.beginRender(cam); this.beginRender(cam);
@@ -10,4 +15,5 @@ class DefaultRenderer extends Renderer {
this.renderAfterStateCheck(renderable, cam); this.renderAfterStateCheck(renderable, cam);
} }
} }
}
} }
+41 -1
View File
@@ -1,7 +1,47 @@
interface IRenderable { module es {
/**
*
*
*/
export interface IRenderable {
/**
* AABB用于相机剔除
*/
bounds: Rectangle; bounds: Rectangle;
/**
*
*/
enabled: boolean; enabled: boolean;
/**
*
*/
renderLayer: number;
/**
* onBecameVisible/onBecameInvisible方法
*/
isVisible: boolean; isVisible: boolean;
/**
* renderableComponent的边界与camera.bounds相交 true
* isVisible标志的状态开关
* 使
* @param camera
*/
isVisibleFromCamera(camera: Camera); isVisibleFromCamera(camera: Camera);
/**
* 使
* @param camera
*/
render(camera: Camera); render(camera: Camera);
}
/**
* IRenderables的比较器
*/
export class RenderableComparer {
public compare(self: IRenderable, other: IRenderable){
return other.renderLayer - self.renderLayer;
}
}
} }
@@ -1,4 +1,5 @@
class PolyLight extends RenderableComponent { module es {
export class PolyLight extends RenderableComponent {
public power: number; public power: number;
protected _radius: number; protected _radius: number;
private _lightEffect; private _lightEffect;
@@ -43,4 +44,5 @@ class PolyLight extends RenderableComponent {
public reset(){ public reset(){
} }
}
} }
+33 -8
View File
@@ -1,13 +1,23 @@
/** module es {
/**
* RenderableComponent的实际调用 * RenderableComponent的实际调用
*/ */
abstract class Renderer { export abstract class Renderer {
/** /**
* () * ()
* *
* Renderer子类可以选择调用beginRender时使用的摄像头 * Renderer子类可以选择调用beginRender时使用的摄像头
*/ */
public camera: Camera; public camera: Camera;
/**
*
*/
public readonly renderOrder: number = 0;
protected constructor(renderOrder: number, camera: Camera = null){
this.camera = camera;
this.renderOrder = renderOrder;
}
/** /**
* *
@@ -15,17 +25,18 @@ abstract class Renderer {
*/ */
public onAddedToScene(scene: Scene){} public onAddedToScene(scene: Scene){}
protected beginRender(cam: Camera){ /**
* 使
} */
public unload(){ }
/** /**
* *
* @param scene * @param cam
*/ */
public abstract render(scene: Scene); protected beginRender(cam: Camera){ }
public unload(){ } public abstract render(scene: Scene);
/** /**
* *
@@ -35,4 +46,18 @@ abstract class Renderer {
protected renderAfterStateCheck(renderable: IRenderable, cam: Camera){ protected renderAfterStateCheck(renderable: IRenderable, cam: Camera){
renderable.render(cam); renderable.render(cam);
} }
/**
*
* @param newWidth
* @param newHeight
*/
public onSceneBackBufferSizeChanged(newWidth: number, newHeight: number){
}
public compareTo(other: Renderer): number{
return this.renderOrder - other.renderOrder;
}
}
} }
@@ -1,7 +1,9 @@
/** module es {
/**
* 使 * 使
*/ */
class ScreenSpaceRenderer extends Renderer { export class ScreenSpaceRenderer extends Renderer {
public render(scene: Scene) { public render(scene: Scene) {
} }
}
} }
@@ -1,5 +1,6 @@
///<reference path="./SceneTransition.ts"/> ///<reference path="./SceneTransition.ts"/>
class FadeTransition extends SceneTransition { module es {
export class FadeTransition extends SceneTransition {
public fadeToColor: number = 0x000000; public fadeToColor: number = 0x000000;
public fadeOutDuration = 0.4; public fadeOutDuration = 0.4;
public fadeEaseType: Function = egret.Ease.quadInOut; public fadeEaseType: Function = egret.Ease.quadInOut;
@@ -14,9 +15,8 @@ class FadeTransition extends SceneTransition {
public async onBeginTransition() { public async onBeginTransition() {
this._mask.graphics.beginFill(this.fadeToColor, 1); this._mask.graphics.beginFill(this.fadeToColor, 1);
this._mask.graphics.drawRect(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); this._mask.graphics.drawRect(0, 0, Core.graphicsDevice.viewport.width, Core.graphicsDevice.viewport.height);
this._mask.graphics.endFill(); this._mask.graphics.endFill();
SceneManager.stage.addChild(this._mask);
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 () => { .call(async () => {
@@ -24,7 +24,6 @@ class FadeTransition extends SceneTransition {
}).wait(this.delayBeforeFadeInDuration).call(() => { }).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(); this.transitionComplete();
SceneManager.stage.removeChild(this._mask);
}); });
}); });
} }
@@ -32,7 +31,8 @@ class FadeTransition extends SceneTransition {
public render(){ public render(){
this._mask.graphics.clear(); this._mask.graphics.clear();
this._mask.graphics.beginFill(this.fadeToColor, this._alpha); this._mask.graphics.beginFill(this.fadeToColor, this._alpha);
this._mask.graphics.drawRect(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); this._mask.graphics.drawRect(0, 0, Core.graphicsDevice.viewport.width, Core.graphicsDevice.viewport.height);
this._mask.graphics.endFill(); this._mask.graphics.endFill();
} }
}
} }
@@ -1,7 +1,8 @@
/** module es {
/**
* SceneTransition用于从一个场景过渡到另一个场景或在一个有效果的场景中过渡 * SceneTransition用于从一个场景过渡到另一个场景或在一个有效果的场景中过渡
*/ */
abstract class SceneTransition { export abstract class SceneTransition {
private _hasPreviousSceneRender: boolean; private _hasPreviousSceneRender: boolean;
/** 是否加载新场景的标志 */ /** 是否加载新场景的标志 */
public loadsNewScene: boolean; public loadsNewScene: boolean;
@@ -43,7 +44,7 @@ abstract class SceneTransition {
} }
protected transitionComplete() { protected transitionComplete() {
SceneManager.sceneTransition = null; Core._instance._sceneTransition = null;
if (this.onTransitionCompleted) { if (this.onTransitionCompleted) {
this.onTransitionCompleted(); this.onTransitionCompleted();
@@ -58,7 +59,7 @@ abstract class SceneTransition {
this.isNewSceneLoaded = true; this.isNewSceneLoaded = true;
} }
SceneManager.scene = await this.sceneLoadAction(); Core.scene = await this.sceneLoadAction();
this.isNewSceneLoaded = true; this.isNewSceneLoaded = true;
} }
@@ -72,4 +73,5 @@ abstract class SceneTransition {
}); });
}); });
} }
}
} }
@@ -1,4 +1,5 @@
class WindTransition extends SceneTransition { module es {
export class WindTransition extends SceneTransition {
private _mask: egret.Shape; private _mask: egret.Shape;
private _windEffect: egret.CustomFilter; private _windEffect: egret.CustomFilter;
@@ -50,16 +51,15 @@ class WindTransition extends SceneTransition {
this._mask = new egret.Shape(); this._mask = new egret.Shape();
this._mask.graphics.beginFill(0xFFFFFF, 1); this._mask.graphics.beginFill(0xFFFFFF, 1);
this._mask.graphics.drawRect(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); this._mask.graphics.drawRect(0, 0, Core.graphicsDevice.viewport.width, Core.graphicsDevice.viewport.height);
this._mask.graphics.endFill(); this._mask.graphics.endFill();
this._mask.filters = [this._windEffect]; this._mask.filters = [this._windEffect];
SceneManager.stage.addChild(this._mask);
} }
public async onBeginTransition() { public async onBeginTransition() {
this.loadNextScene(); this.loadNextScene();
await this.tickEffectProgressProperty(this._windEffect, this.duration, this.easeType); await this.tickEffectProgressProperty(this._windEffect, this.duration, this.easeType);
this.transitionComplete(); this.transitionComplete();
SceneManager.stage.removeChild(this._mask); }
} }
} }
+17 -1
View File
@@ -1,4 +1,5 @@
class Viewport { module es {
export class Viewport {
private _x: number; private _x: number;
private _y: number; private _y: number;
private _width: number; private _width: number;
@@ -6,6 +7,20 @@ class Viewport {
private _minDepth: number; private _minDepth: number;
private _maxDepth: 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(){ public get aspectRatio(){
if ((this._height != 0) && (this._width != 0)) if ((this._height != 0) && (this._width != 0))
return (this._width / this._height); return (this._width / this._height);
@@ -31,4 +46,5 @@ class Viewport {
this._maxDepth = 1; this._maxDepth = 1;
} }
}
} }
+4 -2
View File
@@ -1,5 +1,6 @@
/** 贝塞尔帮助类 */ module es {
class Bezier { /** 贝塞尔帮助类 */
export class Bezier {
/** /**
* 线 * 线
* @param p0 * @param p0
@@ -118,4 +119,5 @@ class Bezier {
this.recursiveGetOptimizedDrawingPoints(start, pt12, pt123, pt1234, points, distanceTolerance); this.recursiveGetOptimizedDrawingPoints(start, pt12, pt123, pt1234, points, distanceTolerance);
this.recursiveGetOptimizedDrawingPoints(pt1234, pt234, pt34, end, points, distanceTolerance); this.recursiveGetOptimizedDrawingPoints(pt1234, pt234, pt34, end, points, distanceTolerance);
} }
}
} }
+4 -2
View File
@@ -1,9 +1,10 @@
/** module es {
/**
* *
* isFlagSet之外flag参数是一个非移位的标志 * isFlagSet之外flag参数是一个非移位的标志
* 使(0123)/ * 使(0123)/
*/ */
class Flags { export class Flags {
/** /**
* *
* *
@@ -59,4 +60,5 @@ class Flags {
public static invertFlags(self: number){ public static invertFlags(self: number){
return ~self; return ~self;
} }
}
} }
+3 -1
View File
@@ -1,4 +1,5 @@
class MathHelper { module es {
export class MathHelper {
public static readonly Epsilon: number = 0.00001; public static readonly Epsilon: number = 0.00001;
public static readonly Rad2Deg = 57.29578; public static readonly Rad2Deg = 57.29578;
public static readonly Deg2Rad = 0.0174532924; public static readonly Deg2Rad = 0.0174532924;
@@ -75,4 +76,5 @@ class MathHelper {
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); return Math.atan2(to.y - from.y, to.x - from.x);
} }
}
} }
+136 -171
View File
@@ -1,217 +1,182 @@
/** module es {
export var matrixPool = [];
/**
* 3 * 3 * 3 * 3
*/ */
class Matrix2D { export class Matrix2D extends egret.Matrix{
public m11: number = 0; public get m11(): number{
public m12: number = 0; return this.a;
public m21: number = 0;
public m22: number = 0;
public m31: number = 0;
public m32: number = 0;
private static _identity: Matrix2D = new Matrix2D(1, 0, 0, 1, 0, 0);
/**
*
*/
public static get identity(){
return Matrix2D._identity;
} }
public set m11(value: number){
constructor(m11?: number, m12?: number, m21?: number, m22?: number, m31?: number, m32?: number){ this.a = value;
this.m11 = m11 ? m11 : 1;
this.m12 = m12 ? m12 : 0;
this.m21 = m21 ? m21 : 0;
this.m22 = m22 ? m22 : 1;
this.m31 = m31 ? m31 : 0;
this.m32 = m32 ? m32 : 0;
} }
public get m12(): number{
/** 存储在这个矩阵中的位置 */ return this.b;
public get translation(){
return new Vector2(this.m31, this.m32);
} }
public set m12(value: number){
public set translation(value: Vector2){ this.b = value;
this.m31 = value.x;
this.m32 = value.y;
} }
public get m21(): number{
/** 以弧度表示的旋转存储在这个矩阵中 */ return this.c;
public get rotation(){
return Math.atan2(this.m21, this.m11);
} }
public set m21(value: number){
public set rotation(value: number){ this.c = value;
let val1 = Math.cos(value); }
let val2 = Math.sin(value); public get m22(): number{
return this.d;
this.m11 = val1; }
this.m12 = val2; public set m22(value: number){
this.m21 = -val2; this.d = value;
this.m22 = val1; }
public get m31(): number {
return this.tx;
}
public set m31(value: number){
this.tx = value;
}
public get m32(): number{
return this.ty;
}
public set m32(value: number){
this.ty = value;
} }
/** /**
* * Matrix对象
*/ */
public get rotationDegrees(){ public static create(): Matrix2D{
return MathHelper.toDegrees(this.rotation); let matrix = matrixPool.pop();
if (!matrix)
matrix = new Matrix2D();
return matrix;
} }
public set rotationDegrees(value: number){ public identity(): Matrix2D{
this.rotation = MathHelper.toRadians(value); this.a = this.d = 1;
this.b = this.c = this.tx = this.ty = 0;
return this;
} }
public get scale(){ public translate(dx: number, dy: number): Matrix2D {
return new Vector2(this.m11, this.m22); this.tx += dx;
this.ty += dy;
return this;
} }
public set scale(value: Vector2){ public scale(sx: number, sy: number): Matrix2D {
this.m11 = value.x; if (sx !== 1){
this.m12 = value.y; this.a *= sx;
this.c *= sx;
this.tx *= sx;
}
if (sy !== 1){
this.b *= sy;
this.d *= sy;
this.ty *= sy;
}
return this;
}
public rotate(angle: number): Matrix2D {
angle = +angle;
if (angle !== 0) {
angle = angle / DEG_TO_RAD;
let u = Math.cos(angle);
let v = Math.sin(angle);
let ta = this.a;
let tb = this.b;
let tc = this.c;
let td = this.d;
let ttx = this.tx;
let tty = this.ty;
this.a = ta * u - tb * v;
this.b = ta * v + tb * u;
this.c = tc * u - td * v;
this.d = tc * v + td * u;
this.tx = ttx * u - tty * v;
this.ty = ttx * v + tty * u;
}
return this;
}
public invert(): Matrix2D {
this.$invertInto(this);
return this;
} }
/** /**
* matrix, * matrix,
* @param matrix1 * @param matrix
* @param matrix2
*/ */
public static add(matrix1: Matrix2D, matrix2: Matrix2D){ public add(matrix: Matrix2D): Matrix2D{
matrix1.m11 += matrix2.m11; this.m11 += matrix.m11;
matrix1.m12 += matrix2.m12; this.m12 += matrix.m12;
matrix1.m21 += matrix2.m21; this.m21 += matrix.m21;
matrix1.m22 += matrix2.m22; this.m22 += matrix.m22;
matrix1.m31 += matrix2.m31; this.m31 += matrix.m31;
matrix1.m32 += matrix2.m32; this.m32 += matrix.m32;
return matrix1; return this;
} }
public static divide(matrix1: Matrix2D, matrix2: Matrix2D){ public substract(matrix: Matrix2D): Matrix2D {
matrix1.m11 /= matrix2.m11; this.m11 -= matrix.m11;
matrix1.m12 /= matrix2.m12; this.m12 -= matrix.m12;
matrix1.m21 /= matrix2.m21; this.m21 -= matrix.m21;
matrix1.m22 /= matrix2.m22; this.m22 -= matrix.m22;
matrix1.m31 /= matrix2.m31; this.m31 -= matrix.m31;
matrix1.m32 /= matrix2.m32; this.m32 -= matrix.m32;
return matrix1; return this;
} }
public static multiply(matrix1: Matrix2D, matrix2: Matrix2D){ public divide(matrix: Matrix2D): Matrix2D{
let result = new Matrix2D(); this.m11 /= matrix.m11;
this.m12 /= matrix.m12;
let m11 = ( matrix1.m11 * matrix2.m11 ) + ( matrix1.m12 * matrix2.m21 ); this.m21 /= matrix.m21;
let m12 = ( matrix1.m11 * matrix2.m12 ) + ( matrix1.m12 * matrix2.m22 ); this.m22 /= matrix.m22;
let m21 = ( matrix1.m21 * matrix2.m11 ) + ( matrix1.m22 * matrix2.m21 ); this.m31 /= matrix.m31;
let m22 = ( matrix1.m21 * matrix2.m12 ) + ( matrix1.m22 * matrix2.m22 ); this.m32 /= matrix.m32;
let m31 = ( matrix1.m31 * matrix2.m11 ) + ( matrix1.m32 * matrix2.m21 ) + matrix2.m31; return this;
let m32 = ( matrix1.m31 * matrix2.m12 ) + ( matrix1.m32 * matrix2.m22 ) + matrix2.m32;
result.m11 = m11;
result.m12 = m12;
result.m21 = m21;
result.m22 = m22;
result.m31 = m31;
result.m32 = m32;
return result;
} }
public static multiplyTranslation(matrix: Matrix2D, x: number, y: number){ public multiply(matrix: Matrix2D): Matrix2D{
let trans = Matrix2D.createTranslation(x, y); let m11 = ( this.m11 * matrix.m11 ) + ( this.m12 * matrix.m21 );
return Matrix2D.multiply(matrix, trans); 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 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;
this.m21 = m21;
this.m22 = m22;
this.m31 = m31;
this.m32 = m32;
return this;
} }
public determinant(){ public determinant(){
return this.m11 * this.m22 - this.m12 * this.m21; return this.m11 * this.m22 - this.m12 * this.m21;
} }
public static invert(matrix: Matrix2D, result: Matrix2D = new Matrix2D()){ public release(matrix: Matrix2D) {
let det = 1 / matrix.determinant(); if (!matrix)
return;
result.m11 = matrix.m22 * det; matrixPool.push(matrix);
result.m12 = -matrix.m12 * det;
result.m21 = -matrix.m21 * det;
result.m22 = matrix.m11 * det;
result.m31 = (matrix.m32 * matrix.m21 - matrix.m31 * matrix.m22) * det;
result.m32 = -(matrix.m32 * matrix.m11 - matrix.m31 * matrix.m12) * det;
return result;
} }
/**
* tranlation
* @param xPosition
* @param yPosition
*/
public static createTranslation(xPosition: number, yPosition: number){
let result = new Matrix2D();
result.m11 = 1;
result.m12 = 0;
result.m21 = 0;
result.m22 = 1;
result.m31 = xPosition;
result.m32 = yPosition;
return result;
}
/**
* position translation
* @param position
*/
public static createTranslationVector(position: Vector2){
return this.createTranslation(position.x, position.y);
}
public static createRotation(radians: number, result?: Matrix2D){
result = new Matrix2D();
let val1 = Math.cos(radians);
let val2 = Math.sin(radians);
result.m11 = val1;
result.m12 = val2;
result.m21 = -val2;
result.m22 = val1;
return result;
}
public static createScale(xScale: number, yScale: number, result: Matrix2D = new Matrix2D()){
result.m11 = xScale;
result.m12 = 0;
result.m21 = 0;
result.m22 = yScale;
result.m31 = 0;
result.m32 = 0;
return result;
}
public toEgretMatrix(): egret.Matrix{
let matrix = new egret.Matrix(this.m11, this.m12, this.m21, this.m22, this.m31, this.m32);
return matrix;
} }
} }
+26 -4
View File
@@ -1,4 +1,5 @@
class Rectangle extends egret.Rectangle { module es {
export class Rectangle extends egret.Rectangle {
/** /**
* *
*/ */
@@ -69,9 +70,10 @@ class Rectangle extends egret.Rectangle {
/** /**
* *
* @param point * @param point
* @param edgeNormal
*/ */
public getClosestPointOnRectangleBorderToPoint(point: Vector2): { res: Vector2, edgeNormal: Vector2 } { public getClosestPointOnRectangleBorderToPoint(point: Vector2, edgeNormal: Vector2): Vector2 {
let edgeNormal = Vector2.zero; edgeNormal = Vector2.zero;
// 对于每个轴,如果点在盒子外面 // 对于每个轴,如果点在盒子外面
let res = new Vector2(); let res = new Vector2();
@@ -106,7 +108,7 @@ class Rectangle extends egret.Rectangle {
if (res.y == this.bottom) edgeNormal.y = 1; if (res.y == this.bottom) edgeNormal.y = 1;
} }
return { res: res, edgeNormal: edgeNormal }; return res;
} }
/** /**
@@ -138,6 +140,25 @@ class Rectangle extends egret.Rectangle {
return boundsPoint; return boundsPoint;
} }
public calculateBounds(parentPosition: Vector2, position: Vector2, origin: Vector2, scale: Vector2, rotation: number, width: number, height: number){
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;
this.height = height * scale.y;
}
/**
* egret矩形转化为Rectangle
* @param rect
*/
public setEgretRect(rect: egret.Rectangle): Rectangle{
this.x = rect.x;
this.y = rect.y;
this.width = rect.width;
this.height = rect.height;
return this;
}
/** /**
* *
* @param points * @param points
@@ -161,4 +182,5 @@ class Rectangle extends egret.Rectangle {
return this.fromMinMax(minX, minY, maxX, maxY); return this.fromMinMax(minX, minY, maxX, maxY);
} }
}
} }
+50 -3
View File
@@ -1,5 +1,6 @@
/** 2d 向量 */ module es {
class Vector2 { /** 2d 向量 */
export class Vector2 {
public x: number = 0; public x: number = 0;
public y: number = 0; public y: number = 0;
@@ -33,6 +34,46 @@ class Vector2 {
this.y = y ? y : this.x; this.y = y ? y : this.x;
} }
/**
*
* @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;
}
/** /**
* *
* @param value1 * @param value1
@@ -156,7 +197,8 @@ class Vector2 {
* @param matrix * @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), (position.x * matrix.m12) + (position.y * matrix.m22)); return new Vector2((position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m31,
(position.x * matrix.m12) + (position.y * matrix.m22) + matrix.m32);
} }
/** /**
@@ -180,4 +222,9 @@ class Vector2 {
return result; return result;
} }
public equals(other: Vector2){
return other.x == this.x && other.y == this.y;
}
}
} }
+3 -1
View File
@@ -1,4 +1,5 @@
class Vector3 { module es {
export class Vector3 {
public x: number; public x: number;
public y: number; public y: number;
public z: number; public z: number;
@@ -8,4 +9,5 @@ class Vector3 {
this.y = y; this.y = y;
this.z = z; this.z = z;
} }
}
} }

Some files were not shown because too many files have changed in this diff Show More