because what I see right now in my code, is that the actual gravitational constant aren't stabilized normally and can't hande properre collision performance with obstacles-platforms.: const canvas=document.getElementById("game-canvas");const context=canvas.getContext("2d");canvas.width=300;canvas.height=300;const GRAVITY=8;const ENEMY_RADIUS=10;const PLAYER_RADIUS=10;const TRACTION=.9999;const maxFallSpeed=1;const OBSTACLE_COUNT=10;const OBSTACLE_GAP=0;let playerX=50;let playerY=250;let isPlayerAlive=true;let enemyX=400;let enemyY=500;let enemySpeedX=0;let enemySpeedY=0;let enemyMultiplier=0;let playerSpeedX=0;let playerSpeedY=0;let playerIsOnGround=false;let lasers=[];let shootingTimer=0;let obstacles=[];const obstacleWidth=100;const obstacleHeight=20;let offsetX=0;let offsetY=0;let scrollSpeed=1;function applyGravity(){if(!playerIsOnGround){playerSpeedY+=GRAVITY/60;if(playerSpeedY>maxFallSpeed){playerSpeedY=maxFallSpeed}}}function applyTraction(){if(playerIsOnGround){playerSpeedX*=TRACTION}}function setPlayerStartPosition(){playerX=10;playerY=10}function respawnPlayer(){playerX=10;playerY=10;playerSpeedX=0;playerSpeedY=0;isPlayerAlive=true}function movePlayer(){if(!isPlayerAlive)return;playerX+=playerSpeedX;playerY+=playerSpeedY;if(playerX<0){playerX=0}if(playerX+PLAYER_RADIUS*2>canvas.width){playerX=canvas.width-PLAYER_RADIUS*2}if(playerY+PLAYER_RADIUS*2>canvas.height){respawnPlayer()}context.fillStyle="pink";context.fillRect(playerX-offsetX,playerY-offsetY,PLAYER_RADIUS*2,PLAYER_RADIUS*2)}function moveEnemy(){if(!isPlayerAlive)return;const targetIndex=findNearestObstacle(playerX,playerY);const targetX=obstacles[targetIndex].x+obstacleWidth/2;const targetY=obstacles[targetIndex].y+obstacleHeight/2;const epsilon=25;if(Math.abs(enemyX-targetX)>epsilon||Math.abs(enemyY-targetY)>epsilon){const angle=Math.atan2(targetY-enemyY,targetX-enemyX);enemySpeedX=Math.cos(angle)*2;enemySpeedY=Math.sin(angle)*2}else{enemySpeedX=0;enemySpeedY=0}enemyX+=enemySpeedX;enemyY+=enemySpeedY;context.fillStyle="cyan";context.fillRect(enemyX-ENEMY_RADIUS-offsetX,enemyY-ENEMY_RADIUS,ENEMY_RADIUS*2,ENEMY_RADIUS*2)}function findNearestObstacle(x,y){let minIndex=0;let minDistance=Number.MAX_VALUE;for(let i=0;i<obstacles.length;i++){const dx=x-(obstacles[i].x+obstacleWidth/2);const dy=y-(obstacles[i].y+obstacleHeight/2);const distance=Math.sqrt(dx*dx+dy*dy);if(distance<minDistance){minDistance=distance;minIndex=i}}return minIndex}function handlePlayerCollision(obstacle,axis){if(axis==="horizontal"){if(playerSpeedX>0){playerX=obstacle.x-PLAYER_RADIUS*2-1}else{playerX=obstacle.x+obstacle.width+1}playerSpeedX=0}else{if(playerSpeedY>0){playerY=obstacle.y-PLAYER_RADIUS*2-1;playerSpeedY=0;playerIsOnGround=true}else{playerY=obstacle.y+obstacle.height+1;playerSpeedY=0}}}function isColliding(x,y,width,height){for(const obstacle of obstacles){if(obstacle&&x<obstacle.x+obstacle.width&&x+width>obstacle.x&&y<obstacle.y+obstacle.height&&y+height>obstacle.y){return obstacle}}return null}function checkCollision(){detectObstacleCollision()}function detectObstacleCollision(){const obstacleHorizontal=isColliding(playerX+playerSpeedX,playerY,PLAYER_RADIUS*2,PLAYER_RADIUS*2);const obstacleVertical=isColliding(playerX,playerY+playerSpeedY,PLAYER_RADIUS*2,PLAYER_RADIUS*2);if(obstacleHorizontal){handlePlayerCollision(obstacleHorizontal,"horizontal")}if(obstacleVertical){handlePlayerCollision(obstacleVertical,"vertical")}else{playerIsOnGround=false}}function jump(){if(playerIsOnGround){playerSpeedY=-20;playerIsOnGround=false}}function shootLaser(){const laserSpeed=2;const angle=Math.atan2(playerX-enemyX);const laserSpeedX=Math.cos(angle)*laserSpeed;const laserSpeedY=Math.sin(angle)*laserSpeed;lasers.push({x:enemyX+ENEMY_RADIUS,y:enemyY+ENEMY_RADIUS,speedX:laserSpeedX,speedY:laserSpeedY})}function moveLasers(){let playerHit=false;for(let i=0;i<lasers.length;i++){const laser=lasers[i];laser.x+=laser.speedX;laser.y+=laser.speedY;if(!playerHit&&laser.x>=playerX&&laser.x<=playerX+PLAYER_RADIUS*2&&laser.y>=playerY&&laser.y<=playerY+PLAYER_RADIUS*2){const randomColor="rgb("+Math.floor(Math.random()*256)+","+Math.floor(Math.random()*256)+","+Math.floor(Math.random()*256)+")";context.strokeStyle=randomColor;context.beginPath();context.moveTo(laser.x,laser.y);context.lineTo(laser.x+laser.speedX,laser.y+laser.speedY);context.lineWidth=3;context.stroke();playerHit=true;isPlayerAlive=false}if(isOutOfBounds(laser.x,laser.y,0,0)){lasers.splice(i,1);i}}if(playerHit){playerX=-100;playerY=-100}}function drawLasers(){context.fillStyle="red";for(const laser of lasers){context.beginPath();context.arc(laser.x,laser.y,5,0,Math.PI*2);context.fill()}}function drawObstacles(){context.fillStyle="yellow";for(const obstacle of obstacles){context.fillRect(obstacle.x,obstacle.y,obstacle.width,obstacle.height)}if(obstacles.length&&isOutOfBounds(obstacles[0].x,obstacles[0].y,obstacleWidth,obstacleHeight)){generateNewObstacle("up")}if(obstacles.length&&isOutOfBounds(obstacles[obstacles.length-1].x,obstacles[obstacles.length-1].y,obstacleWidth,obstacleHeight)){generateNewObstacle("down")}}function createObstacles(){for(let i=0;i<OBSTACLE_COUNT;i++){const obstacleX=Math.random()*(canvas.width-obstacleWidth);const obstacleY=i*(canvas.height/OBSTACLE_COUNT)+OBSTACLE_GAP;obstacles.push({x:obstacleX,y:obstacleY,width:obstacleWidth,height:obstacleHeight})}}function setPlayerStartPosition(){const startingObstacle=obstacles[0];playerX=startingObstacle.x+obstacleWidth/2-PLAYER_RADIUS;playerY=startingObstacle.y-PLAYER_RADIUS*2}function isOutOfBounds(x,y,width,height){return x<0||x>canvas.width||y<0||y>canvas.height}function generateNewObstacle(playerDirection){if(playerDirection==="up"){obstacles.shift();const obstacleX=Math.random()*(canvas.width-obstacleWidth);const obstacleY=obstacles.length>0?obstacles[obstacles.length-1].y-canvas.height/OBSTACLE_COUNT-OBSTACLE_GAP:canvas.height;obstacles.push({x:obstacleX,y:obstacleY,width:obstacleWidth,height:obstacleHeight})}else if(playerDirection==="down"){obstacles.pop();const obstacleX=Math.random()*(canvas.width-obstacleWidth);const obstacleY=obstacles.length>0?obstacles[0].y+canvas.height/OBSTACLE_COUNT+OBSTACLE_GAP:0;obstacles.unshift({x:obstacleX,y:obstacleY,width:obstacleWidth,height:obstacleHeight})}}function checkEnemyDeath(){if(isPlayerAlive&&playerSpeedX>=0&&playerY+PLAYER_RADIUS*2>enemyY-ENEMY_RADIUS&&playerX+PLAYER_RADIUS*2>enemyX-ENEMY_RADIUS&&playerX<enemyX+ENEMY_RADIUS){playerIsOnGround=false;playerSpeedY=-2;setTimeout(()=>{playerSpeedY=0},100);enemyX=-100;setTimeout(spawnNewEnemy,1e3);enemyMultiplier++}}function spawnNewEnemy(){enemyX=Math.random()*(canvas.width-ENEMY_RADIUS*2);enemyY=Math.random()*(canvas.height-ENEMY_RADIUS*2);for(let i=0;i<enemyMultiplier-0;i++){shootLaser()}}function draw(timestamp){context.fillStyle="black";context.fillRect(0,0,canvas.width,canvas.height);const elapsedSeconds=(timestamp-lastFrameTime)/1e3;lastFrameTime=timestamp;applyGravity(elapsedSeconds);applyTraction();movePlayer();moveEnemy();moveLasers();detectObstacleCollision();drawLasers();drawObstacles();checkEnemyDeath();if(playerY<offsetY+PLAYER_RADIUS*2&&playerX>offsetX-PLAYER_RADIUS*2&&playerX<offsetX+obstacleWidth+PLAYER_RADIUS*2){offsetY-=canvas.height/OBSTACLE_COUNT;playerY+=canvas.height/OBSTACLE_COUNT;enemyY+=canvas.height/OBSTACLE_COUNT;generateNewObstacle()}requestAnimationFrame(draw)}let lastFrameTime=0;createObstacles();setPlayerStartPosition();draw();document.addEventListener("keydown",event=>{if(event.code==="KeyA"){playerSpeedX=-5}if(event.code==="KeyD"){playerSpeedX=5}if(event.code==="KeyW"){jump()}});document.addEventListener("keyup",event=>{if(event.code==="KeyA"||event.code==="KeyD"){playerSpeedX=0}});