Okay, so this is a problem I've been trying to figure out for quite some time. Mine is a 2D platformer game with a world made up of (usually) immobile tiles and mobile sprites, both of which use AABBs to represent their hitboxes. This game is NOT grid-based due to some complications with moving layers of tiles.

I can detect collisions and easily figure out the depth of the collision. I use the "shallowest axis method" to determine which way to resolve a collision between the sprite and the tile. If the sprite is deeper horizontally than vertically, the direction to resolve is either up or down. If the sprite is deeper vertically than horizontally, the direction to resolve is either left or right.



This is simple enough, and it works pretty well. That is, until you have a sprite colliding with more than one tile. As, by their nature, each collision has to be checked separately, different collisions may have different direction to resolve in. For example, if a sprite is trying to walk across a row of tiles, for one frame they will intersect the next tile such that the horizontal depth is shorter than the vertical depth. As the collision says "resolve left", it will be pushed back and will be stuck on the corner.



I've been mulling this problem over, on and off, for quite some time, and several solutions have come to me, but all have flaws. I could mark certain sides as unreachable, but without a grid-based engine, determining "unreachability" is remarkably complex, especially with moving layers of tiles always a possibility.

Another possible method would be to predict collisions before they happen and "work back" the movement to the point of the collision, I suppose, but I'm not sure how the math on that works.

I feel that I'm missing something incredibly obvious, especially since games from the 80s have already solved this problem.


Question: Javascript looping behaviour
Answer: There isn't an existing Array method to do what you want, but one is easily defined using Array.prototype.slice and Array.prototype.concat:

// move i elements from the start of the array to the end of the array
Array.prototype.lcycle = function(i) {
  var xs = this.slice(0,i);
  var ys = this.slice(i);
  return ys.concat(xs)
};
// move i elements from the end of the array to the start of the array
Array.prototype.rcycle = function(i) {
  var xs = this.slice(0,-i);
  var ys = this.slice(-i);
  return ys.concat(xs);
};


And then you can use lcycle and rcycle  as normal array methods:

&gt;&gt;&gt; alltones.lcycle(3)
[ "D#" , "E" , "F" , "F#" , "G" , "G#" , "A" , "A#" , "B" , "C" , "C#" , "D" ]
&gt;&gt;&gt; alltones.rcycle(4)
[ "G#" , "A" , "A#" , "B" , "C" , "C#" , "D" , "D#" , "E" , "F" , "F#" , "G" ]


Note that both of these methods return a new array.  If you wanted to mutate the original array, you could define similar methods using Array.prototype.splice.

// move i elements from the start of the array to the end of the array, mutating the original array
Array.prototype.lcycle_m = function(i) {
  var args = this.splice(0,i);
  args.unshift(0);
  args.unshift(this.length);
  this.splice.apply(this, args);
};
// move i elements from the end of the array to the start of the array, mutating the original array
Array.prototype.rcycle_m = function(i) {
  var args = this.splice(-i);
  args.unshift(0);
  args.unshift(0);
  this.splice.apply(this, args);
};


And again, you can can use lcycle_m and rcycle_m as normal array methods:

&gt;&gt;&gt; alltones.lcycle_m(3)
&gt;&gt;&gt; alltones
[ "D#" , "E" , "F" , "F#" , "G" , "G#" , "A" , "A#" , "B" , "C" , "C#" , "D" ]
&gt;&gt;&gt; alltones.rcycle_m(3)
&gt;&gt;&gt; alltones
[ "C" , "C#" , "D" , "D#" , "E" , "F" , "F#" , "G" , "G#" , "A" , "A#" , "B" ]