mirror of
https://github.com/Aviortheking/games.git
synced 2025-07-03 22:59:19 +00:00
uodate
This commit is contained in:
@ -45,4 +45,9 @@ export default class Vector2D {
|
||||
parseFloat(this.y.toFixed(nDecimal))
|
||||
)
|
||||
}
|
||||
|
||||
public set(x: number, y: number) {
|
||||
this.x = x
|
||||
this.y = y
|
||||
}
|
||||
}
|
||||
|
@ -10,10 +10,21 @@ export interface ComponentState {
|
||||
isColliding?: string
|
||||
}
|
||||
|
||||
export type StaticComponent<
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
T extends {} | void = {} | void
|
||||
> =
|
||||
new (params: T | undefined) => Component2D<T>
|
||||
|
||||
/**
|
||||
* 2D Component
|
||||
*/
|
||||
export default abstract class Component2D {
|
||||
export default abstract class Component2D<
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
T extends {} | void = {} | void
|
||||
> {
|
||||
|
||||
public params: T = {} as T
|
||||
|
||||
/**
|
||||
* Indicate how the component is rendered
|
||||
@ -75,6 +86,12 @@ export default abstract class Component2D {
|
||||
*/
|
||||
public debug?: boolean
|
||||
|
||||
public constructor(it: T | void) {
|
||||
if (it) {
|
||||
this.params = it
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function run when the component is initialized
|
||||
*/
|
||||
|
@ -1,25 +1,57 @@
|
||||
import GameEngine from 'GameEngine'
|
||||
import ComponentDebug from 'GameEngine/2D/Debug/ComponentDebug'
|
||||
import Vector2D from 'GameEngine/2D/Vector2D'
|
||||
import Component2D from 'GameEngine/Component2D'
|
||||
import Renderer from 'GameEngine/Renderer'
|
||||
import TextRenderer from 'GameEngine/Renderer/TextRenderer'
|
||||
|
||||
export default class FPSCounter extends Component2D {
|
||||
export default class FPSCounter extends Component2D<{textColor?: string, size?: number}> {
|
||||
|
||||
|
||||
public position: Vector2D = new Vector2D(0,0)
|
||||
public position: Vector2D = new Vector2D(10,8)
|
||||
public scale: Vector2D = new Vector2D(1, 1)
|
||||
public origin: Vector2D = new Vector2D(0, 0)
|
||||
public childs: Array<Component2D> = [new ComponentDebug(this)]
|
||||
|
||||
public renderer: TextRenderer = new TextRenderer(this, {text: 'pouet'})
|
||||
public renderer: TextRenderer = new TextRenderer(this, {text: 'loading...'})
|
||||
|
||||
private lastUpdate: number = new Date().getTime()
|
||||
private length = 1
|
||||
private previousFrameTimes: Array<number> = []
|
||||
private lastUpdate = window.performance.now() * 1000
|
||||
|
||||
public init() {
|
||||
const fps = GameEngine.getGameEngine().options?.goalFramerate
|
||||
if (!fps || fps < 1) {
|
||||
this.length = 60
|
||||
} else {
|
||||
this.length = fps
|
||||
}
|
||||
|
||||
if (this.params.textColor) {
|
||||
this.renderer.color = this.params.textColor
|
||||
}
|
||||
|
||||
if (this.params.size) {
|
||||
this.renderer.size = this.params.size
|
||||
}
|
||||
}
|
||||
|
||||
public update() {
|
||||
const now = new Date().getTime()
|
||||
this.renderer.text = (1000 / (now - this.lastUpdate)).toFixed(2)
|
||||
this.lastUpdate = now
|
||||
const t = GameEngine.getGameEngine().lastFrame
|
||||
// if (!t) {return}
|
||||
// console.log(this.previousFrameTimes, t)
|
||||
const diff = t - this.lastUpdate
|
||||
this.lastUpdate = t
|
||||
this.previousFrameTimes.push(diff)
|
||||
if (this.previousFrameTimes.length > this.length) {
|
||||
this.previousFrameTimes.shift()
|
||||
}
|
||||
const time = (this.previousFrameTimes.reduce((p, c) => p + c, 0)) / this.previousFrameTimes.length
|
||||
if (time === 0) {
|
||||
this.renderer.text = 'a lot'
|
||||
} else {
|
||||
this.renderer.text = (1000 / time).toFixed(2)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -29,17 +29,14 @@ export default class Scene {
|
||||
}
|
||||
|
||||
public async init() {
|
||||
this.components.forEach((v) => {
|
||||
if (v.init) {
|
||||
v.init()
|
||||
}
|
||||
})
|
||||
for await (const component of this.components) {
|
||||
await component.init?.()
|
||||
}
|
||||
}
|
||||
|
||||
public async update() {
|
||||
for (let index = 0; index < this.components.length; index++) {
|
||||
const component = this.components[index];
|
||||
await this.updateComponent(component, index)
|
||||
await this.updateComponent(this.components[index], index)
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,8 +96,8 @@ export default class Scene {
|
||||
if (debug) {
|
||||
console.log('Processing childs', v)
|
||||
}
|
||||
for await (const child of v.childs) {
|
||||
await this.updateComponent(child)
|
||||
for (let cIndex = 0; cIndex < v.childs.length; cIndex++) {
|
||||
await this.updateComponent(v.childs[cIndex], cIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,8 +22,23 @@ export default class GameEngine {
|
||||
wasDown: false
|
||||
}
|
||||
public currentScene?: Scene
|
||||
|
||||
// last frame timestamp
|
||||
public lastFrame = 0
|
||||
|
||||
/**
|
||||
* last frame execution time in milliseconds
|
||||
*
|
||||
* @memberof GameEngine
|
||||
*/
|
||||
public frameTime = 0
|
||||
|
||||
private isRunning = false
|
||||
private timer = 16.6
|
||||
|
||||
|
||||
// timer between frames
|
||||
private timer = 0
|
||||
|
||||
|
||||
public constructor(
|
||||
id: string,
|
||||
@ -61,12 +76,8 @@ export default class GameEngine {
|
||||
ctx.imageSmoothingEnabled = false
|
||||
this.ctx = ctx
|
||||
|
||||
if (options?.goalFramerate) {
|
||||
if (options.goalFramerate === -1) {
|
||||
this.timer = 0
|
||||
} else {
|
||||
this.timer = 1000 / options.goalFramerate
|
||||
}
|
||||
if (options?.goalFramerate && options.goalFramerate >= 0) {
|
||||
this.timer = 1000 / options.goalFramerate
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,13 +91,11 @@ export default class GameEngine {
|
||||
return
|
||||
}
|
||||
this.isRunning = true
|
||||
requestAnimationFrame(() => {
|
||||
this.update()
|
||||
})
|
||||
this.currentScene?.init().then(() => this.update())
|
||||
document.addEventListener('mousemove', (ev) => {
|
||||
this.cursor.position = new Vector2D(
|
||||
ev.clientX / this.caseSize.x - (this.currentScene?.camera?.topLeft?.x ?? 0),
|
||||
ev.clientY / this.caseSize.y - (this.currentScene?.camera?.topLeft?.y ?? 0)
|
||||
(ev.clientX + window.scrollX) / this.caseSize.x - (this.currentScene?.camera?.topLeft?.x ?? 0),
|
||||
(ev.clientY + window.scrollY) / this.caseSize.y - (this.currentScene?.camera?.topLeft?.y ?? 0)
|
||||
)
|
||||
if (this.cursor.isDown) {
|
||||
this.cursor.wasDown = true
|
||||
@ -109,35 +118,66 @@ export default class GameEngine {
|
||||
|
||||
public async setScene(scene: Scene | string) {
|
||||
console.log('Setting scene', typeof scene === 'string' ? scene : scene.id)
|
||||
const wasRunning = this.isRunning
|
||||
if (wasRunning) {
|
||||
this.isRunning = false
|
||||
}
|
||||
await this.currentScene?.destroy()
|
||||
await this.currentScene?.init()
|
||||
if (wasRunning) {
|
||||
this.isRunning = true
|
||||
}
|
||||
this.currentScene = typeof scene === 'string' ? Scene.scenes[scene] : scene
|
||||
this.currentScene.setGameEngine(this)
|
||||
}
|
||||
|
||||
private update() {
|
||||
const now = new Date().getTime()
|
||||
if (!this.isRunning) {
|
||||
return
|
||||
}
|
||||
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
|
||||
if (this.options?.background) {
|
||||
this.ctx.fillStyle = this.options.background
|
||||
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height)
|
||||
}
|
||||
this.currentScene?.update()
|
||||
const diff = new Date().getTime() - now
|
||||
if (diff > this.timer) {
|
||||
requestAnimationFrame(() => {
|
||||
this.update()
|
||||
})
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
// this.update()
|
||||
requestAnimationFrame(() => {
|
||||
this.update()
|
||||
})
|
||||
}, this.timer - diff)
|
||||
}
|
||||
private async update() {
|
||||
// console.log('update')
|
||||
let frameFinished = true
|
||||
setInterval((it) => {
|
||||
// get current time
|
||||
const now = window.performance.now()
|
||||
|
||||
// game is not runnig, wait a frame
|
||||
if (!this.isRunning || !frameFinished) {
|
||||
// console.log('skip frame')
|
||||
// setTimeout(() => {
|
||||
// this.update()
|
||||
// }, this.timer)
|
||||
return
|
||||
}
|
||||
|
||||
// game is running too fast, wait until necessary
|
||||
if (this.lastFrame + this.timer > now ) {
|
||||
// console.log('skip frame')
|
||||
// setTimeout(() => {
|
||||
// this.update()
|
||||
// }, (this.lastFrame + this.timer) - now)
|
||||
return
|
||||
}
|
||||
// console.log('new frame')
|
||||
frameFinished = false
|
||||
|
||||
// if a background need to be drawn
|
||||
if (this.options?.background) {
|
||||
this.ctx.fillStyle = this.options.background
|
||||
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height)
|
||||
} else {
|
||||
// clear the previous frame
|
||||
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
|
||||
}
|
||||
|
||||
// update scene
|
||||
this.currentScene?.update()
|
||||
|
||||
// calculate for next frame
|
||||
this.lastFrame = window.performance.now()
|
||||
this.frameTime = window.performance.now() - now
|
||||
frameFinished = true
|
||||
// this.update()
|
||||
// requestAnimationFrame(() => {
|
||||
// })
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user