NewFiveFour | Blog | Portfolio


Javascript: create game obstacles in canvas

In our previous tutorial on canvas we smoothly moved a player (read: rectangle). We can use the same kind of code to generate obstacles.
 
We're going to have obstacles moving from the left to the right of the screen.
 
First let's create an array with an initial obstacle: var obstacles = [{width: 30, height: 30, x: canvas.width, y:110}].
 
In our update function we'll loop through them all and draw those rectangles. And move the x each frame back to create movement.

function updateGameArea() {
    context.clearRect(0, 0, canvas.width, canvas.height)  
    obstacles.forEach(o => {
      o.x -= 1
      context.fillRect(o.x, o.y, o.width, o.height);      
    })

    requestAnimationFrame(updateGameArea);  
}

We obviously only have one obstacle. Let's now create a new one each time we see 100 frames. A frame is a counter that is incremented on each animation draw.

var frame = 0
function updateGameArea() {
    frame++
    context.clearRect(0, 0, canvas.width, canvas.height)
  
    if(frame % 100 == 0) obstacles.push({width: 30, height: 30, x: canvas.width, y:canvas.height * Math.random()});
  
    obstacles.forEach(o => {
      o.x -= 1
      context.fillRect(o.x, o.y, o.width, o.height);      
    })

    requestAnimationFrame(updateGameArea);  
}

We'll also randomise the y position of the obstacles.
 
Our full code is:

var canvas = document.querySelector("canvas")
var context = canvas.getContext("2d");
var obstacles = [{width: 30, height: 30, x: canvas.width, y:110}];
var frame = 0
function updateGameArea() {
    frame++
    context.clearRect(0, 0, canvas.width, canvas.height)
  
    if(frame % 100 == 0) obstacles.push({width: 30, height: 30, x: canvas.width, y:canvas.height * Math.random(), speedX: 0.0, speedY: 0.0});
  
    obstacles.forEach(o => {
      o.x -= 1
      context.fillRect(o.x, o.y, o.width, o.height);      
    })

    requestAnimationFrame(updateGameArea);  
}

requestAnimationFrame(updateGameArea);


javascript canvas


Javascript: Smoothly move a player in canvas

Previously we learnt how to move a player around a canvas: https://newfivefour.com/javascript-canvas-move-a-player.html

var canvas = document.querySelector("canvas")
var context = canvas.getContext("2d");
var player = {width: 30, height: 30, x: 0, y:110, speedX: 0.0, speedY: 0.0};

function updateGameArea() {
    context.clearRect(0, 0, canvas.width, canvas.height)  
    context.fillRect(player.x, player.y, player.width, player.height);

    requestAnimationFrame(updateGameArea);  
}

window.onkeydown = function(event) {
  event.preventDefault() // stops the button scrolling the page
  if(event.keyCode == 40) { // down
    player.y += 10
  } else if(event.keyCode == 38) { // up
    player.y -= 10    
  } else if(event.keyCode == 39) { // right 
    player.x += 10    
  } else if(event.keyCode == 37) { // left
    player.x -= 10        
  } 
}

requestAnimationFrame(updateGameArea);

But the movement is jerky. We can fix that.
 
We will make our player object take a speedX and speedY property firstly: player = {width: 30, height: 30, x: 0, y:110, speedX: 0.0, speedY: 0.0}; .
 
And in the update function we will change the player x and y by this variable:

function updateGameArea() {
    context.clearRect(0, 0, canvas.width, canvas.height)  
    player.x += player.speedX;
    player.y += player.speedY;
    context.fillRect(player.x, player.y, player.width, player.height);

    requestAnimationFrame(updateGameArea);  
}

All that's left is the onkeyup and down functions that change the speedX and speedY.
 
When the button is pressed down we'll increase the speed. And when it's released we'll completely stop the movement:
 
Here's all the code:

var canvas = document.querySelector("canvas")
var context = canvas.getContext("2d");
player = {width: 30, height: 30, x: 0, y:110, speedX: 0.0, speedY: 0.0};

function updateGameArea() {
    context.clearRect(0, 0, canvas.width, canvas.height)  
    player.x += player.speedX;
    player.y += player.speedY;
    context.fillRect(player.x, player.y, player.width, player.height);

    requestAnimationFrame(updateGameArea);  
}

window.onkeydown = function(event) {
  event.preventDefault() // stop the arrow keys scrolling the page
  if(event.keyCode == 40) { // down
    player.speedY += 1
  } else if(event.keyCode == 38) { // up
    player.speedY -= 1
  } else if(event.keyCode == 39) { // right 
    player.speedX += 1
  } else if(event.keyCode == 37) { // left
    player.speedX -= 1        
  } 
}

window.onkeyup = function(event) {
  event.preventDefault() // stop the arrow keys scrolling the page
  player.speedX = 0
  player.speedY = 0
}

requestAnimationFrame(updateGameArea);


javascript canvas


Javascript: Move a player on the canvas

We're going to create a player. This is a rectangle. We're going to move it around our canvas.
 
First create a HTML file a canvas tag with width and height attributes.
 
Let's start the javascript. Call requestAnimationFrame with a function that loops by calling requestAnimationFrame inside that function.
 
In the function clear the screen each time. Obviously nothing will be printed on the screen at this point.

var canvas = document.querySelector("canvas")
var context = canvas.getContext("2d");

function updateGameArea() {
    context.clearRect(0, 0, canvas.width, canvas.height)  
    requestAnimationFrame(updateGameArea);  
}

requestAnimationFrame(updateGameArea);

For the next iteration we'll create a player object. It will have height and width and an x and a y.
 
In the updateGameArea function we'll use these properties to draw a rectangle to the screen.

var canvas = document.querySelector("canvas")
var context = canvas.getContext("2d");
var player = {width: 30, height: 30, x: 0, y:110};

function updateGameArea() {
    context.clearRect(0, 0, canvas.width, canvas.height)  
    context.fillRect(player.x, player.y, player.width, player.height);

    requestAnimationFrame(updateGameArea);  
}

requestAnimationFrame(updateGameArea);

This now constantly prints a rectangle to the screen.
 
In the next iteration we will use a onkeydown listener to check for the left, right and up and down buttons.
 
When we find those, we will update the player x and y positions and thus move our player.

var canvas = document.querySelector("canvas")
var context = canvas.getContext("2d");
var player = {width: 30, height: 30, x: 0, y:110, speedX: 0.0, speedY: 0.0};

function updateGameArea() {
    context.clearRect(0, 0, canvas.width, canvas.height)  
    context.fillRect(player.x, player.y, player.width, player.height);

    requestAnimationFrame(updateGameArea);  
}

window.onkeydown = function(event) {
  event.preventDefault() // stops the button scrolling the page
  if(event.keyCode == 40) { // down
    player.y += 10
  } else if(event.keyCode == 38) { // up
    player.y -= 10    
  } else if(event.keyCode == 39) { // right 
    player.x += 10    
  } else if(event.keyCode == 37) { // left
    player.x -= 10        
  } 
}

requestAnimationFrame(updateGameArea);

And voila.

javascript canvas


Javascript: A scrolling background in canvas

If you want a scrolling background in Canvas let's first do the initial canvas stuff, including specifying the canvas width and height, and setting a new image and loading a local png file in it.

var canvas = document.querySelector("canvas")
var ctx = canvas.getContext("2d")
var canvasWidth = 1000 // for example
var canvasHeight = 400 // for example
var image = new Image()
image.src = "somefile.png" // for example

Next let's specify the scrolling speed in pixels and initial x position:

var speed = -0.2
var x = 0;

Let's create a update function. It will move the x position depending on the pixel speed.
 
Then it will draw two images, one that will be scrolling off the screen, another that will be to the right of it.

function update() {
  x += speed
  x %= canvasWidth
  ctx.drawImage(image, x, 0, 
    canvasWidth, canvasHeight)
  ctx.drawImage(image, x + canvasWidth, 0, 
    canvasWidth, canvasHeight)

  requestAnimationFrame(update)                      
} 
requestAnimationFrame(update)                      

It's doing two other things.
  1. The whole thing is started with requestAnimationFrame(update). It will only call update once though. So in update we must call it again.
  2. Say the canvas width is 500. Once x is 501 the image will be off the canvas. To make it back we can do 501 % 500 to get the position 1. (And when it's 499 that will produce 499 anyway). So that what the x %=500 lines does.

javascript canvas


Javascript: Draw rounded rectangle in canvas

Canvas doesn't provide a method to do rounded rectangles. But we can make one with arcs and lineTos.
 
We can also add it to the CanvasRenderingContext2D prototype. This means we can use it like the below. And set your own stroke and fill styles:

  let canvas = document.getElementById('example');
  let ctx = canvas.getContext('2d');  
  ctx.beginPath();
  ctx.roundedRectangle(0, 0, 100, 100, 20);
  ctx.stroke();
  
  ctx.beginPath();  
  ctx.roundedRectangle(5, 5, 90, 90, 15);
  ctx.stroke();     

Here's the function to draw a rounded rectangle.

CanvasRenderingContext2D.prototype.roundedRectangle = function(x, y, width, height, rounded) {
  const radiansInCircle = 2 * Math.PI
  const halfRadians = (2 * Math.PI)/2
  const quarterRadians = (2 * Math.PI)/4  
  
  // top left arc
  this.arc(rounded + x, rounded + y, rounded, -quarterRadians, halfRadians, true)
  
  // line from top left to bottom left
  this.lineTo(x, y + height - rounded)

  // bottom left arc  
  this.arc(rounded + x, height - rounded + y, rounded, halfRadians, quarterRadians, true)  
  
  // line from bottom left to bottom right
  this.lineTo(x + width - rounded, y + height)

  // bottom right arc
  this.arc(x + width - rounded, y + height - rounded, rounded, quarterRadians, 0, true)  
  
  // line from bottom right to top right
  this.lineTo(x + width, y + rounded)  

  // top right arc
  this.arc(x + width - rounded, y + rounded, rounded, 0, -quarterRadians, true)  
  
  // line from top right to top left
  this.lineTo(x + rounded, y)  
}

javascript canvas


Page 1 of 91
next

Portfolio