If you're having trouble or run into any bugs with the code, post a comment here! I will try to get back to you within a few days.
Hello, first of all. Thank you for the time and effort you've dedicated to creating renpy tools and guides. Its wonderful. Next, I was trying out the layered image mask code to see what I could do with it, but I kept running into an issue. Anytime I try to use:
LayeredImageMask()
to define something, I get the following error
AttributeError: 'MultiBox' object has no attribute '_choose_attributes'
would you happen to know why that is?
Oh! Apologies for the delayed response. The error appears when I use
show angel cutin
which is defined as shown in the example on the itch page as
image angel cutin = LayeredImageMask("angel", Transform(crop=(230, 0, 564, 953)), mask="gui/mask.png")The "angel" image is a layered image defined as
image angel = LiveComposite(
(277, 277),
(0, 0), "angelbase@3.png",
(0, 0), "angel normal",
(0, 0), WhileSpeaking("angel", "angel talk", "angelbasemouthclosed@3.png"),
)
However, I also get the error message when I attempt this with a basic png. My renpy version is: 8.3.0.24082114
Thanks again for your time.
The full error message is:
I'm sorry, but an uncaught exception occurred.
While running game code:
File "game/script.rpy", line 680, in script
show angel cutin
File "renpy/common/00layeredimage.rpy", line 1195, in _choose_attributes
return self.filter_attributes(self.image._choose_attributes(tag, attributes, optional))
AttributeError: 'MultiBox' object has no attribute '_choose_attributes'
-- Full Traceback ------------------------------------------------------------
Full traceback:
File "game/script.rpy", line 680, in script
show angel cutin
File "C:\Users\streg\Documents\Visual Novels\renpy-8.3.0-sdk\renpy\ast.py", line 1111, in execute
show_imspec(self.imspec, atl=getattr(self, "atl", None))
File "C:\Users\streg\Documents\Visual Novels\renpy-8.3.0-sdk\renpy\ast.py", line 1074, in show_imspec
renpy.config.show(name,
File "C:\Users\streg\Documents\Visual Novels\renpy-8.3.0-sdk\renpy\exports\displayexports.py", line 474, in show
name, what = _find_image(layer, key, name, what)
File "C:\Users\streg\Documents\Visual Novels\renpy-8.3.0-sdk\renpy\exports\displayexports.py", line 278, in _find_image
new_image = renpy.game.context().images.apply_attributes(layer, key, name)
File "C:\Users\streg\Documents\Visual Novels\renpy-8.3.0-sdk\renpy\display\image.py", line 990, in apply_attributes
return self.choose_image(nametag, required, optional, name)
File "C:\Users\streg\Documents\Visual Novels\renpy-8.3.0-sdk\renpy\display\image.py", line 1011, in choose_image
newattrs = ca(tag, ca_required, ca_optional)
File "renpy/common/00layeredimage.rpy", line 1195, in _choose_attributes
return self.filter_attributes(self.image._choose_attributes(tag, attributes, optional))
AttributeError: 'MultiBox' object has no attribute '_choose_attributes'
Windows-10-10.0.19044 AMD64
Ren'Py 8.3.0.24082114
HEATWAVE MINIMUM WAGE MAXIMUM DEBT 1.0
Mon Oct 7 10:23:32 2024
The problem is your angel image is not a layered image - if you don't have a layered image you'd just use regular AlphaMask and not the LayeredImageMask. Layered images are declared like layeredimage angel and have a specific format that Ren'Py expects. I suggest you look into it, as it's the modern and simpler way to put together images with multiple layers. https://www.renpy.org/doc/html/layeredimage.html#LayeredImage
If your question is whether you can use a defined image displayable instead of a layered image - the answer is no, that's what a regular AlphaMask displayable is for. If your question is if you can use a defined image displayable for the mask image, sure! LayeredImageMask takes any kind of displayable for the mask, just like AlphaMask does.
Sure! It's a bit of a weird setup, but you can use a regular function as the Transform argument to LayeredImageMask. Here's an example:
image fen_masked = LayeredImageMask("feniks", lambda x : At(x, adjust_crop), mask="mask2", background="bg2")
transform adjust_crop:
animation
crop (0, 0, 637, 431)
linear 2.0 crop (1171-637, 950-431, 637, 431)
linear 2.0 crop (0, 0, 637, 431)
repeat
label start:
"Start"
show fen_masked at truecenter
"Tada"
show fen_masked sparkle animated right2
"Sparkle"
The important part is the lambda - that's a function. You could also make a regular function that returns At(<img>, <transform>) yourself and set that as the second argument to LayeredImageMask. The `animation` property in the transform is also important so that the transform doesn't reset for every new expression change. Hope that helps!