Open thomai-d opened 3 years ago
Explanation After debugging arcade code, I found out, that to improve performance, a quick collision check is made before the 'real' collision detection algorithm is run.
This quick check relies on the sprites width/height properties, which in my case are zero for the invisible sprite. Therefore, the collision only works within the monkey height's radius.
Solution To make it work, I have to set the invisible sprite's width/height manually to the hitbox's bounding box width/height.
Suggestion
Not sure if using a sprite for collision detection is considered 'hacky', but if this is the officially supported method, I would have expected that by using set_hit_box()
the sprite's collision radius should be calculated based on the hitbox points and not the sprite's width / height.
Agreed, I think we need to hook into set_hit_box
so it also will reset height/width. Thanks for the very detailed report.
Doing invisible collision with sprite like that is kind of hacky yes, but it's not too unreasonable.
Some random thoughts: 1) It's probably not reasonable that a sprite doesn't have a texture (adds complexity). It can have a dummy texture for sure, and those are easy to make. 2) If the dummy texture needs to be scaled it will also scale the hit box points. That can be a hit weird. 3) Possibly a sprite type could be added for this kind of use.
This is still a issue with current development, the width/height of the image is used, and if the hitbox extends past that, it is going to be ignored.
I looked at his brifely. When it comes to performance it's alll about the cost of calling left, right, top and bottom. These might need to be cached in the sprite to make it viable, but no idea if this reasonable.
Is it even reasonable that points extend past the texture area?
Is it even reasonable that points extend past the texture area?
Things like the anomalies from the STALKER series might do something like this to save on texture space: small sprite, large hitbox to set it off.
We now have arcade.get_sprites_in_rect((l, r, b, t), spritelist)
that can used instead of dummy sprite. Still, this doesn't solve the core issue.
This quick check relies on the sprites width/height properties, which in my case are zero for the invisible sprite. Therefore, the collision only works within the monkey height's radius.
This quick check also makes the collision detection to fail if the hitbox is set to something bigger than the sprite itself.
See https://discord.com/channels/458662222697070613/696054878593744946/1038023494946017320
So we have had a big hitbox re-work very recently, and this problem still exists, however we've had a lot of performance improvements, and are able to achieve greater than 20x speedups to the are_polygons_intersecting
check that this bounding box check tries to ignore via the upcoming arcade-accelerate
package. Given all of this, I'm tempted to say that we can just remove the check altogether, and always use the full are_polygons_intersecting
check which will stay true to the hitbox.
Using the new super stripped back Sprite, could we not provide a BlankSprite
class to solve this issue? Give it a 2x2 invisible texture that can't be changed, just the hitbox and sprite size.
EDIT: might not be the same issue, refiled here https://github.com/pythonarcade/arcade/issues/2255
TL;DR: It's still happening, and it isn't just big sprites
One of our users appears to have run into this on Discord today. Their sprite tiles appear to be 48x48 and the hitbox appears to be clean. See the video below (Converted with ffmepg -i file.avi file.mp4
):
https://github.com/pythonarcade/arcade/assets/36696816/d0b054f7-e0f2-41db-a8fe-0aaa704ad62b
Big hitbox areas are very inaccurate.
Tested with version: arcade==2.5.5 Shapely==1.7.1
Small repro-code (you can switch hitboxes in player.py): repro-code.zip
Related: #753