So you let the player select a series of sprite sheets. And there is some order in which you overlay them to create the sprite sheet of the player.
Image manipulation at runtime
We can create an
var image = Image.new()
256,256 with the appropriate size.
There the format is important. You want a format that has an alpha channel, otherwise, you will not be able to draw with transparency.
Now we need the image we are going to draw (the first sprite sheet). We can use
preload to get it. For example:
var icon := preload("res://icon.png")
We usually import as textures, but we want an image. So we use
var source := preload("res://icon.png").get_data()
Then we can draw it with
image.blit_rect(source, Rect2(Vector2.ZERO, source.get_size()), Vector2.ZERO)
Rect2 is the source area (the area of the image we are drawing that we want to draw) which goes from
Vector2.ZERO to the size of the image. The other
Vector2.ZERO is the position where we want to draw it.
Now the idea is that you will do that for all the sprite sheets that you need to draw.
Note: depending on the format of the image you want to draw, you may have to convert it first:
Also, usually, the images are imported in a compressed format that cannot be converted directly, and thus you would have to decompress first:
blit_rect line is giving you problems, try that.
Using a Viewport texture
If you found the above approach too limiting. You can add a
Viewport with a
Camera2D. Then to get the texture from the
Viewport, you can use
viewport.get_texture() (and, of course, you can get an
Image from it with
Thus, you can add to the
Viewport anything you want to draw. Which means that you can add multiple nodes to compose the image, with their transforms and modulations. Or it could be a single one which uses the methods described in Custom drawing in 2D, or CanvasItem shaders (For example, you may allow the user to do a hue rotation of a sprite sheet, implemented in a shader). Or combinations of those techniques.
Creating sprite frames for animation
Once you are done, you can create an ImageTexture from the
Image, like this:
image_texture = ImageTexture.new()
Since we are talking of sprite sheet, we can create
func get_texture_frame(row, column):
var t = AtlasTexture.new()
t.atlas = image_texture
t.region = (
column * SPRITE_WIDTH,
row * SPRITE_HEIGHT,
Then we can add the
AtlasTextures to a
add_frame to use them in an
SpriteFrames in code looks something like this:
var frames := SpriteFrames.new()
frames.add_frame("animation_name", get_texture_frame(0, 0))
frames.add_frame("animation_name", get_texture_frame(0, 1))
If you want to save an
Image, you can use
If you want to save the
ImageTexture or the
AtlasTextures or the
SpriteFrames, you can use
ResourceSaver.save. I suggest to use path in
user://, see Data Paths.
To load them again, you can use