init framework

This commit is contained in:
yhh
2020-06-08 11:49:45 +08:00
parent a2fd5153ad
commit db077d187c
125 changed files with 140474 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
class Camera {
private _displayContent: egret.DisplayObject;
constructor(displayObject: egret.DisplayObject){
this._displayContent = displayObject;
}
public destory(){
this._displayContent = null;
}
}

31
source/src/ECS/Entity.ts Normal file
View File

@@ -0,0 +1,31 @@
class Entity {
public name: string;
/** 当前实体所属的场景 */
public scene: Scene;
/** 封装实体的位置/旋转/缩放,并允许设置一个高层结构 */
public readonly transform: Transform;
constructor(name: string){
this.name = name;
this.transform = new Transform(this);
}
public attachToScene(newScene: Scene){
this.scene = newScene;
newScene.entities.push(this);
for (let i = 0; i < this.transform.childCount; i ++){
this.transform.getChild(i).entity.attachToScene(newScene);
}
}
public destory(){
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.destory();
}
}
}

58
source/src/ECS/Scene.ts Normal file
View File

@@ -0,0 +1,58 @@
/** 场景 */
class Scene extends egret.DisplayObjectContainer {
public camera: Camera;
public entities: Entity[] = [];
constructor(displayObject: egret.DisplayObject){
super();
/** 初始化默认相机 */
this.camera = new Camera(displayObject);
this.addEventListener(egret.Event.ACTIVATE, this.onActive, this);
this.addEventListener(egret.Event.DEACTIVATE, this.onDeactive, this);
}
public createEntity(name: string){
let entity = new Entity(name);
return this.addEntity(entity);
}
public addEntity(entity: Entity){
this.entities.push(entity);
entity.scene = this;
return entity;
}
public setActive(): Scene{
SceneManager.setActiveScene(this);
return this;
}
/** 初始化场景 */
public initialize(){
}
/** 场景激活 */
public onActive(){
}
/** 场景失去焦点 */
public onDeactive(){
}
public destory(){
this.removeEventListener(egret.Event.DEACTIVATE, this.onDeactive, this);
this.removeEventListener(egret.Event.ACTIVATE, this.onActive, this);
this.camera.destory();
this.camera = null;
this.entities.forEach(entity => entity.destory());
this.entities.length = 0;
}
}

View File

@@ -0,0 +1,36 @@
/** 运行时的场景管理。 */
class SceneManager {
private static _loadedScenes: Map<string, Scene> = new Map();
/** 上一个场景 */
private static _lastScene: Scene;
/** 当前激活的场景 */
private static _activeScene: Scene;
/**
* 使用给定的名称在运行时创建一个空的新场景。
* 新场景将与当前打开的任何现有场景一起被添加到层次结构中。
* 这个函数用于在运行时创建场景。
* @param name
* @param scene
*/
public static createScene(name: string, scene: Scene){
scene.name = name;
this._loadedScenes.set(name, scene);
return scene;
}
public static setActiveScene(scene: Scene){
if (this._activeScene){
// 如果场景相同则不进行切换
if (this._activeScene == scene)
return;
this._lastScene = this._activeScene;
this._activeScene.destory();
}
this._activeScene = scene;
this._activeScene.initialize();
return scene;
}
}

View File

@@ -0,0 +1,42 @@
class Transform {
/** 相关联的实体 */
public readonly entity: Entity;
private _children: Transform[];
private _parent: Transform;
public get childCount(){
return this._children.length;
}
constructor(entity: Entity){
this.entity = entity;
this._children = [];
}
public getChild(index: number){
return this._children[index];
}
public get parent(){
return this._parent;
}
public set parent(value: Transform){
this.setParent(value);
}
public setParent(parent: Transform){
if (this._parent == parent)
return this;
if (this._parent)
this._parent._children.remove(this);
if (parent)
parent._children.push(this);
this._parent = parent;
return this;
}
}

367
source/src/Extension.ts Normal file
View File

@@ -0,0 +1,367 @@
declare interface Array<T> {
/**
* 获取满足表达式的数组元素索引
* @param predicate 表达式
*/
findIndex(predicate: Function): number;
/**
* 是否存在满足表达式的数组元素
* @param predicate 表达式
*/
any(predicate: Function): boolean;
/**
* 获取满足表达式的第一个或默认数组元素
* @param predicate 表达式
*/
firstOrDefault(predicate: Function): T;
/**
* 获取满足表达式的第一个数组元素
* @param predicate 表达式
*/
find(predicate: Function): T;
/**
* 筛选满足表达式的数组元素
* @param predicate 表达式
*/
where(predicate: Function): Array<T>;
/**
* 获取满足表达式的数组元素的计数
* @param predicate 表达式
*/
count(predicate: Function): number;
/**
* 获取满足表达式的数组元素的数组
* @param predicate 表达式
*/
findAll(predicate: Function): Array<T>;
/**
* 是否有获取满足表达式的数组元素
* @param value 值
*/
contains(value): boolean;
/**
* 移除满足表达式的数组元素
* @param predicate 表达式
*/
removeAll(predicate: Function): void;
/**
* 移除数组元素
* @param element 数组元素
*/
remove(element): boolean;
/**
* 移除特定索引数组元素
* @param index 索引
*/
removeAt(index): void;
/**
* 移除范围数组元素
* @param index 开始索引
* @param count 删除的个数
*/
removeRange(index, count): void;
/**
* 获取通过选择器转换的数组
* @param selector 选择器
*/
select(selector: Function): Array<T>;
/**
* 排序(升序)
* @param keySelector key选择器
* @param comparer 比较器
*/
orderBy(keySelector: Function, comparer: Function): Array<T>;
/**
* 排序(降序)
* @param keySelector key选择器
* @param comparer 比较器
*/
orderByDescending(keySelector: Function, comparer: Function): Array<T>;
/**
* 分组
* @param keySelector key选择器
*/
groupBy(keySelector: Function): Array<T>;
/**
* 求和
* @param selector 选择器
*/
sum(selector);
}
Array.prototype.findIndex = function (predicate) {
function findIndex(array, predicate) {
for (let i = 0, len = array.length; i < len; i++) {
if (predicate.call(arguments[2], array[i], i, array)) {
return i;
}
}
return -1;
}
return findIndex(this, predicate);
}
Array.prototype.any = function (predicate) {
function any(array, predicate) {
return array.findIndex(predicate) > -1;
}
return any(this, predicate);
}
Array.prototype.firstOrDefault = function (predicate) {
function firstOrDefault(array, predicate) {
let index = array.findIndex(predicate);
return index == -1 ? null : array[index];
}
return firstOrDefault(this, predicate);
}
Array.prototype.find = function (predicate) {
function find(array, predicate) {
return array.firstOrDefault(predicate);
}
return find(this, predicate);
}
Array.prototype.where = function (predicate) {
function where(array, predicate) {
if (typeof (array.reduce) === "function") {
return array.reduce(function (ret, element, index) {
if (predicate.call(arguments[2], element, index, array)) {
ret.push(element);
}
return ret;
}, []);
}
else {
let ret = [];
for (let i = 0, len = array.length; i < len; i++) {
let element = array[i];
if (predicate.call(arguments[2], element, i, array)) {
ret.push(element);
}
}
return ret;
}
}
return where(this, predicate);
}
Array.prototype.count = function (predicate) {
function count(array, predicate) {
return array.where(predicate).length;
}
return count(this, predicate);
}
Array.prototype.findAll = function (predicate) {
function findAll(array, predicate) {
return array.where(predicate);
}
return findAll(this, predicate);
}
Array.prototype.contains = function (value) {
function contains(array, value) {
for (let i = 0, len = array.length; i < len; i++) {
if (JSON.stringify(array[i]) == JSON.stringify(value)) {
return true;
}
}
return false;
}
return contains(this, value);
}
Array.prototype.removeAll = function (predicate) {
function removeAll(array, predicate) {
let index;
do {
index = array.findIndex(predicate);
if (index >= 0) {
array.splice(index, 1);
}
}
while (index >= 0)
}
removeAll(this, predicate);
}
Array.prototype.remove = function (element) {
function remove(array, element) {
let index = array.findIndex(function (x) {
return x === element;
});
if (index >= 0) {
array.splice(index, 1);
return true;
}
else {
return false;
}
}
return remove(this, element);
}
Array.prototype.removeAt = function (index) {
function removeAt(array, index) {
array.splice(index, 1);
}
return removeAt(this, index);
}
Array.prototype.removeRange = function (index, count) {
function removeRange(array, index, count) {
array.splice(index, count);
}
return removeRange(this, index, count);
}
Array.prototype.select = function (selector) {
function select(array, selector) {
if (typeof (array.reduce) === "function") {
return array.reduce(function (ret, element, index) {
ret.push(selector.call(arguments[2], element, index, array));
return ret;
}, []);
}
else {
let ret = [];
for (let i = 0, len = array.length; i < len; i++) {
ret.push(selector.call(arguments[2], array[i], i, array))
}
return ret;
}
}
return select(this, selector);
}
Array.prototype.orderBy = function (keySelector, comparer) {
function orderBy(array, keySelector, comparer) {
array.sort(function (x, y) {
let v1 = keySelector(x)
let v2 = keySelector(y)
if (comparer) {
return comparer(v1, v2);
}
else {
return (v1 > v2) ? 1 : -1;
}
});
return array;
}
return orderBy(this, keySelector, comparer);
}
Array.prototype.orderByDescending = function (keySelector, comparer) {
function orderByDescending(array, keySelector, comparer) {
array.sort(function (x, y) {
let v1 = keySelector(x)
let v2 = keySelector(y)
if (comparer) {
return -comparer(v1, v2);
}
else {
return (v1 < v2) ? 1 : -1;
}
});
return array;
}
return orderByDescending(this, keySelector, comparer);
}
Array.prototype.groupBy = function (keySelector) {
function groupBy(array, keySelector) {
if (typeof (array.reduce) === "function") {
let keys = [];
return array.reduce(function (groups, element, index) {
let key = JSON.stringify(keySelector.call(arguments[1], element, index, array))
let index2 = keys.findIndex(function (x) { return x === key });
if (index2 < 0) {
index2 = keys.push(key) - 1;
}
if (!groups[index2]) {
groups[index2] = [];
}
groups[index2].push(element);
return groups;
}, []);
}
else {
let groups = [];
let keys = [];
for (let i = 0, len = array.length; i < len; i++) {
let key = JSON.stringify(keySelector.call(arguments[1], array[i], i, array));
let index = keys.findIndex(function (x) { return x === key });
if (index < 0) {
index = keys.push(key) - 1;
}
if (!groups[index]) {
groups[index] = [];
}
groups[index].push(array[i]);
}
return groups;
}
}
return groupBy(this, keySelector);
}
Array.prototype.sum = function (selector) {
function sum(array, selector) {
let ret;
for (let i = 0, len = array.length; i < len; i++) {
if (i == 0) {
if (selector) {
ret = selector.call(arguments[2], array[i], i, array);
}
else {
ret = array[i]
}
}
else {
if (selector) {
ret += selector.call(arguments[2], array[i], i, array);
}
else {
ret += array[i]
}
}
}
return ret;
}
return sum(this, selector);
}

View File

@@ -0,0 +1,17 @@
class MathHelper {
/**
* 将弧度转换成角度。
* @param radians 用弧度表示的角
*/
public static ToDegrees(radians: number){
return radians * 57.295779513082320876798154814105;
}
/**
* 将角度转换为弧度
* @param degrees
*/
public static ToRadians(degrees: number){
return degrees * 0.017453292519943295769236907684886;
}
}

130
source/src/Math/Matrix2D.ts Normal file
View File

@@ -0,0 +1,130 @@
/**
* 表示右手3 * 3的浮点矩阵可以存储平移、缩放和旋转信息。
*/
class Matrix2D {
public m11: number;
public m12: number;
public m21: number;
public m22: number;
public m31: number;
public m32: number;
private static _identity: Matrix2D = new Matrix2D(1, 0, 0, 1, 0, 0);
/**
* 单位矩阵
*/
public static get identity(){
return Matrix2D._identity;
}
constructor(m11: number, m12: number, m21: number, m22: number, m31: number, m32: number){
this.m11 = m11;
this.m12 = m12;
this.m21 = m21;
this.m22 = m22;
this.m31 = m31;
this.m32 = m32;
}
/** 存储在这个矩阵中的位置 */
public get translation(){
return new Vector2(this.m31, this.m32);
}
public set translation(value: Vector2){
this.m31 = value.x;
this.m32 = value.y;
}
/** 以弧度表示的旋转存储在这个矩阵中 */
public get rotation(){
return Math.atan2(this.m21, this.m11);
}
public set rotation(value: number){
let val1 = Math.cos(value);
let val2 = Math.sin(value);
this.m11 = val1;
this.m12 = val2;
this.m21 = -val2;
this.m22 = val1;
}
/**
* 以度为单位的旋转存储在这个矩阵中
*/
public get rotationDegrees(){
return MathHelper.ToDegrees(this.rotation);
}
public set rotationDegrees(value: number){
this.rotation = MathHelper.ToRadians(value);
}
public get scale(){
return new Vector2(this.m11, this.m22);
}
public set scale(value: Vector2){
this.m11 = value.x;
this.m12 = value.y;
}
/**
* 创建一个新的matrix, 它包含两个矩阵的和。
* @param matrix1
* @param matrix2
*/
public static add(matrix1: Matrix2D, matrix2: Matrix2D){
matrix1.m11 += matrix2.m11;
matrix1.m12 += matrix2.m12;
matrix1.m21 += matrix2.m21;
matrix1.m22 += matrix2.m22;
matrix1.m31 += matrix2.m31;
matrix1.m32 += matrix2.m32;
return matrix1;
}
public static divide(matrix1: Matrix2D, matrix2: Matrix2D){
matrix1.m11 /= matrix2.m11;
matrix1.m12 /= matrix2.m12;
matrix1.m21 /= matrix2.m21;
matrix1.m22 /= matrix2.m22;
matrix1.m31 /= matrix2.m31;
matrix1.m32 /= matrix2.m32;
return matrix1;
}
public static multiply(matrix1: Matrix2D, matrix2: Matrix2D){
let m11 = ( matrix1.m11 * matrix2.m11 ) + ( matrix1.m12 * matrix2.m21 );
let m12 = ( matrix1.m11 * matrix2.m12 ) + ( matrix1.m12 * matrix2.m22 );
let m21 = ( matrix1.m21 * matrix2.m11 ) + ( matrix1.m22 * matrix2.m21 );
let m22 = ( matrix1.m21 * matrix2.m12 ) + ( matrix1.m22 * matrix2.m22 );
let m31 = ( matrix1.m31 * matrix2.m11 ) + ( matrix1.m32 * matrix2.m21 ) + matrix2.m31;
let m32 = ( matrix1.m31 * matrix2.m12 ) + ( matrix1.m32 * matrix2.m22 ) + matrix2.m32;
matrix1.m11 = m11;
matrix1.m12 = m12;
matrix1.m21 = m21;
matrix1.m22 = m22;
matrix1.m31 = m31;
matrix1.m32 = m32;
return matrix1;
}
}

View File

@@ -0,0 +1,46 @@
/** 2d 向量 */
class Vector2 {
public x: number;
public y: number;
/**
* 从两个值构造一个带有X和Y的二维向量。
* @param x 二维空间中的x坐标
* @param y 二维空间的y坐标
*/
constructor(x: number, y: number){
this.x = x;
this.y = y;
}
public static add(value1: Vector2, value2: Vector2){
value1.x += value2.x;
value1.y += value2.y;
return value1;
}
public static divide(value1: Vector2, value2: Vector2){
value1.x /= value2.x;
value1.y /= value2.y;
return value1;
}
public static multiply(value1: Vector2, value2: Vector2){
value1.x *= value2.x;
value1.y *= value2.y;
return value1;
}
public static subtract(value1: Vector2, value2: Vector2){
value1.x -= value2.x;
value1.y -= value2.y;
return value1;
}
/** 变成一个方向相同的单位向量 */
public normalize(){
let val = 1 / Math.sqrt((this.x * this.x) + (this.y * this.y));
this.x *= val;
this.y *= val;
}
}