Единственный способ решить эту проблему - вычислить «направление движения». Например, вы можете сохранить координату предыдущего шага, и если на текущем шаге is_colliding вернет True, и mario на предыдущем шаге находился под монстром, а в предыдущемstep is_colliding вернул False, чем вы можете решить, что Марио упал сверху.
# x1,y1,h1,w1 - mario params
# x2,y2,h2,w2 - monster params
# y1_prev - mario previous param
# y2_prev - monster prevoius param
# collide_prev - previous sollision check
def check_above(x1, y1, w1, h1, x2, y2, w2, h2, y1_prev, y2_prev, collide_prev):
collide = is_colliding(x1, y1, w1, h1, x2, y2, w2, h2)
if collide and y2_prev + h2 < y1_prev and not collide_prev:
return True
else:
return False
Логика проста, если на текущем шаге Марио сталкивается, а на предыдущем не было столкновения, и Марио находился над монстром, то это означает, что Марио сталкивается сверху.
NOTE Код будет работать, если координата x находится в левом нижнем углу прямоугольника