You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
4.1 KiB
150 lines
4.1 KiB
import {
|
|
autoDetectRenderer,
|
|
Container,
|
|
Renderer,
|
|
Ticker,
|
|
} from "pixi.js";
|
|
import { Orientation } from "@/enums/Orientation";
|
|
import { initDevtools } from "@pixi/devtools";
|
|
import { logger } from "./Logger";
|
|
import { tweenManager } from "@/utils/Tween";
|
|
|
|
class Game {
|
|
private static instance: Game;
|
|
private _stage: Container;
|
|
private _renderer: Renderer;
|
|
private _ticker: Ticker;
|
|
private orientation: Orientation = Orientation.Portrait;
|
|
|
|
public designWidth: number = 750;
|
|
|
|
public info: { width: number; height: number } = {
|
|
width: 0,
|
|
height: 0,
|
|
};
|
|
|
|
private constructor() {}
|
|
|
|
static getInstance(): Game {
|
|
if (!Game.instance) {
|
|
Game.instance = new Game();
|
|
}
|
|
return Game.instance;
|
|
}
|
|
|
|
public get renderer(): Renderer {
|
|
return this._renderer;
|
|
}
|
|
|
|
public get stage(): Container {
|
|
return this._stage;
|
|
}
|
|
|
|
public get ticker(): Ticker {
|
|
return this._ticker;
|
|
}
|
|
|
|
async init(): Promise<void> {
|
|
const screenWidth = document.documentElement.clientWidth;
|
|
const screenHeight = document.documentElement.clientHeight;
|
|
|
|
this._stage = new Container();
|
|
this._stage.label = "root";
|
|
|
|
this._renderer = await autoDetectRenderer({
|
|
autoDensity: true,
|
|
width: screenWidth,
|
|
height: screenHeight,
|
|
antialias: true,
|
|
backgroundAlpha: 1,
|
|
resolution: window.devicePixelRatio || 1,
|
|
backgroundColor: 0x1d9ce0,
|
|
});
|
|
|
|
this.renderer.resize(screenWidth, screenHeight);
|
|
document.body.appendChild(this.renderer.canvas);
|
|
|
|
window.addEventListener("resize", () => {
|
|
this.updateView();
|
|
});
|
|
|
|
this._ticker = Ticker.shared;
|
|
this._ticker.autoStart = true;
|
|
|
|
this._ticker.add(() => {
|
|
tweenManager.update();
|
|
});
|
|
|
|
if (import.meta.env.DEV) {
|
|
initDevtools({ stage: this._stage, renderer: this._renderer });
|
|
}
|
|
|
|
this.updateView();
|
|
logger.info("Game initialized", { screenWidth, screenHeight });
|
|
}
|
|
|
|
getInfo(): { width: number; height: number } {
|
|
return { ...this.info };
|
|
}
|
|
|
|
setOrientation(orientation: Orientation): void {
|
|
this.orientation = orientation;
|
|
this.updateView();
|
|
}
|
|
|
|
private detectCurrentOrientation(): Orientation {
|
|
const isLandscape = window.innerWidth > window.innerHeight;
|
|
return isLandscape ? Orientation.Landscape : Orientation.Portrait;
|
|
}
|
|
|
|
updateView(): void {
|
|
const clientWidth = document.documentElement.clientWidth;
|
|
const clientHeight = document.documentElement.clientHeight;
|
|
|
|
this.renderer.resize(clientWidth, clientHeight);
|
|
|
|
const currentOrientation = this.detectCurrentOrientation();
|
|
|
|
if (this.orientation === Orientation.Landscape) {
|
|
if (currentOrientation === Orientation.Landscape) {
|
|
this._stage.rotation = 0;
|
|
this._stage.position.set(0, 0);
|
|
const scaleRatio = clientWidth / this.designWidth;
|
|
this._stage.scale.set(scaleRatio, scaleRatio);
|
|
this.info.width = clientWidth / scaleRatio;
|
|
this.info.height = clientHeight / scaleRatio;
|
|
} else {
|
|
this._stage.rotation = Math.PI / 2;
|
|
this._stage.position.set(0, 0);
|
|
const scaleRatio = clientHeight / this.designWidth;
|
|
this._stage.scale.set(scaleRatio, scaleRatio);
|
|
this.info.width = clientHeight / scaleRatio;
|
|
this.info.height = clientWidth / scaleRatio;
|
|
}
|
|
} else {
|
|
if (currentOrientation === Orientation.Portrait) {
|
|
this._stage.rotation = 0;
|
|
this._stage.position.set(0, 0);
|
|
const scaleRatio = clientWidth / this.designWidth;
|
|
this._stage.scale.set(scaleRatio, scaleRatio);
|
|
this.info.width = clientWidth / scaleRatio;
|
|
this.info.height = clientHeight / scaleRatio;
|
|
} else {
|
|
this._stage.rotation = -Math.PI / 2;
|
|
this._stage.position.set(0, clientWidth);
|
|
const scaleRatio = clientHeight / this.designWidth;
|
|
this._stage.scale.set(scaleRatio, scaleRatio);
|
|
this.info.width = clientHeight / scaleRatio;
|
|
this.info.height = clientWidth / scaleRatio;
|
|
}
|
|
}
|
|
|
|
this.render();
|
|
}
|
|
|
|
render(): void {
|
|
this.renderer.render(this.stage);
|
|
}
|
|
}
|
|
|
|
export default Game;
|