I’m currently creating a jigsaw puzzle game and I’m a bit stuck on something apparently easy, I want to get a new image with a predetermined shape using another image as mask (an svg) but the resulting image is zero and I get the following error:
jigsaw_core.gd:38 @ _ready(): Condition “dsize == 0” is true. (line 38 is the line where I use blit_rect_mask)
Basically I want to extract a piece of image and display it in a jigsaw piece.
This is the svg image:
@export var puzzle_width := 9
@export var puzzle_height := 5
@export var puzzle_scale := Vector2i.ONE
@onready var puzzle_image: TextureRect = $PuzzleImage
@onready var puzzle_image_dimensions := Utilities.get_texture_dimensions(image_to_puzzle)
const PUZZLE_SHAPE = preload("res://components/algorithms/jigsaw_puzzle/assets/pieces/puzzle_shape.svg")
func _ready():
puzzle_image.texture = image_to_puzzle
puzzle_image.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
puzzle_image.custom_minimum_size = puzzle_image_dimensions.size * puzzle_scale
divide_image_into_pieces()
var current_puzzle_image = puzzle_image.texture.get_image()
var puzzle_shape_image = PUZZLE_SHAPE.get_image()
var puzzle_shape_size = puzzle_shape_image.get_size()
var piece_shape = Image.new()
piece_shape.create(puzzle_shape_size.x, puzzle_shape_size.y, true, Image.FORMAT_RGBA8)
piece_shape.fill(Color.TRANSPARENT)
piece_shape.blit_rect_mask(current_puzzle_image, puzzle_shape_image, Rect2(Vector2.ZERO, puzzle_shape_size), Vector2.ZERO)
## TEST PURPOSES
var sprite = Sprite2D.new()
sprite.texture = ImageTexture.create_from_image(piece_shape)
add_child(sprite)
One thing to think about doing is to use your own canvas material shader in a material to do this, where it would have two texture inputs, the whole puzzle image, then a slot for the shape mask, then with a few exposed parameters, you would feed that material the offset coordinates to shift the mapping of the whole puzzle image, etc.
Then you wouldn’t have to do the extra image creation, which I imagine you’d need to do for all pieces, which could be time consuming in ms to bake, and memory intensive especially if you want high resolution pieces.
Hey @roc4u1000 thanks for your contribution. For now to generate about 500 pieces, there is not a big memory consumption since I have the parts I use as a mask preloaded.
I have also tried your alternative with assigning a ShaderMaterial where I pass the mask as a texture instead of creating it by code.
For the memory part I was referring to the cost of the generated images in runtime memory, the generated piece image puzzle_shape_image that are assigned to all of those 500 sprites. All of that would be in memory during the game, as well as the full puzzle_image source texture and then all of the source mask_image textures for all of pieces.
If you just had the puzzle_image texture in memory and all of the mask_image textures it should be much less runtime memory overall, but that would depend on the resulting resolution of those generated piece images and how many you make.
For the perf, drawing them either way is cheap and performant, I was thinking how much ms it would take to generate all of those puzzle piece images, but it is still minimal though I wonder about generating 500 of them and if there are any delays in gameplay that would be a consideration, and the ways around doing that if it is a problem.