pinball/assets/_Game/Scripts/Extension/Extension.ts

345 lines
8.8 KiB
TypeScript
Raw Normal View History

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,
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
const fixedTime = PhysicsSystem2D.instance.fixedTimeStep;
2024-06-07 00:08:39 -07:00
Game.prototype.timeScale = 1;
// @ts-ignore
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();
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