Add new method for exporting tileset

This commit is contained in:
Lucas S. Vieira 2025-01-11 00:20:05 -03:00
parent 6f1095e3dd
commit 4cc5a9ab01
3 changed files with 37 additions and 117 deletions

View file

@ -1,113 +0,0 @@
if TilesetMode == nil then return app.alert "Use Aseprite v1.3" end
-- Export tilesets for aseprite files with two layers: foreground and background
-- Layer names don't matter. Make sure foreground is on top.
-- 1. Copy both layers.
-- 2. Turn original layers invisible
-- 3. Flatten copied layers, make them visible
-- 4. Convert flattened layer to tilemap layer
-- 5. Export tileset
-- 6. Delete flattened layer
--local row_len = 32
local function activeFrameNumber()
local f = app.activeFrame
if f == nil then
return 1
else
return f
end
end
app.command.GotoFirstFrame()
local spr = app.activeSprite
local lay = app.activeLayer
local fs = app.fs
local output_folder = fs.filePath(spr.filename)
if not lay.isTilemap then return app.alert "No active tilemap layer" end
local function layers_tilemap_duplicate(spr)
for i,layer in ipairs(spr.layers) do
if layer.isTilemap then
app.activeLayer = layer
layer.isVisible = true
app.command.DuplicateLayer()
layer.isVisible = false
else
layer.isVisible = false
end
end
end
local function layers_visible_flatten(spr)
for i,layer in ipairs(spr.layers) do
app.command.FlattenLayers{["visibleOnly"]="true"}
local grid = spr.gridBounds
grid.height = 8
grid.width = 8
spr.gridBounds = grid
--row_len = 256 / grid.width
end
end
local function layers_2visible(spr)
for i,layer in ipairs(spr.layers) do
layer.isVisible = true
end
end
local function layers_visible2tilemap(spr)
for i,layer in ipairs(spr.layers) do
if layer.isVisible then
app.command.ConvertLayer{["to"]="tilemap"}
end
end
end
local function layers_getName(layers,name)
local out
for i,layer in ipairs(layers) do
if (layers[i].name == name) then
out = layers[i]
break
end
end
return out
end
layers_tilemap_duplicate(spr)
layers_visible_flatten(spr)
layers_visible2tilemap(spr)
local lay = layers_getName(spr.layers,"Flattened")
app.activeLayer = lay
if lay.isTilemap then
local tileset = lay.tileset
local spec = spr.spec
local grid = tileset.grid
local size = grid.tileSize
local row_len = 256 / size.width
spec.width = 256
local col_len = math.ceil(#tileset / row_len)
spec.height = size.height * col_len
local image = Image(spec)
image:clear()
for i = 0,row_len-1 do
for j = 0, col_len do
local current = i + j* row_len
if (current < #tileset) then
local tile = tileset:getTile(current)
image:drawImage(tile, i*size.width, j*size.height)
end
end
end
local path = fs.joinPath(output_folder, app.fs.fileTitle(spr.filename) .. ".png")
image:saveAs(path)
end
app.command.RemoveLayer()
layers_2visible(spr)

View file

@ -30,6 +30,8 @@ To run any scripts with this venv, run ~./tools/venv/bin/python
* Generating a character sprite 8x8 tileset and mappings
** Exporting tilemap and tileset
For characters, we need to use the Aseprite tool for building sprites.
Import the character's sprites as a sprite sheet and into an .aseprite file (see
@ -40,13 +42,42 @@ layer, with 8x8 tiles. Plus, you'll have to organize the frames in such a way
that frames of the same animation are coupled together.
Finally, group frames into animations by creating tags with animation names
(again, see 'SONIC.aseprite' for valid animation names).
(again, see 'SONIC.ase' for valid animation names).
Finally, export the animation names and mappings using 'export_tilemap_psx.lua',
then export the player tileset using 'export_tileset_psx.lua'.
Finally, export the animation names and mappings using 'export_tilemap_psx.lua'.
Now to export the tileset itself, you'll need to File > Export > Export
Tileset. On this window, choose the following options:
- Sheet Type: By Rows;
- Constraints: Fixed Width;
- Merge Duplicates: Yes;
- Borders
- Spacing: 1;
- Output
- Output File: SONIC.png.
[[file:sprite_export_settings.png]]
This will create a 'SONIC.png' file and a 'SONIC.json' file.
** Tweaking the texture
This is not over yet -- You'll need to open up SONIC.png on a tool such as GIMP
and guarantee that no individual tile is being divided by the 256px line at the
bottom of the image.
If so, you'll need to take the row of tiles that is being cut in half and move
it downwards so the first pixel in Y coordinate aligns with position 256.
This is necessary since these tiles need to be within a 256x256 texture, and
when they can't, we simply snap them to the next texture page (in this case, at
the bottom). So the sprites use four texture pages (two horizontally since it
uses 8bpp color, and other two on the bottom of VRAM since they don't fit in a
single row), but the same CLUT.
** Produce a TIM texture and a CHARA file
Now, just pack the frame and tile data into a CHARA file, and generate a TIM
image with correct CLUT and TPAGE info:
@ -59,7 +90,9 @@ Notice that, different than other image tile data, character sprites rely on a
PNG's alpha channel to generate transparency bits, instead of using the full
black color as mask.
NOTE: If you need to refer to an animation directly by name, the animations are
** Animation names and generating their Adler32 hashes
If you need to refer to an animation directly by name, the animations are
referred to by the engine by their Adler32 hash, so you might want to add a new
definition for that on ~player.c~.

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB