How I can do a smooth movement of player in canvas game?

To make a smoother animation you need a higher frame rate. In the code given you just use the onkeydown event which is not à certain number of frame per second. You can use setInterval in complement or window.requestAnimationFrame :

//Canvas
mycan.style.display = "block";
mycan.height = innerHeight;
mycan.width = innerWidth;
mycan.style.backgroundColor = "grey";
//Context
const ctx = mycan.getContext("2d");
//Player
const player = {x: 10, y: 10, w: 20, h: 20};
//Start-position
ctx.fillRect(player.x, player.y, player.w, player.h);
//No-smooth-movement
window.onkeydown = move = (e) => {
    let key = e.keyCode;
    if     (key === 68 && player.x <= mycan.width-25) {player.x += 10;} //right
    else if(key === 65 && player.x >= 10) {player.x -= 10;} //left
    else if(key === 83 && player.y <= mycan.height-25) {player.y += 10;} //down
    else if(key === 87 && player.y >= 10) {player.y -= 10;} //up
}

const draw = ()=>{
  ctx.clearRect(0,0, mycan.width, mycan.height);
  ctx.fillRect(player.x, player.y, player.w, player.h);
};

setInterval(()=>{
  draw();
},1000/60);
<canvas id="mycan"></canvas>

you can also reduce the pace (here you use 10 to move the player 10 pixels in a direction)

and customize your event :

//Canvas
mycan.style.display = "block";
mycan.height = innerHeight;
mycan.width = innerWidth;
mycan.style.backgroundColor = "grey";
//Context
const ctx = mycan.getContext("2d");
//Player
const player = {x: 10, y: 10, w: 20, h: 20};
const keystack = [];
//Start-position
ctx.fillRect(player.x, player.y, player.w, player.h);
//No-smooth-movement
window.onkeydown = move = (e) => {
    keystack.push(e.keyCode);
}

const draw = ()=>{
  let key = keystack.pop();
  if     (key === 68 && player.x <= mycan.width-25) {player.x += 10;} //right
    else if(key === 65 && player.x >= 10) {player.x -= 10;} //left
    else if(key === 83 && player.y <= mycan.height-25) {player.y += 10;} //down
    else if(key === 87 && player.y >= 10) {player.y -= 10;} //up
  ctx.clearRect(0,0, mycan.width, mycan.height);
  ctx.fillRect(player.x, player.y, player.w, player.h);
};

setInterval(()=>{
  draw();
},1000/60);
<canvas id=mycan></canvas>

and the last and most important thing is adding steps to that animation. instead of moving +10 immediately move +5 then again +5 but this time in the drawing and not in the event :

//Canvas
mycan.style.display = "block";
mycan.height = innerHeight;
mycan.width = innerWidth;
mycan.style.backgroundColor = "grey";
//Context
const ctx = mycan.getContext("2d");
//Player
const player = {x: 10, y: 10, w: 20, h: 20};
const keystack = [];
let isMoving = 0;
let prevKey = {};
//Start-position
ctx.fillRect(player.x, player.y, player.w, player.h);
//No-smooth-movement
window.onkeydown = move = (e) => {
    keystack.push(e.keyCode);
}

window.onkeyup = move = (e) => {
    keystack.pop();
}

const draw = ()=>{
  let key = keystack[keystack.length-1];
  //if(!(isMoving=isMoving%2)) key = keystack.pop(); 
  //else key = prevKey;
  
  if     (key === 68 && player.x <= mycan.width-25) {player.x += 5;} //right
    else if(key === 65 && player.x >= 10) {player.x -= 5;} //left
    else if(key === 83 && player.y <= mycan.height-25) {player.y += 5;} //down
    else if(key === 87 && player.y >= 10) {player.y -= 5;} //up
  ctx.clearRect(0,0, mycan.width, mycan.height);
  ctx.fillRect(player.x, player.y, player.w, player.h);
  prevKey = key;
  isMoving++;
};

setInterval(()=>{
  draw();
},1000/60);
<canvas id = mycan > </canvas>

and to prevent initial stuttering :

//Canvas
mycan.style.display = "block";
mycan.height = innerHeight;
mycan.width = innerWidth;
mycan.style.backgroundColor = "grey";
//Context
const ctx = mycan.getContext("2d");
//Player
const player = {x: 10, y: 10, w: 20, h: 20};
const keystack = [];
let isMoving = 0;
let prevKey = {};
//Start-position
ctx.fillRect(player.x, player.y, player.w, player.h);
//No-smooth-movement
window.onkeydown = move = (e) => {
    keystack.push(e.keyCode);
}

window.onkeyup = move = (e) => {
    keystack.pop();
}

const draw = ()=>{
  let key = keystack[keystack.length-1];
  
  if     (key === 68 && player.x <= mycan.width-25) {player.x += 5;} //right
    else if(key === 65 && player.x >= 10) {player.x -= 5;} //left
    else if(key === 83 && player.y <= mycan.height-25) {player.y += 5;} //down
    else if(key === 87 && player.y >= 10) {player.y -= 5;} //up
  ctx.clearRect(0,0, mycan.width, mycan.height);
  ctx.fillRect(player.x, player.y, player.w, player.h);
  prevKey = key;
  isMoving++;
};

setInterval(()=>{
  draw();
},1000/60);
<canvas id=mycan></canvas>

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top