I made a simple Snake game designed for trying Snake bots. I thought the base map functions work, but now I found there is an error. What I need is to properly translate any coordinates outside the actual map to coordinates within it.
For example, if you're at the right edge of a 10x10 map and you go to (zero-indexed) [10, 5], you'd expect to pop out at [0, 5]. That works in my implementation, but not the negative overflow. I tried a lot of formulas in the dev console and just can't figure it out. Consider this code:
/**
* Normalizes overflow of a point so that it is within the map
* @param {number|Vector2} x
* @param {number} y
* @returns {Vector2}
*/
normalizePoint(x, y) {
if (x instanceof Vector2) {
y = x.y;
x = x.x;
}
// auto overflow
if (x >= this.size) {
x = (x % this.size);
}
else if (x < 0) {
// ???
}
if (y >= this.size) {
y = (y % this.size);
}
else if (y < 0) {
// one of the formulae I tried, does not work for all values
y = this.size + (y-1) % this.size;
}
return new Vector2(x, y);
}
Vector2
is a simple object with properties x
and y
. this.size
represents the map size. For negative coordinates, I am not getting the correct results. I want overflowing X and Y coords to resolve to the same numbers. For example for a 5x5 map, all rows should be equal X coords after normalizing:
Real map coord X: | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
Negative alternatives: | -5 | -4 | -3 | -2 | -1 |
Negative alternatives: | -10 | -9 | -8 | -7 | -6 |
I would prefer it to be a O(1) formula, rather than some weird loop. With a loop, I solved it like this:
if (x < 0) {
while (x < 0) {
x += this.size;
}
}
```