# Collision detection and solution causes teleportation on corners

I am making my own game engine on Python and I got stuck with collision between objects.

# If we go Right
if (collision_rect.right >= object_collision_rect.left) and \
(collision_rect.left <= object_collision_rect.left):
if (collision_rect.bottom > object_collision_rect.top) and \
(collision_rect.top < object_collision_rect.bottom):
if self.acceleration.x > 0:
self.acceleration.x = 0
moving.x = object_collision_rect.left - collision_rect.right

# Bottom
if (collision_rect.bottom >= object_collision_rect.top) and \
(collision_rect.top <= object_collision_rect.top):
if (collision_rect.right > object_collision_rect.left) and \
(collision_rect.left < object_collision_rect.right):
if self.acceleration.y > 0:
self.acceleration.y = 0
moving.y = object_collision_rect.top - collision_rect.bottom


There are two more for left and top.

It makes teleporting on corners. And if we change the second conditions from < > to <= >=, we get teleporting on edges, if we have acceleration x and y both != 0

• Hmm, first of all I would compartimentalize this far more (if just for readability) Make one method for collision detection Then one to find out the direction of the collision And you call both those in the method that handles movement. That way you decouple the detection from the actual movement and are more likely to find the source of the teleportation Aug 14, 2019 at 13:57

I found solution. First of all I made collision detection function for readability, then I made collision for each axis apart.

self.collision(objects_around, Vector2D(self.acceleration.x, 0))
self.collision(objects_around, Vector2D(0, self.acceleration.y))

def collision(self, objects, acceleration):
if not self.collision:
return

self.position += acceleration
collision_rect = self.get_collision_rect()

for object in objects:
if not object.isCollision or self.id_ == object.id_:
continue
object_collision_rect = object.get_collision_rect()
if not collision_rect.intersects(object_collision_rect):
continue

if acceleration.x > 0:
self.position.x += object_collision_rect.left - collision_rect.right
elif acceleration.x < 0:
self.position.x += object_collision_rect.right - collision_rect.left

if acceleration.y > 0:
self.position.y += object_collision_rect.top - collision_rect.bottom
elif acceleration.y < 0:
self.position.y += object_collision_rect.bottom - collision_rect.top