Skip to content

Instantly share code, notes, and snippets.

@aJamDonut
Last active August 10, 2021 02:40
Show Gist options
  • Save aJamDonut/65a8ffa34de93d3747176a1f94cf65cf to your computer and use it in GitHub Desktop.
Save aJamDonut/65a8ffa34de93d3747176a1f94cf65cf to your computer and use it in GitHub Desktop.
DDA Walk Javascript
ddaWalk(x, y, endX, endY) {
//DDA Algorithm https://lodev.org/cgtutor/raycasting.html
//https://www.youtube.com/watch?v=NbSee-XM7WA
//https://github.com/OneLoneCoder/olcPixelGameEngine
const Vector = Matter.Vector; //Replace with whatever Vector class you use
let mapSize = Vector.create(100, 100); //Grid size in cell size
let rayStart = Vector.create(x, y);
let rayEnd = Vector.create(endX, endY);
let rayDir = Vector.normalise(Vector.sub(rayEnd, rayStart))
// Lodev.org also explains this additional optimistaion (but it's beyond scope of video)
// olc::vf2d vRayUnitStepSize = { abs(1.0f / vRayDir.x), abs(1.0f / vRayDir.y) };
let rayUnitStepSize = Vector.create(
Math.sqrt(1 + (rayDir.y / rayDir.x) * (rayDir.y / rayDir.x)),
Math.sqrt(1 + (rayDir.x / rayDir.y) * (rayDir.x / rayDir.y))
);
let mapCheck = Vector.create(rayStart.x, rayStart.y);
let rayLength1D = Vector.create();
let step = Vector.create();
//Setup initial variables
if (rayDir.x < 0) {
step.x = -1;
rayLength1D.x = (rayStart.x - mapCheck.x) * rayUnitStepSize.x;
} else {
step.x = 1;
rayLength1D.x = (mapCheck.x + 1 - rayStart.x) * rayUnitStepSize.x;
}
if (rayDir.y < 0) {
step.y = -1;
rayLength1D.y = (rayStart.y - mapCheck.y) * rayUnitStepSize.y;
} else {
step.y = 1;
rayLength1D.y = (mapCheck.y + 1 - rayStart.y) * rayUnitStepSize.y;
}
//Start walking
let tileFound = false;
let maxDistance = 10; //Max distance to walk in 'cells'
let distance = 0;
let maxIterations = 100; //Just for safety, don't crash browsers!
let iterations = 0;
while (!tileFound && distance < maxDistance && iterations < maxIterations) {
iterations++;
if (rayLength1D.x < rayLength1D.y) { //Staying true to javids demo here but if u want X to be dominant change < to <=
mapCheck.x += step.x;
distance = rayLength1D.x;
rayLength1D.x += rayUnitStepSize.x;
} else {
mapCheck.y += step.y;
distance = rayLength1D.y;
rayLength1D.y += rayUnitStepSize.y;
}
//This is the meat, do your checks here, I just use it to reduce a rays length
if (mapCheck.x >= 0 && mapCheck.x < mapSize.x && mapCheck.y >= 0 && mapCheck.y < mapSize.y) {
if(this.isBlocked(mapCheck.x*64, mapCheck.y*64)) {
tileFound = true;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment