Reputation: 1
I'm making a game and I bumped into a strange problem. So, I've found a JS code for drawing a line via Bresenham's algorithm, without plot() function (maybe I write it wrong) and all this stuff works weird:
What am I doing wrong?
let ctx = canvas.getContext("2d");
const TILE = 30;
let map = [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
];
ctx.fillStyle = "rgba(0,50,200)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
for (let i = 0; i < 10; i++) {
for (let j = 0; j < 10; j++) {
if (map[i][j] === 1) {
ctx.fillStyle = "black";
ctx.fillRect(j * TILE, i * TILE, TILE - 1, TILE - 1)
}
if (map[i][j] === 0) {
ctx.fillStyle = "gray";
ctx.fillRect(j * TILE, i * TILE, TILE - 1, TILE - 1)
}
}
}
let plot = (x, y) => {
ctx.fillRect(x * TILE, y * TILE, TILE, TILE);
return true;
}
let castRay = (x0, y0, x1, y1) => {
let tmp;
let steep = Math.abs(y1 - y0) > Math.abs(x1 - x0);
if (steep) {
tmp = x0;
x0 = y0;
y0 = tmp;
tmp = x1;
x1 = y1;
y1 = tmp;
}
let sign = 1;
if (x0 > x1) {
sign = -1;
x0 *= -1;
x1 *= -1;
}
let dx = x1 - x0;
let dy = Math.abs(y1 - y0);
let err = ((dx / 2));
let ystep = y0 < y1 ? 1 : -1;
let y = y0;
for (let x = 0; x <= x1; x++) {
if (!(steep ? plot(y, sign * x) : plot(sign * x, y))) return;
err = (err - dy);
if (err < 0) {
y += ystep;
err += dx;
}
}
}
ctx.fillStyle = "green";
castRay(0, 0, 4, 4);
ctx.fillStyle = "rgb(0,0,255)";
castRay(8, 0, 4, 4)
<canvas width="300" height="300" id="canvas"></canvas>
Upvotes: 0
Views: 572
Reputation: 12891
I would get rid of the sign variable and instead just swap the appropriate variables inside the if (x0 > x1)
condition. Furthermore your line drawing always starts at x=0 because you didn't set it to x0.
for (let x = 0; x <= x1; x++)
should be
for (let x = x0; x <= x1; x++)
Here's the updated example code:
let ctx = canvas.getContext("2d");
const TILE = 30;
let map = [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
];
ctx.fillStyle = "rgba(0,50,200)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
for (let i = 0; i < 10; i++) {
for (let j = 0; j < 10; j++) {
if (map[i][j] === 1) {
ctx.fillStyle = "black";
ctx.fillRect(j * TILE, i * TILE, TILE - 1, TILE - 1)
}
if (map[i][j] === 0) {
ctx.fillStyle = "gray";
ctx.fillRect(j * TILE, i * TILE, TILE - 1, TILE - 1)
}
}
}
let plot = (x, y) => {
ctx.fillRect(x * TILE, y * TILE, TILE, TILE);
return true;
}
let castRay = (x0, y0, x1, y1) => {
let tmp = x0;
let steep = Math.abs(y1 - y0) > Math.abs(x1 - x0);
if (steep) {
x0 = y0;
y0 = tmp;
tmp = x1;
x1 = y1;
y1 = tmp;
}
if (x0 > x1) {
x0 = x1;
x1 = tmp;
tmp = y0;
y0 = y1;
y1 = tmp;
}
let dx = x1 - x0;
let dy = Math.abs(y1 - y0);
let err = ((dx / 2));
let ystep = y0 < y1 ? 1 : -1;
let y = y0;
for (let x = x0; x <= x1; x++) {
if (!(steep ? plot(y, x) : plot(x, y))) return;
err = (err - dy);
if (err < 0) {
y += ystep;
err += dx;
}
}
}
ctx.fillStyle = "green";
castRay(0, 0, 4, 4);
ctx.fillStyle = "rgb(0,0,255)";
castRay(8, 0, 4, 4)
<canvas width="300" height="300" id="canvas">
Upvotes: 1