Hi macromint, welcome.
I think this can be done from the information that you have in that context, mainly the positions of both rectangles on the current frame when a collision happened and on the frame before that.
In these images the player is the red box and the enemy is the white box, and imagine that these represent the previous frame before a collision:
- temp.png (2.06 KiB) Viewed 3120 times
- temp02.png (2.06 KiB) Viewed 3120 times
When a collision happens on the next frame, since the player rectangle was
clearly above the enemy rectangle, even if both rectangles are moving, then you know that the player came from above.
By "clearly" I mean, no part of the player was below the highest point of the enemy, so the bottom of the player was completely above the blue line in that image.
You'd do the same to find horizontal collisions: if a collision happens, and on the previous frame the player was clearly to the left of the enemy (no part of the player was to the right of the enemy's leftmost part, that orange-ish line), then the player is coming from the left and bumped their right side on the enemy.
You'd do this for the right and bottom directions as well, so you can know this for all 4 sides of the rectangle.
The problem is what
priority to give to each direction when a collision happens: in that image, the player is both clearly above the enemy and also clearly to the left of the enemy, so if a collision happens on the next frame, is it a horizontal or vertical collision? I think you should give priority to the vertical collision so it's easier for players to jump on enemies than it is for them to die. But maybe have some tolerance, like if the player traveled less horizontally than vertically, then up to a certain distance you consider it a vertical collision and so a success for the player, rather than a failure of them touching an enemy.