1 changed files with 144 additions and 0 deletions
@ -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…
Reference in new issue