feat(game): 实现精灵图渲染优化游戏性能

- 新增 AnimalSpriteImage 组件用于精灵图渲染
- 集成精灵图渲染到桌面版动物组件
- 集成精灵图渲染到移动版动物组件
- 重构历史记录组件使用精灵图渲染
- 更新动物覆盖层组件使用精灵图渲染
- 移除旧的单个图片资源引用
- 添加精灵图生成脚本和相关配置
- 优化启动资源加载排除精灵图源文件
- 添加精灵图位置计算工具函数
This commit is contained in:
JiaJun
2026-06-10 16:38:00 +08:00
parent da8adc336d
commit c3059549e6
20 changed files with 652 additions and 135 deletions

View File

@@ -0,0 +1,53 @@
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import sharp from 'sharp'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const rootDir = path.resolve(__dirname, '..')
const animalDir = path.join(rootDir, 'src/assets/animal')
const outputPath = path.join(animalDir, 'animal-sprite.webp')
const columns = 6
const rows = 6
const cellWidth = 446
const cellHeight = 224
const quality = 82
const composites = await Promise.all(
Array.from({ length: columns * rows }, async (_, index) => {
const id = index + 1
const input = path.join(animalDir, `${id}.webp`)
const left = (index % columns) * cellWidth
const top = Math.floor(index / columns) * cellHeight
const buffer = await sharp(input)
.resize(cellWidth, cellHeight, {
fit: 'cover',
position: 'center',
})
.webp({ quality })
.toBuffer()
return {
input: buffer,
left,
top,
}
}),
)
await sharp({
create: {
width: columns * cellWidth,
height: rows * cellHeight,
channels: 4,
background: { r: 0, g: 0, b: 0, alpha: 0 },
},
})
.composite(composites)
.webp({ quality })
.toFile(outputPath)
console.log(
`Generated ${path.relative(rootDir, outputPath)} (${columns}x${rows}, ${cellWidth}x${cellHeight})`,
)

View File

@@ -0,0 +1,53 @@
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import sharp from 'sharp'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const rootDir = path.resolve(__dirname, '..')
const rewardDir = path.join(rootDir, 'src/assets/reward')
const outputPath = path.join(rewardDir, 'reward-sprite.webp')
const columns = 6
const rows = 6
const cellWidth = 102
const cellHeight = 98
const quality = 86
const composites = await Promise.all(
Array.from({ length: columns * rows }, async (_, index) => {
const id = index + 1
const input = path.join(rewardDir, `${id}.webp`)
const left = (index % columns) * cellWidth
const top = Math.floor(index / columns) * cellHeight
const buffer = await sharp(input)
.resize(cellWidth, cellHeight, {
fit: 'contain',
background: { r: 0, g: 0, b: 0, alpha: 0 },
})
.webp({ quality })
.toBuffer()
return {
input: buffer,
left,
top,
}
}),
)
await sharp({
create: {
width: columns * cellWidth,
height: rows * cellHeight,
channels: 4,
background: { r: 0, g: 0, b: 0, alpha: 0 },
},
})
.composite(composites)
.webp({ quality })
.toFile(outputPath)
console.log(
`Generated ${path.relative(rootDir, outputPath)} (${columns}x${rows}, ${cellWidth}x${cellHeight})`,
)