2024-05-07 03:20:37 -07:00
|
|
|
import {
|
2024-06-07 00:08:39 -07:00
|
|
|
AudioSource,
|
2024-05-07 03:20:37 -07:00
|
|
|
Component,
|
2024-06-07 00:08:39 -07:00
|
|
|
Event,
|
|
|
|
Game,
|
2024-05-07 03:20:37 -07:00
|
|
|
IVec2Like,
|
|
|
|
IVec3Like,
|
|
|
|
Label,
|
|
|
|
Node,
|
|
|
|
NodeSpace,
|
2024-06-12 20:39:54 -07:00
|
|
|
PhysicsSystem2D,
|
2024-06-07 00:08:39 -07:00
|
|
|
Sprite,
|
2024-05-07 03:20:37 -07:00
|
|
|
Vec2,
|
|
|
|
Vec3,
|
2024-06-07 00:08:39 -07:00
|
|
|
game,
|
2024-05-07 03:20:37 -07:00
|
|
|
randomRangeInt,
|
|
|
|
toDegree,
|
|
|
|
toRadian,
|
|
|
|
} from 'cc';
|
|
|
|
import ObjectPool from '../Pool/ObjectPool';
|
|
|
|
|
|
|
|
declare module 'cc' {
|
2024-06-07 00:08:39 -07:00
|
|
|
interface Game {
|
|
|
|
timeScale: number;
|
|
|
|
}
|
|
|
|
|
2024-05-07 03:20:37 -07:00
|
|
|
interface Component {
|
|
|
|
setNodeActive(isActive: boolean): void;
|
2024-06-07 00:08:39 -07:00
|
|
|
setNodeActive(event: Event, customEventData?: string): void;
|
|
|
|
setNodeActive(a: boolean | Event, b?: string): void;
|
2024-05-07 03:20:37 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
interface Node {
|
|
|
|
setActive(isActive: boolean): void;
|
|
|
|
setPositionX(x: number): void;
|
|
|
|
setPositionY(y: number): void;
|
|
|
|
setPositionZ(z: number): void;
|
2024-05-15 00:42:31 -07:00
|
|
|
setWorldPositionX(x: number): void;
|
|
|
|
setWorldPositionY(y: number): void;
|
|
|
|
setWorldPositionZ(z: number): void;
|
2024-05-07 03:20:37 -07:00
|
|
|
translateX(x: number, ns?: NodeSpace): void;
|
|
|
|
translateY(y: number, ns?: NodeSpace): void;
|
|
|
|
translateZ(z: number, ns?: NodeSpace): void;
|
|
|
|
setScaleX(x: number): void;
|
|
|
|
setScaleY(y: number): void;
|
|
|
|
setScaleZ(z: number): void;
|
2024-06-07 00:08:39 -07:00
|
|
|
releaseToPool(): boolean;
|
2024-05-07 03:20:37 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
interface Vec2 {
|
|
|
|
toVec3(): Vec3;
|
|
|
|
getPositionOnCircle(angle: number, radius?: number): Vec2;
|
|
|
|
getAngleOnCircle(center: IVec2Like): number;
|
|
|
|
}
|
|
|
|
|
|
|
|
interface Vec3 {
|
|
|
|
toVec2(): Vec2;
|
|
|
|
getPositionOnCircle(angle: number, radius?: number): Vec3;
|
|
|
|
getAngleOnCircle(center: IVec3Like): number;
|
|
|
|
}
|
|
|
|
|
|
|
|
interface Label {
|
2024-06-07 00:08:39 -07:00
|
|
|
setString(value: string | number): void;
|
|
|
|
}
|
|
|
|
|
|
|
|
interface Sprite {
|
|
|
|
setFillRange(value: number): void;
|
|
|
|
}
|
|
|
|
|
|
|
|
interface AudioSource {
|
|
|
|
getPlaybackRate(): number;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set playbackRate of this audio source
|
|
|
|
*
|
|
|
|
* Note: playbackRate control may be ineffective on some platforms.
|
|
|
|
*/
|
|
|
|
setPlaybackRate(value: number): void;
|
2024-05-07 03:20:37 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
declare global {
|
|
|
|
interface String {
|
|
|
|
jsonParse(): any;
|
|
|
|
isNullOrWhiteSpace(): boolean;
|
|
|
|
}
|
|
|
|
|
|
|
|
interface Array<T> {
|
2024-06-10 21:35:13 -07:00
|
|
|
getRandomIndex(): number;
|
2024-06-12 04:48:19 -07:00
|
|
|
getRandomIndex(weights: number[]): number;
|
2024-05-07 03:20:37 -07:00
|
|
|
getRandom(): T;
|
|
|
|
getRandom(weights: number[]): T;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-07 00:08:39 -07:00
|
|
|
//#region GAME
|
|
|
|
|
2024-06-12 20:39:54 -07:00
|
|
|
const fixedTime = PhysicsSystem2D.instance.fixedTimeStep;
|
|
|
|
|
2024-06-07 00:08:39 -07:00
|
|
|
Game.prototype.timeScale = 1;
|
|
|
|
// @ts-ignore
|
2024-06-12 20:39:54 -07:00
|
|
|
game._calculateDT = function (useFixedDeltaTime: boolean) {
|
|
|
|
PhysicsSystem2D.instance.fixedTimeStep = fixedTime * game.timeScale;
|
2024-06-07 00:08:39 -07:00
|
|
|
this._useFixedDeltaTime = useFixedDeltaTime;
|
|
|
|
if (useFixedDeltaTime) {
|
|
|
|
this._startTime = performance.now();
|
2024-06-12 20:39:54 -07:00
|
|
|
return (this.frameTime / 1000) * game.timeScale;
|
2024-06-07 00:08:39 -07:00
|
|
|
}
|
|
|
|
const now = performance.now();
|
|
|
|
this._deltaTime = now > this._startTime ? (now - this._startTime) / 1000 : 0;
|
|
|
|
if (this._deltaTime > Game.DEBUG_DT_THRESHOLD) {
|
|
|
|
this._deltaTime = this.frameTime / 1000;
|
|
|
|
}
|
|
|
|
this._startTime = now;
|
|
|
|
return this._deltaTime * this.timeScale;
|
|
|
|
};
|
|
|
|
|
|
|
|
//#endregion
|
|
|
|
|
2024-05-07 03:20:37 -07:00
|
|
|
//#region COMPONENT
|
|
|
|
|
2024-06-07 00:08:39 -07:00
|
|
|
Component.prototype.setNodeActive = function (a: boolean | Event, b?: string) {
|
|
|
|
if (a instanceof Event) {
|
|
|
|
this.node.active = b?.toLowerCase() === 'true';
|
|
|
|
} else {
|
|
|
|
this.node.active = a;
|
|
|
|
}
|
2024-05-07 03:20:37 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
//#endregion
|
|
|
|
|
|
|
|
//#region NODE
|
|
|
|
|
|
|
|
Node.prototype.setActive = function (isActive: boolean) {
|
|
|
|
this.active = isActive;
|
|
|
|
};
|
|
|
|
|
|
|
|
Node.prototype.setPositionX = function (x: number): void {
|
|
|
|
this.position = new Vec3(x, this.position.y, this.position.z);
|
|
|
|
};
|
|
|
|
|
|
|
|
Node.prototype.setPositionY = function (y: number): void {
|
|
|
|
this.position = new Vec3(this.position.x, y, this.position.z);
|
|
|
|
};
|
|
|
|
|
|
|
|
Node.prototype.setPositionZ = function (z: number): void {
|
|
|
|
this.position = new Vec3(this.position.x, this.position.y, z);
|
|
|
|
};
|
|
|
|
|
2024-05-15 00:42:31 -07:00
|
|
|
Node.prototype.setWorldPositionX = function (x: number): void {
|
|
|
|
this.worldPosition = new Vec3(x, this.worldPosition.y, this.worldPosition.z);
|
|
|
|
};
|
|
|
|
|
|
|
|
Node.prototype.setWorldPositionY = function (y: number): void {
|
|
|
|
this.worldPosition = new Vec3(this.worldPosition.x, y, this.worldPosition.z);
|
|
|
|
};
|
|
|
|
|
|
|
|
Node.prototype.setWorldPositionZ = function (z: number): void {
|
|
|
|
this.worldPosition = new Vec3(this.worldPosition.x, this.worldPosition.y, z);
|
|
|
|
};
|
|
|
|
|
2024-05-07 03:20:37 -07:00
|
|
|
Node.prototype.translateX = function (x: number, ns?: NodeSpace): void {
|
|
|
|
this.translate(new Vec3(x, 0), ns);
|
|
|
|
};
|
|
|
|
|
|
|
|
Node.prototype.translateY = function (y: number, ns?: NodeSpace): void {
|
|
|
|
this.translate(new Vec3(0, y), ns);
|
|
|
|
};
|
|
|
|
|
|
|
|
Node.prototype.translateZ = function (z: number, ns?: NodeSpace): void {
|
|
|
|
this.translate(new Vec3(0, 0, z), ns);
|
|
|
|
};
|
|
|
|
|
|
|
|
Node.prototype.setScaleX = function (x: number): void {
|
|
|
|
this.scale = new Vec3(x, this.scale.y, this.scale.z);
|
|
|
|
};
|
|
|
|
|
|
|
|
Node.prototype.setScaleY = function (y: number): void {
|
|
|
|
this.scale = new Vec3(this.scale.x, y, this.scale.z);
|
|
|
|
};
|
|
|
|
|
|
|
|
Node.prototype.setScaleZ = function (z: number): void {
|
|
|
|
this.scale = new Vec3(this.scale.x, this.scale.y, z);
|
|
|
|
};
|
|
|
|
|
|
|
|
Node.prototype.releaseToPool = function () {
|
2024-06-07 00:08:39 -07:00
|
|
|
return ObjectPool.release(this);
|
2024-05-07 03:20:37 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
//#endregion
|
|
|
|
|
|
|
|
//#region VEC2
|
|
|
|
|
|
|
|
Vec2.prototype.toVec3 = function () {
|
|
|
|
return new Vec3(this.x, this.y);
|
|
|
|
};
|
|
|
|
|
|
|
|
Vec2.prototype.getPositionOnCircle = function (angle: number, radius?: number) {
|
|
|
|
const rad = toRadian(angle);
|
|
|
|
const r = radius || 1;
|
|
|
|
const x = this.x + r * -Math.cos(rad);
|
|
|
|
const y = this.y + r * Math.sin(rad);
|
|
|
|
return new Vec2(x, y);
|
|
|
|
};
|
|
|
|
|
|
|
|
Vec2.prototype.getAngleOnCircle = function (center: IVec2Like): number {
|
|
|
|
const diffX = this.x - center.x;
|
|
|
|
const diffY = this.y - center.y;
|
|
|
|
const angle = Math.atan2(diffY, diffX);
|
|
|
|
return toDegree(angle) - 90;
|
|
|
|
};
|
|
|
|
|
|
|
|
//#endregion
|
|
|
|
|
|
|
|
//#region VEC3
|
|
|
|
|
|
|
|
Vec3.prototype.toVec2 = function () {
|
|
|
|
return new Vec2(this.x, this.y);
|
|
|
|
};
|
|
|
|
|
|
|
|
Vec3.prototype.getPositionOnCircle = function (angle: number, radius?: number) {
|
|
|
|
const rad = toRadian(angle);
|
|
|
|
const r = radius || 1;
|
|
|
|
const x = this.x + r * -Math.cos(rad);
|
|
|
|
const y = this.y + r * Math.sin(rad);
|
|
|
|
return new Vec3(x, y, this.z);
|
|
|
|
};
|
|
|
|
|
|
|
|
Vec3.prototype.getAngleOnCircle = function (center: IVec3Like): number {
|
|
|
|
const diffX = this.x - center.x;
|
|
|
|
const diffY = this.y - center.y;
|
|
|
|
const angle = Math.atan2(diffY, diffX);
|
|
|
|
return toDegree(angle) - 90;
|
|
|
|
};
|
|
|
|
|
|
|
|
//#endregion
|
|
|
|
|
|
|
|
//#region LABEL
|
|
|
|
|
|
|
|
Label.prototype.setString = function (value: string | number) {
|
|
|
|
if (typeof value == 'number') {
|
|
|
|
this.string = value.toString();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.string = value;
|
|
|
|
};
|
|
|
|
|
|
|
|
//#endregion
|
|
|
|
|
2024-06-07 00:08:39 -07:00
|
|
|
//#region SPRITE
|
|
|
|
|
|
|
|
Sprite.prototype.setFillRange = function (value: number) {
|
|
|
|
this.fillRange = value;
|
|
|
|
};
|
|
|
|
|
|
|
|
//#endregion
|
|
|
|
|
2024-05-07 03:20:37 -07:00
|
|
|
//#region STRING
|
|
|
|
|
|
|
|
String.prototype.jsonParse = function () {
|
|
|
|
try {
|
|
|
|
return JSON.parse(this);
|
|
|
|
} catch (error) {
|
|
|
|
console.log(error);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
String.prototype.isNullOrWhiteSpace = function () {
|
|
|
|
return !this || !this.trim();
|
|
|
|
};
|
|
|
|
|
|
|
|
//#endregion
|
|
|
|
|
|
|
|
//#region ARRAY
|
|
|
|
|
2024-06-12 04:48:19 -07:00
|
|
|
Array.prototype.getRandomIndex = function (weights?: number[]) {
|
|
|
|
if (weights) {
|
|
|
|
let weightsClone = [...weights];
|
|
|
|
const totalWeight = weightsClone.reduce((a, b) => a + b, 0);
|
|
|
|
let random = Math.random() * totalWeight;
|
|
|
|
let index;
|
|
|
|
this.findIndex((_, i) => (random -= weightsClone[i]) <= 0);
|
|
|
|
return index;
|
|
|
|
} else {
|
|
|
|
return randomRangeInt(0, this.length);
|
|
|
|
}
|
2024-06-10 21:35:13 -07:00
|
|
|
};
|
|
|
|
|
2024-05-07 03:20:37 -07:00
|
|
|
Array.prototype.getRandom = function (weights?: number[]) {
|
|
|
|
if (weights) {
|
|
|
|
let weightsClone = [...weights];
|
|
|
|
const totalWeight = weightsClone.reduce((a, b) => a + b, 0);
|
|
|
|
let random = Math.random() * totalWeight;
|
|
|
|
const item = this.find((_, i) => (random -= weightsClone[i]) <= 0);
|
|
|
|
return item;
|
|
|
|
} else {
|
|
|
|
return this[randomRangeInt(0, this.length)];
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
//#endregion
|
2024-06-07 00:08:39 -07:00
|
|
|
|
|
|
|
//#region AUDIO SOURCE
|
|
|
|
|
|
|
|
//support audio playbackRate
|
|
|
|
//@ts-ignore
|
|
|
|
AudioSource.prototype._playbackRate = 1;
|
|
|
|
//@ts-ignores
|
|
|
|
AudioSource.prototype._syncStates = function () {
|
|
|
|
if (this._player) {
|
|
|
|
this._player.loop = this._loop;
|
|
|
|
this._player.volume = this._volume;
|
|
|
|
// this._player._sourceNode.playbackRate = this._playbackRate;
|
|
|
|
|
|
|
|
this._operationsBeforeLoading.forEach((opInfo): void => {
|
|
|
|
if (opInfo.op === 'SEEK') {
|
|
|
|
this._cachedCurrentTime = (opInfo.params && opInfo.params[0]) as number;
|
|
|
|
if (this._player) {
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
|
|
this._player.seek(this._cachedCurrentTime).catch((e): void => {});
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
this[opInfo.op]?.();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
try {
|
|
|
|
this._player._player._sourceNode.playbackRate.value = this._playbackRate;
|
|
|
|
} catch (e) {
|
|
|
|
console.log(e);
|
|
|
|
}
|
|
|
|
this._operationsBeforeLoading.length = 0;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
AudioSource.prototype.getPlaybackRate = function () {
|
|
|
|
return this._playbackRate;
|
|
|
|
};
|
|
|
|
|
|
|
|
AudioSource.prototype.setPlaybackRate = function (value: number) {
|
2024-06-17 04:07:20 -07:00
|
|
|
this._playbackRate = value;
|
2024-06-07 00:08:39 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
//#endregion
|