I’m trying to make a 2d game with multiple maps. I am trying to make 8×8 map with squares of same size.
Here is the code for the function I have problem with. I expect that the map will be the same as the array I wrote. When I try it looks similar but it is completely off.
function loadMap(ctx, map) {
var w = innerWidth / 8
var x = 0
var y = 0
for (var i = 0; i < map.length; i++) {
if (map[i] == 1) {
rect(x, y, w, w, ctx, 'orange')
x += w
} else {
x += w
}
if (Number.isInteger(i / 8)) {
y += w
x = 0
}
}
}
function rect(x, y, w, h, ctx, color = 'white') {
ctx.beginPath()
ctx.fillStyle = color
ctx.fillRect(x, y, w, h)
}
const map1 = [
1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 1, 0, 0, 0, 0, 1,
1, 0, 1, 1, 0, 0, 0, 1,
1, 0, 0, 0, 0, 1, 1, 1,
1, 0, 0, 1, 1, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 1
]
loadMap(document.querySelector('#cnv').getContext('2d'), map1);
<canvas id="cnv"></canvas>
Here is the rect function:
2
Answers
There are two issues in your logic, both to do with how to increment
y
andx
.Firstly,
0 / 8
returns an integer, so the first iteration of the loop causes a new line to be rendered. You can also use the modulo operator for this instead of checking that the result is an integer.Secondly, you need to perform the new line check before you render a line’s first square.
Also note that there’s no need for the
else
condition asx += w
happens in both logic flows.Note that you could keep the
if
condition to start the new line after therect()
call, but you would have to change the logic to something like this, which is not very intuitive:Every 8 iterations we enter a new row. Before drawing a row’s first element, you should move the draw position (i.e.
x
andy
) accordingly.With the
if (Number.isInteger(i / 8)) ...
statement (which sets the draw position to the start of the next row) after drawing a row’s first element, the following elements will be misplaced.You can fix this by either:
Number.isInteger((i + 1) / 8)
, or in words: "Wheni
is one element before the next row"), ori == 0
), so as to not be one row off when drawing.Alternatively to keeping track of
x
andy
across iterations, we can also calculate them for the given value ofi
:Note: Here I use the remainder operator
%
(also called modulo operator) which returns the remainder of the implied division. You can also use the remainder operator in the if-statement, as in Rory McCrossan’s answer.