Add support for separate X and Y sprite scaling
Enhancement request:
What should be added/changed?
- Add
scale_xandscale_yproperties to sprites - Allow
Sprite.rescale_relative_to_pointto takeUnion[float, Sequence[float, float]]
The existing scale property could continue to take only scalar values, or optionally accept Union[float, Sequence[float, float]] as well.
What would it help with?
It could help with efficiently implementing UI elements such as progress or health bars, as well as sliders. Examples include the following issues:
- #1101
- #1164
Pixel game UIs would benefit from stretching simple rectangle textures, saving atlas space by re-using simple white textures with tint colors applied on the sprite. I thought we already added this to SolidSpriteColor, but it seems like the optimizations were never written. The current SpriteSolidColor implementation generates multiple textures for different widths and heights.
The 9patch renderer could use this ticket's functionality to handle the internal and side (left, top, right, and bottom) portions of the 9patch data inside the texture atlas. This could make the code cleaner if we want to keep it in Python instead of shaders.
The internal sprite buffers already have a vec2 size, so there's nothing hundering this change I think. Still, this can affect collision functions and the spatial hash. needs to be looked into. I think the single scale value was mostly there so users don't accidentally create sprite with the wrong aspect ratio, but allowing that opens up a lot more possibilities.
It's a hassle to make things like health bars with sprites at the moment due to this limitation.
It is already pretty easy to use the width and height of the sprite. We could consolidate the two into one.
We could consolidate the two into one.
Offering unified pair setters like Sprite.position is something we should consider in general. It could help avoid excessive sprite list updates like the ones in #1187.
For functions that could take Union[float, Sequence[float, float]], we could add a utility function that expands single floats into a repeated tuple:
def as_pair(param: Union[float, Sequence[float, float]]) -> Sequence[float, float]:
if not hasattr(param, '__len__'):
return param, param
return param
I've used a similar approach in some experiments where expressiveness was more important than speed.