So we would handle collision and movement separately?
Yes... That's what I'm saying all the time.
The movement depends on the velocity, and the velocity can be affected by collision response. Thus, the collision response indirectly influences the movement.
Something like this?
** Start **
Entities (all entities are non passable):
1, 2, 3,
4, 5, 6,
7, 8, 9
** Move everything **
Blue entities move towards green entity and green entity moves to the down right
** Check collisions **
List of collisions (let's handle collisions in this order:
1: E2 collision with E3 (X collision)
2: E4 collision with E7 (Y collision)
3: E5 collision with E6 (X collision)
4: E5 collision with E8 (Y collision)
5: E6 collision with E8 (X and Y collision)
** Handle collisions **
1: reset E2 and E3 X movement to prevent collision
-> E2 collides now with E1 (X collision)
2: reset E4 and E7 Y movement to prevent collision
-> E4 collides now with E1 (Y collision)
3: reset E5 and E6 X movement to prevent collision
-> E5 collides now with E4 (X collision)
-> E5 collides now with E7 (Y collision)
-> E5 collides now with E8 (X and Y collision)
4: reset E5 and E8 Y movement to prevent collision
-> E5 collides now with E1 (X and Y collision)
-> E5 collides now with E2 (Y collision)
-> E5 collides now with E4 (X collision)
5: reset E6 and E8 X or Y collision to prevent collision (I've yet to figure out which one) (let's select X collision this time)
-> E8 collides with E7 (X collision)
** Check collisions **
1: E1 collision with E2 (X)
2: E1 collision with E4 (Y)
3: E1 collision with E5 (X and Y)
4: E2 collision with E4 (X and Y)
5: E2 collision with E5 (Y)
6: E4 collision with E5 (X)
7: E7 collision with E8 (X)
** Handle collisions **
1: reset E1 X movement (E2 movement already resetted)
2: reset E1 Y movement (E4 movement already resetted)
3: Do nothing (E1 and E5 movement already resetted)
4: reset E2 Y movement
5: Do nothing
6: reset E4 X movement
7: reset E7 X movement
** Check collisions **
No more collision
-> Continue
Problems I have with above aproach:1. hard to detect should I reset X or Y movement
Scenario 1Entities:
B1
B2, G
Blue entities move towards green entity, while green entity moves top left
**Collisions**
1: B1 collides with B2 (Y)
2: B1 collides with G (X and Y)
3: B2 collides with G (X)
-> Reset blue movement
-> Reset green X movement (nothing blocks Y)
Scenario 2Entities:
B1, B2
G
Blue entities move towards green entity, while green entity moves top left
**Collisions**
1: B1 collides with B2 (X)
2: B1 collides with G (X and Y)
3: B2 collides with G (Y)
-> Reset blue movement
-> Reset green Y movement (nothing blocks X)
Collisions don't know about each others and in these scenarios 2. collision is fixed by handling 3. collision.
How should I handle XY-collision?
Another reason why it's a bad idea to handle collision during Entity::current() is the asymmetry created by the order of iteration: Entities that are moved before others (but in the same frame) get priority for collision. When an entity checks other entities for collision, a part of them has already moved, while another one hasn't.
But there's still assymmetry depending on which order collisions are handled. (It doesn't really matter in this case though)
The third reason is modularity and separation of responsibilities. It's favorable if Entity needn't be aware of the whole world. As suggested, I would even create a separate class for collision detection and response, because World is already quite big.
This is main reason why I would like to move collision handling away from entity update step. It just makes movement a bit trickier.