ruffle-rs / ruffle

A Flash Player emulator written in Rust
https://ruffle.rs
Other
15.63k stars 809 forks source link

Shape hit testing checks the last 2 frames #3244

Open relrelb opened 3 years ago

relrelb commented 3 years ago

In Flash Player, it seems that hitTest with shapeFlag set to true returns true only when a hit occurs in both the current frame and the previous frame. However Ruffle accounts only for the current frame.

The attached test.zip traces in Flash Player false twice, then true repeatedly. In Ruffle it traces false just once, then true repeatedly. Also, test2.zip never traces true in Flash Player, but does once in Ruffle.

Without shapeFlag Flash Player behaves like Ruffle.

Herschel commented 3 years ago

This is reusing the previous frame's rendering in some way, as this only occurs when the object is in the visible area of the stage. If you do _root._x = 2000; to toss everything offscreen, the hitTest returns true on the first frame it collides instead of the one-frame-lag behavior, probably because the player has to redraw the object on demand. Also happens with _visible = false.

The question is what the exact behavior is; I suspect it will require some reverse engineering work to figure it out. Could be something like:

adrian17 commented 8 months ago

It might also be that there's some cached value at play, that doesn't update in the way one might except.

var rect:Shape = new Shape();
// make a 100x100 square...
rect.x = 100;
trace(rect.hitTestPoint(150, 150, true));
rect.x = 200;
trace(rect.hitTestPoint(250, 150, true));

prints true false, but if the first hitTest is commented out, then the second becomes true!