From 36c9522e8a9b94da6fac591cf0b119ec259ae305 Mon Sep 17 00:00:00 2001 From: Dennis Postma Date: Tue, 11 Mar 2025 23:53:27 +0100 Subject: [PATCH] Improvements --- .../gameMaster/assetManager/sprite/update.ts | 136 ++++++++++-------- src/mikro-orm.config.ts | 6 +- 2 files changed, 77 insertions(+), 65 deletions(-) diff --git a/src/events/gameMaster/assetManager/sprite/update.ts b/src/events/gameMaster/assetManager/sprite/update.ts index 995bee4..7b3b319 100644 --- a/src/events/gameMaster/assetManager/sprite/update.ts +++ b/src/events/gameMaster/assetManager/sprite/update.ts @@ -76,12 +76,8 @@ export default class SpriteUpdateEvent extends BaseEvent { if (actionData.sprites.length === 0) continue // Generate and save the sprite sheet - const frameSize = await this.generateAndSaveSpriteSheet( - actionData.sprites, - sprite.getId(), - actionData.action - ) - if (!frameSize) return false + const frameDimensions = await this.generateAndSaveSpriteSheet(actionData.sprites, sprite.getId(), actionData.action) + if (!frameDimensions) return false // Create and save sprite action const spriteAction = new SpriteAction() @@ -89,13 +85,13 @@ export default class SpriteUpdateEvent extends BaseEvent { sprite.getSpriteActions().add(spriteAction) spriteAction - .setAction(actionData.action) - .setSprites(actionData.sprites) - .setOriginX(actionData.originX) - .setOriginY(actionData.originY) - .setFrameWidth(frameSize.width) - .setFrameHeight(frameSize.height) - .setFrameRate(actionData.frameRate) + .setAction(actionData.action) + .setSprites(actionData.sprites) + .setOriginX(actionData.originX) + .setOriginY(actionData.originY) + .setFrameWidth(frameDimensions.frameWidth) + .setFrameHeight(frameDimensions.frameHeight) + .setFrameRate(actionData.frameRate) await this.spriteRepository.getEntityManager().persistAndFlush(spriteAction) } @@ -107,80 +103,96 @@ export default class SpriteUpdateEvent extends BaseEvent { } } - private async generateAndSaveSpriteSheet( - sprites: SpriteImage[], - spriteId: string, - action: string - ): Promise<{ width: number, height: number } | null> { + private async generateAndSaveSpriteSheet(sprites: SpriteImage[], spriteId: string, action: string): Promise<{ frameWidth: number; frameHeight: number } | null> { try { - if (sprites.length === 0) return { width: 0, height: 0 } + if (sprites.length === 0) return { frameWidth: 0, frameHeight: 0 } - // Extract image data from sprites - const imageBuffers = await Promise.all( - sprites.map(sprite => { - const base64Data = sprite.url.split(';base64,').pop() - if (!base64Data) throw new Error('Invalid base64 image') - return Buffer.from(base64Data, 'base64') - }) + // Extract image data and get image metadata + const imagesData = await Promise.all( + sprites.map(async (sprite) => { + const base64Data = sprite.url.split(';base64,').pop() + if (!base64Data) throw new Error('Invalid base64 image') + const buffer = Buffer.from(base64Data, 'base64') + const metadata = await sharp(buffer).metadata() + + return { + buffer, + width: metadata.width || 0, + height: metadata.height || 0 + } + }) ) - // Get metadata for all images to find the maximum dimensions - const metadataList = await Promise.all( - imageBuffers.map(buffer => sharp(buffer).metadata()) - ) - - // Calculate the maximum width and height across all frames - const maxWidth = Math.max(...metadataList.map(meta => meta.width || 0)) - const maxHeight = Math.max(...metadataList.map(meta => meta.height || 0)) - - // Skip creation if we couldn't determine dimensions - if (maxWidth === 0 || maxHeight === 0) { - console.error('Could not determine sprite dimensions') + // Skip creation if any image has invalid dimensions + if (imagesData.some((data) => data.width === 0 || data.height === 0)) { + console.error('One or more sprites have invalid dimensions') return null } - // Resize all frames to the same dimensions - const resizedFrames = await Promise.all( - imageBuffers.map(async (buffer) => { - return sharp(buffer) - .resize({ - width: maxWidth, - height: maxHeight, - fit: 'contain', - background: { r: 0, g: 0, b: 0, alpha: 0 } - }) - .toBuffer() + // Calculate the maximum width and height to use for all frames + const maxWidth = Math.max(...imagesData.map((data) => data.width)) + const maxHeight = Math.max(...imagesData.map((data) => data.height)) + + // Create frames of uniform size with the original sprites centered + const uniformFrames = await Promise.all( + imagesData.map(async (imageData) => { + // Calculate centering offsets to position the sprite in the middle of the frame + const xOffset = Math.floor((maxWidth - imageData.width) / 2) + const yOffset = Math.floor((maxHeight - imageData.height) / 2) + + // Create a uniform-sized frame with the sprite centered + return sharp({ + create: { + width: maxWidth, + height: maxHeight, + channels: 4, + background: { r: 0, g: 0, b: 0, alpha: 0 } + } }) + .composite([ + { + input: imageData.buffer, + left: xOffset, + top: yOffset + } + ]) + .png() + .toBuffer() + }) ) - // Create sprite sheet with uniformly sized frames + // Create the sprite sheet with uniform frames const spriteSheet = await sharp({ create: { - width: maxWidth * resizedFrames.length, + width: maxWidth * uniformFrames.length, height: maxHeight, channels: 4, background: { r: 0, g: 0, b: 0, alpha: 0 } } }) - .composite( - resizedFrames.map((buffer, index) => ({ - input: buffer, - left: index * maxWidth, - top: 0 - })) - ) - .png() - .toBuffer() + .composite( + uniformFrames.map((buffer, index) => ({ + input: buffer, + left: index * maxWidth, + top: 0 + })) + ) + .png() + .toBuffer() // Save sprite sheet const dir = `public/sprites/${spriteId}` await fs.promises.mkdir(dir, { recursive: true }) await fs.promises.writeFile(`${dir}/${action}.png`, spriteSheet) - return { width: maxWidth, height: maxHeight } + // Return the uniform frame dimensions + return { + frameWidth: maxWidth, + frameHeight: maxHeight + } } catch (error) { console.error('Error generating sprite sheet:', error) return null } } -} \ No newline at end of file +} diff --git a/src/mikro-orm.config.ts b/src/mikro-orm.config.ts index f1844ef..5f21b31 100644 --- a/src/mikro-orm.config.ts +++ b/src/mikro-orm.config.ts @@ -1,7 +1,7 @@ import serverConfig from '@/application/config' import { Migrator } from '@mikro-orm/migrations' -// import { defineConfig, MariaDbDriver } from '@mikro-orm/mariadb' -import { defineConfig, MySqlDriver } from '@mikro-orm/mysql' +import { defineConfig, MariaDbDriver } from '@mikro-orm/mariadb' +// import { defineConfig, MySqlDriver } from '@mikro-orm/mysql' import { TsMorphMetadataProvider } from '@mikro-orm/reflection' export default defineConfig({ @@ -9,7 +9,7 @@ export default defineConfig({ metadataProvider: TsMorphMetadataProvider, entities: ['./src/entities/*.ts'], entitiesTs: ['./src/entities/*.ts'], - driver: MySqlDriver, + driver: MariaDbDriver, host: serverConfig.DB_HOST, port: serverConfig.DB_PORT, user: serverConfig.DB_USER,