Browse Source

feat: add Game core class with orientation handling

master
npmrun 4 weeks ago
parent
commit
a0b54f4231
  1. 144
      src/core/Game.ts

144
src/core/Game.ts

@ -0,0 +1,144 @@
import {
autoDetectRenderer,
Container,
Renderer,
Ticker,
} from "pixi.js";
import { Orientation } from "@/enums/Orientation";
import { initDevtools } from "@pixi/devtools";
import { logger } from "./Logger";
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: 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: 255,
resolution: 2,
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;
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();
let offsetWidth = clientWidth;
let offsetHeight = clientHeight;
if (this.orientation === Orientation.Landscape) {
if (currentOrientation === Orientation.Landscape) {
this._stage.rotation = 0;
this._stage.y = 0;
} else {
this._stage.rotation = -Math.PI / 2;
this._stage.y = clientHeight;
}
const scaleRatio = clientWidth / this.designWidth;
this._stage.scale.set(scaleRatio, scaleRatio);
this.info.width = offsetWidth / scaleRatio;
this.info.height = offsetHeight / scaleRatio;
} else {
if (currentOrientation === Orientation.Landscape) {
this._stage.rotation = 0;
this._stage.y = 0;
const scaleRatio = offsetWidth / this.designWidth;
this._stage.scale.set(scaleRatio, scaleRatio);
this.info.width = offsetHeight / scaleRatio;
this.info.height = offsetWidth / scaleRatio;
} else {
this._stage.rotation = -Math.PI / 2;
this._stage.y = offsetHeight;
const scaleRatio = offsetWidth / this.designWidth;
this._stage.scale.set(scaleRatio, scaleRatio);
this.info.width = offsetHeight / scaleRatio;
this.info.height = offsetWidth / scaleRatio;
}
}
this.render();
}
render(): void {
this.renderer.render(this.stage);
}
}
export default Game;
Loading…
Cancel
Save