interesting, can you analyze and improve/fix this? just output full fixed then.: const canvas=document.getElementById("game-canvas");const context=canvas.getContext("2d");const GRAVITY=80;const ENEMY_RADIUS=25;const PLAYER_RADIUS=25;const TRACTION=.95;let playerX=50;let playerY=550;let enemyX=750;let enemyY=150;let enemySpeedX=0;let enemySpeedY=0;let playerSpeedX=0;let playerSpeedY=0;let playerIsOnGround=false;let paths=[];const nodes=[];class Node{constructor(x,y){this.x=x;this.y=y;this.neighbors=[]}distanceTo(otherNode){return Math.sqrt((otherNode.x-this.x)**2+(otherNode.y-this.y)**2)}}class Path{constructor(startNode,endNode,nodes){this.startNode=startNode;this.endNode=endNode;this.nodes=nodes;this.cost=nodes.reduce((acc,node,i)=>{if(i>0){acc+=node.distanceTo(nodes[i-1])}return acc},0)}}generatePaths();canvas.addEventListener("click",event=>{const rect=canvas.getBoundingClientRect();const x=event.clientX-rect.left;const y=event.clientY-rect.top;const startNode=findClosestNode(x,y);const endNode=findClosestNode(playerX+PLAYER_RADIUS,playerY+PLAYER_RADIUS);if(startNode&&endNode){const path=findPath(startNode,endNode);if(path){enemyX=startNode.x;enemyY=startNode.y;paths.push(new Path(startNode,endNode,path))}}});document.addEventListener("keydown",event=>{if(event.code==="KeyA"){playerSpeedX=-5}if(event.code==="KeyD"){playerSpeedX=5}if(event.code==="KeyW"&&playerIsOnGround){playerSpeedY=-20;playerIsOnGround=false}});document.addEventListener("keyup",event=>{if(event.code==="KeyA"||event.code==="KeyD"){playerSpeedX*=TRACTION}});function checkCollision(){let isOnGround=false;if(playerY+PLAYER_RADIUS>=canvas.height){playerSpeedY=0;playerY=canvas.height-PLAYER_RADIUS;playerIsOnGround=true;isOnGround=true}if(playerX+50>=enemyX-ENEMY_RADIUS&&playerX<=enemyX+ENEMY_RADIUS&&playerY<=enemyY+ENEMY_RADIUS&&playerY+50>=enemyY-ENEMY_RADIUS){playerSpeedY=0;playerY=enemyY-ENEMY_RADIUS-50;playerIsOnGround=true;isOnGround=true}if(playerY<=0){playerSpeedY=0;playerY=0}if(!isOnGround){playerIsOnGround=false}}function applyGravity(){if(!playerIsOnGround){playerSpeedY+=GRAVITY/60}}function applyTraction(){playerSpeedX*=TRACTION}function movePlayer(){playerX+=playerSpeedX;playerY+=playerSpeedY;if(playerX<0)playerX=0;if(playerX+50>canvas.width)playerX=canvas.width-50;context.fillStyle="red";context.fillRect(playerX,playerY,50,50)}function moveEnemy(){let path;if(paths.length>0){const path=paths[0];const startNode=path.startNode;const endNode=path.endNode;const shortestPath=findPath(startNode,endNode);console.log("startNode:",startNode);console.log("endNode:",endNode);console.log("shortestPath:",shortestPath)}for(let i=0;i<paths.length;i++){const{nodes,startNode,endNode,cost}=paths[i];if(startNode.x===enemyX&&startNode.y===enemyY){path={nodes:nodes,cost:cost};break}}if(path){const followNode=path.nodes.shift();const theta=Math.atan2(followNode.y-enemyY,followNode.x-enemyX);enemySpeedX=Math.cos(theta)*5;enemySpeedY=Math.sin(theta)*5;enemyX+=enemySpeedX;enemyY+=enemySpeedY;console.log(enemyX,enemyY);if(enemyX-ENEMY_RADIUS<0||enemyX+ENEMY_RADIUS>canvas.width||enemyY-ENEMY_RADIUS<0||enemyY+ENEMY_RADIUS>canvas.height){paths=paths.filter(p=>p.startNode.x!==enemyX||p.startNode.y!==enemyY);return}context.fillStyle="blue";context.fillRect(enemyX-ENEMY_RADIUS,enemyY-ENEMY_RADIUS,ENEMY_RADIUS*2,ENEMY_RADIUS*2);if(path.nodes.length===0){paths=paths.filter(p=>p.startNode.x!==enemyX||p.startNode.y!==enemyY)}}else{paths=paths.filter(p=>p.startNode.x!==enemyX||p.startNode.y!==enemyY)}}function generatePaths(){const nodes=[];for(let i=0;i<canvas.width;i+=50){for(let j=0;j<canvas.height;j+=50){const node=new Node(i+25,j+25);nodes.push(node)}}nodes.forEach((node,index)=>{const neighbors=nodes.filter((otherNode,otherIndex)=>{if(otherIndex===index)return false;return node.distanceTo(otherNode)<75});node.neighbors=neighbors})}canvas.addEventListener("click",event=>{const rect=canvas.getBoundingClientRect();const x=event.clientX-rect.left;const y=event.clientY-rect.top;const closestNode=findClosestNode(x,y);console.log("x:",x,"y:",y);console.log("closestNode:",closestNode);if(closestNode){const path=findPath(playerNode,closestNode);paths.push(path)}});function findClosestNode(x,y){let closestNode=null;let closestDistance=Infinity;nodes.forEach(node=>{const distance=node.distanceTo({x:x,y:y});if(distance<closestDistance){closestNode=node;closestDistance=distance}});if(closestDistance<50){return closestNode}return null}function findPath(startNode,endNode){const queue=[];const visited=new Set;queue.push({node:startNode,path:[startNode]});while(queue.length>0){const{node,path}=queue.shift();if(visited.has(node)){continue}visited.add(node);if(node===endNode){return path}node.neighbors.forEach(neighbor=>{queue.push({node:neighbor,path:[...path,neighbor]})})}return null}function draw(){context.clearRect(0,0,canvas.width,canvas.height);context.fillStyle="gray";context.fillRect(0,0,canvas.width,canvas.height);applyGravity();applyTraction();movePlayer();moveEnemy();checkCollision();requestAnimationFrame(draw)}function reset(){playerX=50;playerY=550;enemyX=750;enemyY=150;enemySpeedX=0;enemySpeedY=0;playerSpeedX=0;playerSpeedY=0;playerIsOnGround=true;context.strokeStyle="black";context.lineWidth=2;context.strokeRect(0,0,canvas.width,canvas.height);context.clearRect(0,0,canvas.width,canvas.height);context.fillStyle="gray";context.fillRect(0,0,canvas.width,canvas.height);paths=[];generatePaths();draw()}window.addEventListener("load",()=>{reset()});