feat(game): 实现精灵图渲染优化游戏性能
- 新增 AnimalSpriteImage 组件用于精灵图渲染 - 集成精灵图渲染到桌面版动物组件 - 集成精灵图渲染到移动版动物组件 - 重构历史记录组件使用精灵图渲染 - 更新动物覆盖层组件使用精灵图渲染 - 移除旧的单个图片资源引用 - 添加精灵图生成脚本和相关配置 - 优化启动资源加载排除精灵图源文件 - 添加精灵图位置计算工具函数
This commit is contained in:
53
scripts/generate-animal-sprite.mjs
Normal file
53
scripts/generate-animal-sprite.mjs
Normal 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})`,
|
||||
)
|
||||
53
scripts/generate-reward-sprite.mjs
Normal file
53
scripts/generate-reward-sprite.mjs
Normal 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})`,
|
||||
)
|
||||
Reference in New Issue
Block a user