Nathaniel3W":27vic9hb said:
That's interesting Xilef. I've never had to work on anything that low-level in a game engine before. What's the default collision shape for MV? What technique do you use for not testing collision of everything against everything? Do you test only when an actor moves, and only against things in its own quadtree node?
Collision detection considered low level? Jesus Christ...
MV is tile-based collision with a 1x1 tile size. The MV logic is basically [point in a direction] -> [move straight] and that move straight will check if the next tile is passable or not. If it is, then the target X&Y for the character is moved 1 step over and the separate animation system takes over for smoothly transitioning the character. This is why when events walk towards each other, one will stop and leave the tile in-front free so the other one can step into it and avoid a collision during the animation.
What I've done here is made that 1-tile step into a 1-animation-frame-distance step. So when you move forward, it will move you 1 frame of that smooth animation I mentioned before.
After that, I changed the logic so rather than "check if next tile is passable or not" it checks the collision engine using the movement direction as a physics vector, that vector is corrected if a collision has occurred (so moving into the side of a shape will push your shape away from it so it is neatly touching) - it also slides along the shape if possible because it uses the normal direction as the "correction" direction, this lets shapes smoothly pass each other and in some cases slot neatly into a gap that they can fit inside (handy for a player trying to enter a tight doorway).
The collision algorithm is separating axis theorem, which works by projecting the 2D shapes onto a number of 1D planes and checking if their projection has a gap between them; if yes, no collision, if no, then the distance between the two projections is how far along the plane the shape needs to move to correct the collision. The 1D planes used for the projections are the normal-vectors to each of the lines on the polygon (in the circle's case, which is 100% normals, it's specifically the shortest distance from the circle to one of the polygon vertices). It's the ideal way to do polygon collisions and is fast enough for 2D shapes.
The easy part is getting this working for player characters. For events, there's a lot that can go wrong and there's also the question of "how should move-routes behave?". I think everything should be as compatible with default MV as much as possible, but if a move-route fails with the player sitting half-way across a tile, should the event be corrected against the player or should they wait until the tile is free?
This time round, I haven't optimised much at all. I'll be optimising last. There's no quadtree and every single event is looped. The collision is quickly discarded by an axis-aligned bounding box check, that's the only optimisation used.