Last active
August 10, 2021 02:40
-
-
Save aJamDonut/65a8ffa34de93d3747176a1f94cf65cf to your computer and use it in GitHub Desktop.
DDA Walk Javascript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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