mirror of
https://gitee.com/dgflash/oops-plugin-framework.git
synced 2026-05-30 18:39:18 +08:00
扩展Array、Diector、Node对象功能
This commit is contained in:
9
assets/core/extension.meta
Normal file
9
assets/core/extension.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "1e41578f-5401-45ed-be1f-ad846351d895",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
373
assets/core/extension/ArrayExt.ts
Normal file
373
assets/core/extension/ArrayExt.ts
Normal file
@@ -0,0 +1,373 @@
|
||||
|
||||
declare global {
|
||||
interface Array<T> {
|
||||
remove(filter: (v: T, i: number, arr: Array<T>) => boolean): Array<T>;
|
||||
remove(filter: T): Array<T>;
|
||||
|
||||
removeOne(filter: (v: T, i: number, arr: Array<T>) => boolean): Array<T>;
|
||||
removeOne(filter: T): Array<T>;
|
||||
|
||||
random(): T;
|
||||
|
||||
first(): T;
|
||||
last(): T;
|
||||
|
||||
max(): T;
|
||||
max<P>(mapper: (v: T, i: number, arr: this) => P): P | null;
|
||||
|
||||
min(): T;
|
||||
min<P>(mapper: (v: T, i: number, arr: this) => P): P | null;
|
||||
|
||||
distinct(): Array<T>;
|
||||
filterIndex(filter: (v: T, i: number, arr: this) => boolean): Array<number>;
|
||||
|
||||
count(filter: (v: T, i: number, arr: this) => boolean): number;
|
||||
sum(mapper?: (v: T, i: number, arr: this) => number): number;
|
||||
average(mapper?: (v: T, i: number, arr: this) => number): number;
|
||||
|
||||
|
||||
// 移除指定位置的元素 返回移除的元素
|
||||
fastRemoveAt(index: number): T;
|
||||
fastRemove(value: T): boolean;
|
||||
|
||||
/**
|
||||
* 同find,但返回整个Array<T>中最后一个匹配元素
|
||||
*/
|
||||
findLast(predicate: (value: T, index: number, obj: Array<T>) => boolean): T | undefined;
|
||||
/**
|
||||
* 同find,但返回整个Array<T>中最后一个匹配元素的index
|
||||
*/
|
||||
findLastIndex(predicate: (value: T, index: number, obj: Array<T>) => boolean): number;
|
||||
|
||||
//排序升序 返回新的数组
|
||||
orderBy(...mappers: ((v: T) => any)[]): Array<T>;
|
||||
// 排序 降序
|
||||
orderByDesc(...mappers: ((v: T) => any)[]): Array<T>;
|
||||
|
||||
/**
|
||||
* 二分查找 前提是数组一定是有序的
|
||||
* @param value 要查找的值
|
||||
* @param keyMapper 要查找的值的mapper方法(默认为查找数组元素本身)
|
||||
* @return 查找到的index,查不到返回-1
|
||||
*/
|
||||
binarySearch(value: number | string, keyMapper?: (v: T) => (number | string)): number;
|
||||
/**
|
||||
* 二分插入 前提是数组一定是有序的
|
||||
* @param item 要插入的值
|
||||
* @param keyMapper 二分查找时要查找的值的mapper方法(默认为查找数组元素本身)
|
||||
* @param unique 是否去重,如果为true,则如果数组内已经有值时不插入,返回已有值的number
|
||||
* @return 返回插入的index位置
|
||||
*/
|
||||
binaryInsert(item: T, unique?: boolean): number;
|
||||
binaryInsert(item: T, keyMapper: (v: T) => (number | string), unique?: boolean): number;
|
||||
/**
|
||||
* 二分去重 前提是数组一定是有序的
|
||||
* @param keyMapper 二分查找时要查找的值的mapper方法(默认为查找数组元素本身)
|
||||
*/
|
||||
binaryDistinct(keyMapper?: (v: T) => (number | string)): Array<T>;
|
||||
|
||||
groupBy(grouper: (v: T) => any): (T[] & { key: any })[];
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
!Array.prototype.__cc_extended && Object.defineProperties(Array.prototype, {
|
||||
remove: {
|
||||
value: function (filter) {
|
||||
if (typeof (filter) == 'function') {
|
||||
for (let i = this.length - 1; i > -1; --i) {
|
||||
filter(this[i], i, this) && this.splice(i, 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (let i = this.length - 1; i > -1; --i) {
|
||||
this[i] === filter && this.splice(i, 1);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
},
|
||||
removeOne: {
|
||||
value: function (filter) {
|
||||
if (typeof (filter) == 'function') {
|
||||
for (let i = 0; i < this.length; ++i) {
|
||||
if (filter(this[i], i, this)) {
|
||||
this.splice(i, 1);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (let i = 0; i < this.length; ++i) {
|
||||
if (this[i] === filter) {
|
||||
this.splice(i, 1);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
},
|
||||
random: {
|
||||
value: function () {
|
||||
let element = this[Math.floor(Math.random() * this.length)];
|
||||
return element;
|
||||
}
|
||||
},
|
||||
fastRemoveAt: {
|
||||
value: function (index) {
|
||||
const length = this.length;
|
||||
if (index < 0 || index >= length) {
|
||||
return null;
|
||||
}
|
||||
let res = this[index];
|
||||
this[index] = this[length - 1];
|
||||
this.length = length - 1;
|
||||
return res;
|
||||
}
|
||||
},
|
||||
fastRemove: {
|
||||
value: function (value) {
|
||||
const index = this.indexOf(value);
|
||||
if (index >= 0) {
|
||||
this[index] = this[this.length - 1];
|
||||
--this.length;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
first: {
|
||||
value: function () {
|
||||
return this.length ? this[0] : null;
|
||||
}
|
||||
},
|
||||
last: {
|
||||
value: function () {
|
||||
return this.length ? this[this.length - 1] : null;
|
||||
}
|
||||
},
|
||||
max: {
|
||||
value: function (mapper) {
|
||||
if (!this.length) {
|
||||
return null;
|
||||
}
|
||||
function _max(a, b) {
|
||||
return a > b ? a : b;
|
||||
}
|
||||
if (typeof (mapper) == 'function') {
|
||||
let max = mapper(this[0], 0, this);
|
||||
for (let i = 1; i < this.length; ++i) {
|
||||
let temp = mapper(this[i], i, this);
|
||||
max = temp > max ? temp : max;
|
||||
}
|
||||
return max;
|
||||
}
|
||||
else {
|
||||
return this.reduce(function (prev, cur) { return _max(prev, cur); });
|
||||
}
|
||||
}
|
||||
},
|
||||
min: {
|
||||
value: function (mapper) {
|
||||
if (!this.length) {
|
||||
return null;
|
||||
}
|
||||
function _min(a, b) {
|
||||
return a < b ? a : b;
|
||||
}
|
||||
if (typeof (mapper) == 'function') {
|
||||
let min = mapper(this[0], 0, this);
|
||||
for (let i = 1; i < this.length; ++i) {
|
||||
let temp = mapper(this[i], i, this);
|
||||
min = temp < min ? temp : min;
|
||||
}
|
||||
return min;
|
||||
}
|
||||
else {
|
||||
return this.reduce(function (prev, cur) { return _min(prev, cur); });
|
||||
}
|
||||
}
|
||||
},
|
||||
distinct: {
|
||||
value: function () {
|
||||
return this.filter(function (v, i, arr) { return arr.indexOf(v) === i; });
|
||||
}
|
||||
},
|
||||
filterIndex: {
|
||||
value: function (filter) {
|
||||
let output = [];
|
||||
for (let i = 0; i < this.length; ++i) {
|
||||
if (filter(this[i], i, this)) {
|
||||
output.push(i);
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
},
|
||||
count: {
|
||||
value: function (filter) {
|
||||
let result = 0;
|
||||
for (let i = 0; i < this.length; ++i) {
|
||||
if (filter(this[i], i, this)) {
|
||||
++result;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
},
|
||||
sum: {
|
||||
value: function (mapper) {
|
||||
let result = 0;
|
||||
for (let i = 0; i < this.length; ++i) {
|
||||
result += mapper ? mapper(this[i], i, this) : this[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
},
|
||||
average: {
|
||||
value: function (mapper) {
|
||||
return this.sum(mapper) / this.length;
|
||||
}
|
||||
},
|
||||
orderBy: {
|
||||
value: function () {
|
||||
let mappers = [];
|
||||
for (let _i = 0; _i < arguments.length; _i++) {
|
||||
mappers[_i] = arguments[_i];
|
||||
}
|
||||
return this.slice().sort(function (a, b) {
|
||||
for (let i = 0; i < mappers.length; ++i) {
|
||||
let va = mappers[i](a);
|
||||
let vb = mappers[i](b);
|
||||
if (va > vb) {
|
||||
return 1;
|
||||
}
|
||||
else if (va < vb) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
},
|
||||
orderByDesc: {
|
||||
value: function () {
|
||||
let mappers = [];
|
||||
for (let _i = 0; _i < arguments.length; _i++) {
|
||||
mappers[_i] = arguments[_i];
|
||||
}
|
||||
return this.slice().sort(function (a, b) {
|
||||
for (let i = 0; i < mappers.length; ++i) {
|
||||
let va = mappers[i](a);
|
||||
let vb = mappers[i](b);
|
||||
if (va > vb) {
|
||||
return -1;
|
||||
}
|
||||
else if (va < vb) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
},
|
||||
binarySearch: {
|
||||
value: function (value, keyMapper) {
|
||||
let low = 0, high = this.length - 1;
|
||||
while (low <= high) {
|
||||
let mid = ((high + low) / 2) | 0;
|
||||
let midValue = keyMapper ? keyMapper(this[mid]) : this[mid];
|
||||
if (value === midValue) {
|
||||
return mid;
|
||||
}
|
||||
else if (value > midValue) {
|
||||
low = mid + 1;
|
||||
}
|
||||
else if (value < midValue) {
|
||||
high = mid - 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
},
|
||||
binaryInsert: {
|
||||
value: function (item, keyMapper, unique) {
|
||||
if (typeof (keyMapper) == 'boolean') {
|
||||
unique = keyMapper;
|
||||
keyMapper = undefined;
|
||||
}
|
||||
let low = 0, high = this.length - 1;
|
||||
let mid = NaN;
|
||||
let itemValue = keyMapper ? keyMapper(item) : item;
|
||||
while (low <= high) {
|
||||
mid = ((high + low) / 2) | 0;
|
||||
let midValue = keyMapper ? keyMapper(this[mid]) : this[mid];
|
||||
if (itemValue === midValue) {
|
||||
if (unique) {
|
||||
return mid;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (itemValue > midValue) {
|
||||
low = mid + 1;
|
||||
}
|
||||
else if (itemValue < midValue) {
|
||||
high = mid - 1;
|
||||
}
|
||||
}
|
||||
let index = low > mid ? mid + 1 : mid;
|
||||
this.splice(index, 0, item);
|
||||
return index;
|
||||
}
|
||||
},
|
||||
binaryDistinct: {
|
||||
value: function (keyMapper) {
|
||||
return this.filter(function (v, i, arr) { return arr.binarySearch(v, keyMapper) === i; });
|
||||
}
|
||||
},
|
||||
findLast: {
|
||||
value: function (predicate) {
|
||||
for (let i = this.length - 1; i > -1; --i) {
|
||||
if (predicate(this[i], i, this)) {
|
||||
return this[i];
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
},
|
||||
findLastIndex: {
|
||||
value: function (predicate) {
|
||||
for (let i = this.length - 1; i > -1; --i) {
|
||||
if (predicate(this[i], i, this)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
},
|
||||
groupBy: {
|
||||
value: function (grouper) {
|
||||
let group = this.reduce(function (prev, next) {
|
||||
let groupKey = grouper(next);
|
||||
if (!prev[groupKey]) {
|
||||
prev[groupKey] = [];
|
||||
}
|
||||
prev[groupKey].push(next);
|
||||
return prev;
|
||||
}, {});
|
||||
return Object.keys(group).map(function (key) {
|
||||
let arr = group[key];
|
||||
arr.key = key;
|
||||
return arr;
|
||||
});
|
||||
}
|
||||
},
|
||||
__cc_extended: {
|
||||
value: true
|
||||
}
|
||||
});
|
||||
|
||||
export { };
|
||||
9
assets/core/extension/ArrayExt.ts.meta
Normal file
9
assets/core/extension/ArrayExt.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "2696f555-d14d-4172-8b70-b6e496eea7bd",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
29
assets/core/extension/DirectorExt.ts
Normal file
29
assets/core/extension/DirectorExt.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { Director, director, js } from "cc";
|
||||
import { EDITOR } from "cc/env";
|
||||
|
||||
/** 全局游戏时间缩放 */
|
||||
if (!EDITOR) {
|
||||
//@ts-ignore
|
||||
if (!Director.prototype["__$cc-director-speed-extension$__"]) {
|
||||
//@ts-ignore
|
||||
Director.prototype["__$cc-director-speed-extension$__"] = true;
|
||||
|
||||
let oldTick = director.tick.bind(director);
|
||||
director.tick = function (dt) {
|
||||
dt *= director.globalGameTimeScale;
|
||||
oldTick(dt);
|
||||
};
|
||||
|
||||
js.mixin(Director.prototype, {
|
||||
globalGameTimeScale: 1,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
declare module "cc" {
|
||||
interface Director {
|
||||
globalGameTimeScale: number;
|
||||
}
|
||||
}
|
||||
|
||||
// director.globalGameTimeScale = 0.5;
|
||||
9
assets/core/extension/DirectorExt.ts.meta
Normal file
9
assets/core/extension/DirectorExt.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "37f480c3-2d1d-445c-a873-9feee92e5581",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
185
assets/core/extension/NodeDragExt.ts
Normal file
185
assets/core/extension/NodeDragExt.ts
Normal file
@@ -0,0 +1,185 @@
|
||||
|
||||
import { EventTouch, Node, Vec2, js, v3 } from "cc";
|
||||
import { DEV, EDITOR } from "cc/env";
|
||||
|
||||
/** 节点拖拽功能 */
|
||||
if (!EDITOR) {
|
||||
//@ts-ignore
|
||||
if (!Node.prototype["__$cc-node-drag-extension$__"]) {
|
||||
//@ts-ignore
|
||||
Node.prototype["__$cc-node-drag-extension$__"] = true;
|
||||
|
||||
let _DragEvent = {
|
||||
DRAG_START: "drag_start",
|
||||
DRAG_MOVE: "drag_move",
|
||||
DRAG_END: "drag_end"
|
||||
}
|
||||
|
||||
js.mixin(Node, {
|
||||
DragEvent: _DragEvent
|
||||
});
|
||||
|
||||
//---------------- Node 添加 拖拽属性 ----------------
|
||||
|
||||
js.mixin(Node.prototype, {
|
||||
_draggable: false,
|
||||
_dragging: false,
|
||||
_dragTesting: false,
|
||||
_dragStartPoint: null,
|
||||
initDrag: function () {
|
||||
if (this._draggable) {
|
||||
this.on(Node.EventType.TOUCH_START, this.onTouchBegin_0, this);
|
||||
this.on(Node.EventType.TOUCH_MOVE, this.onTouchMove_0, this);
|
||||
this.on(Node.EventType.TOUCH_END, this.onTouchEnd_0, this);
|
||||
this.on(Node.EventType.TOUCH_CANCEL, this.onTouchCancel_0, this);
|
||||
}
|
||||
else {
|
||||
this.off(Node.EventType.TOUCH_START, this.onTouchBegin_0, this);
|
||||
this.off(Node.EventType.TOUCH_MOVE, this.onTouchMove_0, this);
|
||||
this.off(Node.EventType.TOUCH_END, this.onTouchEnd_0, this);
|
||||
this.off(Node.EventType.TOUCH_CANCEL, this.onTouchCancel_0, this);
|
||||
}
|
||||
},
|
||||
onTouchBegin_0: function (event: EventTouch) {
|
||||
if (this._dragStartPoint == null) {
|
||||
this._dragStartPoint = new Vec2();
|
||||
}
|
||||
DEV && console.log(`cc-node-drag-extension-> onTouchBegin_0 ${this.name}`);
|
||||
|
||||
// event.preventSwallow = true;
|
||||
let pos = event.getUILocation();
|
||||
this._dragStartPoint.set(pos);
|
||||
this._dragTesting = true;
|
||||
},
|
||||
onTouchMove_0: function (event: EventTouch) {
|
||||
if (!this._dragging && this._draggable && this._dragTesting) {
|
||||
let sensitivity = 10;
|
||||
let pos = event.getUILocation();
|
||||
if (Math.abs(this._dragStartPoint.x - pos.x) < sensitivity
|
||||
&& Math.abs(this._dragStartPoint.y - pos.y) < sensitivity) {
|
||||
return;
|
||||
}
|
||||
|
||||
// event.preventSwallow = true;
|
||||
this._dragging = true;
|
||||
this._dragTesting = false;
|
||||
this.emit(Node.DragEvent.DRAG_START, event);
|
||||
}
|
||||
|
||||
if (this._dragging) {
|
||||
let delta = event.getUIDelta();
|
||||
// /** 这里除以 世界缩放,在有缩放的时候拖拽不至于很怪 */
|
||||
// this.position = this.position.add(v3(delta.x / this.worldScale.x, delta.y / this.worldScale.y, 0));
|
||||
this.position = this.position.add(v3(delta.x, delta.y, 0));
|
||||
this.emit(Node.DragEvent.DRAG_MOVE, event);
|
||||
}
|
||||
},
|
||||
|
||||
onTouchEnd_0: function (event: EventTouch) {
|
||||
if (this._dragging) {
|
||||
this._dragging = false;
|
||||
this.emit(Node.DragEvent.DRAG_END, event);
|
||||
}
|
||||
DEV && console.log(`cc-node-drag-extension-> onTouchEnd_0 ${this.name}, _dragging: ${this._dragging}`);
|
||||
},
|
||||
|
||||
onTouchCancel_0: function (event: EventTouch) {
|
||||
if (this._dragging) {
|
||||
this._dragging = false;
|
||||
this.emit(Node.DragEvent.DRAG_END, event);
|
||||
}
|
||||
DEV && console.log(`cc-node-drag-extension-> onTouchCancel_0 ${this.name}, _dragging: ${this._dragging}`);
|
||||
},
|
||||
|
||||
startDrag: function () {
|
||||
//此节点是否在场景中激活
|
||||
if (!this.activeInHierarchy) {
|
||||
return;
|
||||
}
|
||||
this.dragBegin();
|
||||
},
|
||||
|
||||
dragBegin: function () {
|
||||
this._dragging = true;
|
||||
this._dragTesting = true;
|
||||
this.on(Node.EventType.TOUCH_MOVE, this.onTouchMove_0, this);
|
||||
this.on(Node.EventType.TOUCH_END, this.onTouchEnd_0, this);
|
||||
this.on(Node.EventType.TOUCH_CANCEL, this.onTouchCancel_0, this);
|
||||
},
|
||||
dragEnd: function () {
|
||||
if (this._dragging) {
|
||||
this._dragTesting = false;
|
||||
this._dragging = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 停止拖拽
|
||||
stopDrag: function () {
|
||||
this.dragEnd();
|
||||
},
|
||||
|
||||
// 移除 touch 事件
|
||||
removeDragEvent: function () {
|
||||
this.off(Node.EventType.TOUCH_START, this.onTouchBegin_0, this);
|
||||
this.off(Node.EventType.TOUCH_MOVE, this.onTouchMove_0, this);
|
||||
this.off(Node.EventType.TOUCH_END, this.onTouchEnd_0, this);
|
||||
this.off(Node.EventType.TOUCH_CANCEL, this.onTouchCancel_0, this);
|
||||
}
|
||||
});
|
||||
|
||||
// 如果 node 设置 node.draggable = true, 则启用 拖拽
|
||||
Object.defineProperty(Node.prototype, "draggable", {
|
||||
get: function () {
|
||||
return this._draggable;
|
||||
},
|
||||
set: function (value) {
|
||||
if (this._draggable != value) {
|
||||
this._draggable = value;
|
||||
this.initDrag();
|
||||
}
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
Object.defineProperty(Node.prototype, "dragTesting", {
|
||||
get: function () {
|
||||
return this._dragTesting;
|
||||
},
|
||||
set: function (value) {
|
||||
if (this._dragTesting != value) {
|
||||
this._dragTesting = value;
|
||||
}
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
//---------------- Node 添加 拖拽属性 ---------------- end
|
||||
}
|
||||
}
|
||||
|
||||
declare module "cc" {
|
||||
// 这里使用 interface 进行扩展,如果使用 class 则会与现有的 d.ts 有冲突
|
||||
export interface Node {
|
||||
/** 是否启动拖拽 - true为启动 */
|
||||
draggable: boolean;
|
||||
/** 开始拖拽 */
|
||||
startDrag(): void;
|
||||
/** 停止拖拽 */
|
||||
stopDrag(): void;
|
||||
/** 移除拖拽事件 */
|
||||
removeDragEvent(): void;
|
||||
}
|
||||
|
||||
export namespace Node {
|
||||
/** 支持的拖拽事件 */
|
||||
export class DragEvent {
|
||||
/** 拖拽开始事件 */
|
||||
static DRAG_START: string;
|
||||
/** 拖拽移动事件 */
|
||||
static DRAG_MOVE: string;
|
||||
/** 拖拽结束事件 */
|
||||
static DRAG_END: string;
|
||||
}
|
||||
}
|
||||
}
|
||||
9
assets/core/extension/NodeDragExt.ts.meta
Normal file
9
assets/core/extension/NodeDragExt.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "1a072fee-76ef-4cb5-b75b-c8be7107c891",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
239
assets/core/extension/NodeExt.ts
Normal file
239
assets/core/extension/NodeExt.ts
Normal file
@@ -0,0 +1,239 @@
|
||||
import { Color, Node, Size, UIOpacity, UIRenderer, UITransform, v3 } from "cc";
|
||||
import { EDITOR } from "cc/env";
|
||||
|
||||
// ========= 扩展 cc 提示声明 =========
|
||||
|
||||
/** 扩展节点属性 */
|
||||
declare module "cc" {
|
||||
interface Node {
|
||||
/** 获取、设置节点的本地X坐标 */
|
||||
x: number;
|
||||
/** 获取、设置节点的本地Y坐标 */
|
||||
y: number;
|
||||
/** 获取、设置节点的本地Z坐标 */
|
||||
z: number;
|
||||
/** 获取、设置节点宽 */
|
||||
w: number;
|
||||
/** 获取、设置节点高 */
|
||||
h: number;
|
||||
/** 获取、设置节点尺寸 */
|
||||
size: Size;
|
||||
/** 获取、设置X轴锚点 */
|
||||
anchor_x: number;
|
||||
/** 获取、设置Y轴锚点 */
|
||||
anchor_y: number;
|
||||
/** 获取、设置节点透明度 */
|
||||
opacity: number;
|
||||
/** 获取、设置节点颜色 */
|
||||
color: Color;
|
||||
/** 获取、设置X轴缩放 */
|
||||
scale_x: number;
|
||||
/** 获取、设置Y轴缩放 */
|
||||
scale_y: number;
|
||||
/** 获取、设置Z轴缩放 */
|
||||
scale_z: number;
|
||||
}
|
||||
}
|
||||
|
||||
if (!EDITOR) {
|
||||
//@ts-ignore
|
||||
if (!Node.prototype["$__definedProperties__"]) {
|
||||
//@ts-ignore
|
||||
Node.prototype["$__definedProperties__"] = true;
|
||||
|
||||
/** 获取、设置节点的 X 坐标 */
|
||||
Object.defineProperty(Node.prototype, "x", {
|
||||
get: function () {
|
||||
let self: Node = this;
|
||||
return self.position.x;
|
||||
},
|
||||
set: function (value: number) {
|
||||
let self: Node = this;
|
||||
self.setPosition(value, self.position.y);
|
||||
}
|
||||
});
|
||||
|
||||
/** 获取、设置节点的 Y 坐标 */
|
||||
Object.defineProperty(Node.prototype, "y", {
|
||||
get: function () {
|
||||
let self: Node = this;
|
||||
return self.position.y;
|
||||
},
|
||||
set: function (value: number) {
|
||||
let self: Node = this;
|
||||
self.setPosition(self.position.x, value);
|
||||
}
|
||||
});
|
||||
|
||||
/** 获取、设置节点的 Z 坐标 */
|
||||
Object.defineProperty(Node.prototype, "z", {
|
||||
get: function () {
|
||||
let self: Node = this;
|
||||
return self.position.z;
|
||||
},
|
||||
set: function (value: number) {
|
||||
let self: Node = this;
|
||||
self.setPosition(self.position.x, self.position.y, value);
|
||||
}
|
||||
});
|
||||
|
||||
/** 获取、设置节点的宽度 */
|
||||
Object.defineProperty(Node.prototype, "w", {
|
||||
configurable: true,
|
||||
get: function () {
|
||||
let self: Node = this;
|
||||
return self.getComponent(UITransform)?.width ?? 0;
|
||||
},
|
||||
set: function (value: number) {
|
||||
let self: Node = this;
|
||||
(self.getComponent(UITransform) || self.addComponent(UITransform)).width = value;
|
||||
}
|
||||
});
|
||||
|
||||
/** 获取、设置节点的高度 */
|
||||
Object.defineProperty(Node.prototype, "h", {
|
||||
configurable: true,
|
||||
get: function () {
|
||||
let self: Node = this;
|
||||
return self.getComponent(UITransform)?.height ?? 0;
|
||||
},
|
||||
set: function (value: number) {
|
||||
let self: Node = this;
|
||||
(self.getComponent(UITransform) || self.addComponent(UITransform)).height = value;
|
||||
}
|
||||
});
|
||||
|
||||
/** 获取、设置节点的尺寸 */
|
||||
Object.defineProperty(Node.prototype, "size", {
|
||||
get: function () {
|
||||
let self: Node = this;
|
||||
let uiTransform = self.getComponent(UITransform)!;
|
||||
return new Size(uiTransform.width, uiTransform.height);
|
||||
},
|
||||
set: function (value: Size) {
|
||||
let self: Node = this;
|
||||
let uiTransform = self.getComponent(UITransform) || self.addComponent(UITransform);
|
||||
uiTransform.width = value.width;
|
||||
uiTransform.height = value.height;
|
||||
}
|
||||
});
|
||||
|
||||
/** 获取、设置节点的水平锚点 */
|
||||
Object.defineProperty(Node.prototype, "anchor_x", {
|
||||
get: function () {
|
||||
let self: Node = this;
|
||||
return self.getComponent(UITransform)?.anchorX ?? 0.5;
|
||||
},
|
||||
set: function (value: number) {
|
||||
let self: Node = this;
|
||||
(self.getComponent(UITransform) || self.addComponent(UITransform)).anchorX = value;
|
||||
}
|
||||
});
|
||||
|
||||
/** 获取、设置节点的垂直锚点 */
|
||||
Object.defineProperty(Node.prototype, "anchor_y", {
|
||||
get: function () {
|
||||
let self: Node = this;
|
||||
return self.getComponent(UITransform)?.anchorY ?? 0.5;
|
||||
},
|
||||
set: function (value: number) {
|
||||
let self: Node = this;
|
||||
(self.getComponent(UITransform) || self.addComponent(UITransform)).anchorY = value;
|
||||
}
|
||||
});
|
||||
|
||||
/** 获取、设置节点的透明度 */
|
||||
Object.defineProperty(Node.prototype, "opacity", {
|
||||
get: function () {
|
||||
let self: Node = this;
|
||||
let op = self.getComponent(UIOpacity);
|
||||
if (op != null) {
|
||||
return op.opacity;
|
||||
}
|
||||
|
||||
let render = self.getComponent(UIRenderer);
|
||||
if (render) {
|
||||
return render.color.a;
|
||||
}
|
||||
|
||||
return 255;
|
||||
},
|
||||
|
||||
set: function (value: number) {
|
||||
let self: Node = this;
|
||||
let op = self.getComponent(UIOpacity);
|
||||
if (op != null) {
|
||||
op.opacity = value;
|
||||
return;
|
||||
}
|
||||
|
||||
let render = self.getComponent(UIRenderer);
|
||||
if (render) {
|
||||
// 直接通过 color.a 设置透明度会有bug,没能直接生效,需要激活节点才生效
|
||||
// (render.color.a as any) = value;
|
||||
|
||||
// 创建一个颜色缓存对象,避免每次都创建新对象
|
||||
if (!this.$__color__) {
|
||||
this.$__color__ = new Color(render.color.r, render.color.g, render.color.b, value);
|
||||
}
|
||||
else {
|
||||
this.$__color__.a = value;
|
||||
}
|
||||
render.color = this.$__color__; // 设置 color 对象则可以立刻生效
|
||||
}
|
||||
else {
|
||||
self.addComponent(UIOpacity).opacity = value;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/** 获取、设置节点的颜色 */
|
||||
Object.defineProperty(Node.prototype, "color", {
|
||||
get: function () {
|
||||
let self: Node = this;
|
||||
return self.getComponent(UIRenderer)?.color;
|
||||
},
|
||||
set: function (value: Color) {
|
||||
let self: Node = this;
|
||||
let render = self.getComponent(UIRenderer);
|
||||
render && (render.color = value);
|
||||
}
|
||||
});
|
||||
|
||||
/** 获取、设置节点的 X 缩放系数 */
|
||||
Object.defineProperty(Node.prototype, "scale_x", {
|
||||
get: function () {
|
||||
let self: Node = this;
|
||||
return self.scale.x;
|
||||
},
|
||||
set: function (value: number) {
|
||||
let self: Node = this;
|
||||
self.scale = v3(value, self.scale.y, self.scale.z);
|
||||
}
|
||||
});
|
||||
|
||||
/** 获取、设置节点的 Y 缩放系数 */
|
||||
Object.defineProperty(Node.prototype, "scale_y", {
|
||||
get: function () {
|
||||
let self: Node = this;
|
||||
return self.scale.y;
|
||||
},
|
||||
set: function (value: number) {
|
||||
let self: Node = this;
|
||||
self.scale = v3(self.scale.x, value, self.scale.z);
|
||||
}
|
||||
});
|
||||
|
||||
/** 获取、设置节点的 Z 缩放系数 */
|
||||
Object.defineProperty(Node.prototype, "scale_z", {
|
||||
get: function () {
|
||||
let self: Node = this;
|
||||
return self.scale.z;
|
||||
},
|
||||
set: function (value: number) {
|
||||
let self: Node = this;
|
||||
self.scale = v3(self.scale.x, self.scale.y, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
9
assets/core/extension/NodeExt.ts.meta
Normal file
9
assets/core/extension/NodeExt.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.23",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "493a6bed-02c3-428b-bfdd-adb28720068b",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -4,9 +4,7 @@
|
||||
* @LastEditors: dgflash
|
||||
* @LastEditTime: 2022-09-02 12:09:55
|
||||
*/
|
||||
import { game, Game, Node } from 'cc';
|
||||
|
||||
var timeScale = 1;
|
||||
import { Node, director } from 'cc';
|
||||
|
||||
/** 游戏世界管理 */
|
||||
export class GameManager {
|
||||
@@ -15,30 +13,10 @@ export class GameManager {
|
||||
|
||||
constructor(root: Node) {
|
||||
this.root = root;
|
||||
this.gameTimeScaleExtend();
|
||||
}
|
||||
|
||||
/** 设置游戏动画速度(不支持 Native 模式) */
|
||||
/** 设置游戏动画速度 */
|
||||
setTimeScale(scale: number) {
|
||||
timeScale = scale;
|
||||
}
|
||||
|
||||
/** 只支持web整体加速 */
|
||||
private gameTimeScaleExtend() {
|
||||
//@ts-ignore
|
||||
game._calculateDT = function (now: number) {
|
||||
if (!now) now = performance.now();
|
||||
//@ts-ignore
|
||||
this._deltaTime = now > this._startTime ? (now - this._startTime) / 1000 : 0;
|
||||
//@ts-ignore
|
||||
if (this._deltaTime > Game.DEBUG_DT_THRESHOLD) {
|
||||
//@ts-ignore
|
||||
this._deltaTime = this.frameTime / 1000;
|
||||
}
|
||||
//@ts-ignore
|
||||
this._startTime = now;
|
||||
//@ts-ignore
|
||||
return this._deltaTime * timeScale;
|
||||
};
|
||||
director.globalGameTimeScale = scale;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user