Sprite(​properties)

A versatile way to update and draw your game objects. It can handle simple rectangles, images, and sprite sheet animations. It can be used for your main player object as well as tiny particles in a particle engine.

Sprite Parameters

properties

Object. Properties of the sprite.

properties.x

Number. X coordinate of the position vector.

properties.y

Number. Y coordinate of the position vector.

properties.dx Optional

Number. X coordinate of the velocity vector.

properties.dy Optional

Number. Y coordinate of the velocity vector.

properties.ddx Optional

Number. X coordinate of the acceleration vector.

properties.ddy Optional

Number. Y coordinate of the acceleration vector.

properties.color Optional

String. Fill color for the sprite if no image or animation is provided.

properties.width Optional

Number. Width of the sprite.

properties.height Optional

Number. Height of the sprite.

properties.ttl Optional

Number. How many frames the sprite should be alive. Used by Pool. Defaults to Infinity.

properties.rotation Optional

Number. Sprites rotation around the origin in radians. Defaults to 0.

properties.anchor Optional

Number. The x and y origin of the sprite. {x:0, y:0} is the top left corner of the sprite, {x:1, y:1} is the bottom right corner. Defaults to {x:0,y:0}.

properties.context Optional

Canvas​Rendering​Context2D. The context the sprite should draw to. Defaults to core.getContext().

properties.image Optional

Image or HTMLCanvasElement. Use an image to draw the sprite.

properties.animations Optional

Object. An object of Animations from a Spritesheet to animate the sprite.

properties.update Optional

Function. Function called every frame to update the sprite.

properties.render Optional

Function. Function called every frame to render the sprite.

properties.* Optional

Any type. Any additional properties you need added to the sprite. For example, if you pass Sprite({type: 'player'}) then the sprite will also have a property of the same name and value. You can pass as many additional properties as you want.

Table of Contents

Rectangle Sprite

In its most basic form, a sprite is a rectangle with a fill color. To create a rectangle sprite, pass the arguments width, height, and color. A rectangle sprite is great for initial prototyping and particles.

let { Sprite } = kontra

let sprite = Sprite({
  x: 300,
  y: 100,
  anchor: {x: 0.5, y: 0.5},

  // required for a rectangle sprite
  width: 20,
  height: 40,
  color: 'red'
});

sprite.render();
import { Sprite } from 'path/to/kontra.mjs'

let sprite = Sprite({
  x: 300,
  y: 100,
  anchor: {x: 0.5, y: 0.5},

  // required for a rectangle sprite
  width: 20,
  height: 40,
  color: 'red'
});

sprite.render();
import { Sprite } from 'kontra';

let sprite = Sprite({
  x: 300,
  y: 100,
  anchor: {x: 0.5, y: 0.5},

  // required for a rectangle sprite
  width: 20,
  height: 40,
  color: 'red'
});

sprite.render();

Image Sprite

A sprite can use an image instead of drawing a rectangle. To create an image sprite, pass the image argument. The size of the sprite will automatically be set as the width and height of the image.

let { Sprite } = kontra

let image = new Image();
image.src = 'assets/imgs/character.png';
image.onload = function() {
  let sprite = Sprite({
    x: 300,
    y: 100,
    anchor: {x: 0.5, y: 0.5},

    // required for an image sprite
    image: image
  });

  sprite.render();
};
import { Sprite } from 'path/to/kontra.mjs'

let image = new Image();
image.src = 'assets/imgs/character.png';
image.onload = function() {
  let sprite = Sprite({
    x: 300,
    y: 100,
    anchor: {x: 0.5, y: 0.5},

    // required for an image sprite
    image: image
  });

  sprite.render();
};
import { Sprite } from 'kontra';

let image = new Image();
image.src = 'assets/imgs/character.png';
image.onload = function() {
  let sprite = Sprite({
    x: 300,
    y: 100,
    anchor: {x: 0.5, y: 0.5},

    // required for an image sprite
    image: image
  });

  sprite.render();
};

Animation Sprite

A sprite can use a spritesheet animation as well. To create an animation sprite, pass the animations argument. The size of the sprite will automatically be set as the width and height of a frame of the spritesheet.

A sprite can have multiple named animations. The easiest way to create animations is to use SpriteSheet. All animations will automatically be cloned so no two sprites update the same animation.

let { Sprite, SpriteSheet, GameLoop } = kontra

let image = new Image();
image.src = 'assets/imgs/character_walk_sheet.png';
image.onload = function() {

  // use spriteSheet to create animations from an image
  let spriteSheet = SpriteSheet({
    image: image,
    frameWidth: 72,
    frameHeight: 97,
    animations: {
      // create a named animation: walk
      walk: {
        frames: '0..9',  // frames 0 through 9
        frameRate: 30
      }
    }
  });

  let sprite = Sprite({
    x: 300,
    y: 100,
    anchor: {x: 0.5, y: 0.5},

    // required for an animation sprite
    animations: spriteSheet.animations
  });

  // use kontra.gameLoop to play the animation
  let loop = GameLoop({
    update: function(dt) {
      sprite.update();
    },
    render: function() {
      sprite.render();
    }
  });

  loop.start();
};
import { Sprite, SpriteSheet, GameLoop } from 'path/to/kontra.mjs'

let image = new Image();
image.src = 'assets/imgs/character_walk_sheet.png';
image.onload = function() {

  // use spriteSheet to create animations from an image
  let spriteSheet = SpriteSheet({
    image: image,
    frameWidth: 72,
    frameHeight: 97,
    animations: {
      // create a named animation: walk
      walk: {
        frames: '0..9',  // frames 0 through 9
        frameRate: 30
      }
    }
  });

  let sprite = Sprite({
    x: 300,
    y: 100,
    anchor: {x: 0.5, y: 0.5},

    // required for an animation sprite
    animations: spriteSheet.animations
  });

  // use kontra.gameLoop to play the animation
  let loop = GameLoop({
    update: function(dt) {
      sprite.update();
    },
    render: function() {
      sprite.render();
    }
  });

  loop.start();
};
import { Sprite, SpriteSheet, GameLoop } from 'kontra';

let image = new Image();
image.src = 'assets/imgs/character_walk_sheet.png';
image.onload = function() {

  // use spriteSheet to create animations from an image
  let spriteSheet = SpriteSheet({
    image: image,
    frameWidth: 72,
    frameHeight: 97,
    animations: {
      // create a named animation: walk
      walk: {
        frames: '0..9',  // frames 0 through 9
        frameRate: 30
      }
    }
  });

  let sprite = Sprite({
    x: 300,
    y: 100,
    anchor: {x: 0.5, y: 0.5},

    // required for an animation sprite
    animations: spriteSheet.animations
  });

  // use kontra.gameLoop to play the animation
  let loop = GameLoop({
    update: function(dt) {
      sprite.update();
    },
    render: function() {
      sprite.render();
    }
  });

  loop.start();
};

Custom Properties

If you need to draw a different shape, such as a circle, you can pass in custom properties and a render function to handle drawing the sprite.

let { Sprite } = kontra

let sprite = Sprite({
  x: 300,
  y: 100,

  color: 'red',

  // custom properties
  radius: 20,

  render: function() {
    this.context.fillStyle = this.color;

    this.context.beginPath();
    this.context.arc(this.x, this.y, this.radius, 0, 2  * Math.PI);
    this.context.fill();
  }
});

sprite.render();
import { Sprite } from 'path/to/kontra.mjs'

let sprite = Sprite({
  x: 300,
  y: 100,

  color: 'red',

  // custom properties
  radius: 20,

  render: function() {
    this.context.fillStyle = this.color;

    this.context.beginPath();
    this.context.arc(this.x, this.y, this.radius, 0, 2  * Math.PI);
    this.context.fill();
  }
});

sprite.render();
import { Sprite } from 'kontra';

let sprite = Sprite({
  x: 300,
  y: 100,

  color: 'red',

  // custom properties
  radius: 20,

  render: function() {
    this.context.fillStyle = this.color;

    this.context.beginPath();
    this.context.arc(this.x, this.y, this.radius, 0, 2  * Math.PI);
    this.context.fill();
  }
});

sprite.render();

Extending a Sprite

If you want to extend a Sprite, you can do so by extending the Sprite class. The one caveat is that Sprite is not the Sprite class, but actually is a factory function.

To extend the Sprite class, use the .class property of the constructor.

let { Sprite } = kontra;

class CustomSprite extends Sprite.class {
  // ...
}
import { Sprite } from 'path/to/kontra.mjs';

class CustomSprite extends Sprite.class {
  // ...
}
import { Sprite } from 'kontra';

class CustomSprite extends Sprite.class {
  // ...
}

Sprite​.acceleration

The sprites acceleration vector.

Sprite​.advance(​[dt])

Move the sprite by its acceleration and velocity. If the sprite is an animation sprite, it also advances the animation every frame.

If you override the sprites update() function with your own update function, you can call this function to move the sprite normally.

let { Sprite } = kontra;

let sprite = Sprite({
  x: 100,
  y: 200,
  width: 20,
  height: 40,
  dx: 5,
  dy: 2,
  update: function() {
    // move the sprite normally
    sprite.advance();

    // change the velocity at the edges of the canvas
    if (this.x < 0 ||
        this.x + this.width > this.context.canvas.width) {
      this.dx = -this.dx;
    }
    if (this.y < 0 ||
        this.y + this.height > this.context.canvas.height) {
      this.dy = -this.dy;
    }
  }
});
import { Sprite } from 'path/to/kontra.mjs';

let sprite = Sprite({
  x: 100,
  y: 200,
  width: 20,
  height: 40,
  dx: 5,
  dy: 2,
  update: function() {
    // move the sprite normally
    sprite.advance();

    // change the velocity at the edges of the canvas
    if (this.x < 0 ||
        this.x + this.width > this.context.canvas.width) {
      this.dx = -this.dx;
    }
    if (this.y < 0 ||
        this.y + this.height > this.context.canvas.height) {
      this.dy = -this.dy;
    }
  }
});
import { Sprite } from 'kontra';

let sprite = Sprite({
  x: 100,
  y: 200,
  width: 20,
  height: 40,
  dx: 5,
  dy: 2,
  update: function() {
    // move the sprite normally
    sprite.advance();

    // change the velocity at the edges of the canvas
    if (this.x < 0 ||
        this.x + this.width > this.context.canvas.width) {
      this.dx = -this.dx;
    }
    if (this.y < 0 ||
        this.y + this.height > this.context.canvas.height) {
      this.dy = -this.dy;
    }
  }
});

advance Parameters

dt Optional

Number. Time since last update.

Sprite​.anchor

The x and y origin of the sprite. {x:0, y:0} is the top left corner of the sprite, {x:1, y:1} is the bottom right corner.

let { Sprite } = kontra

let sprite = Sprite({
  x: 150,
  y: 100,
  color: 'red',
  width: 50,
  height: 50,
  render: function() {
    this.draw();

    // draw origin
    this.context.fillStyle = 'yellow';
    this.context.beginPath();
    this.context.arc(this.x, this.y, 3, 0, 2*Math.PI);
    this.context.fill();
  }
});
sprite.render();

sprite.anchor = {x: 0.5, y: 0.5};
sprite.x = 300;
sprite.render();

sprite.anchor = {x: 1, y: 1};
sprite.x = 450;
sprite.render();
import { Sprite } from 'path/to/kontra.mjs'

let sprite = Sprite({
  x: 150,
  y: 100,
  color: 'red',
  width: 50,
  height: 50,
  render: function() {
    this.draw();

    // draw origin
    this.context.fillStyle = 'yellow';
    this.context.beginPath();
    this.context.arc(this.x, this.y, 3, 0, 2*Math.PI);
    this.context.fill();
  }
});
sprite.render();

sprite.anchor = {x: 0.5, y: 0.5};
sprite.x = 300;
sprite.render();

sprite.anchor = {x: 1, y: 1};
sprite.x = 450;
sprite.render();
import { Sprite } from 'kontra';

let sprite = Sprite({
  x: 150,
  y: 100,
  color: 'red',
  width: 50,
  height: 50,
  render: function() {
    this.draw();

    // draw origin
    this.context.fillStyle = 'yellow';
    this.context.beginPath();
    this.context.arc(this.x, this.y, 3, 0, 2*Math.PI);
    this.context.fill();
  }
});
sprite.render();

sprite.anchor = {x: 0.5, y: 0.5};
sprite.x = 300;
sprite.render();

sprite.anchor = {x: 1, y: 1};
sprite.x = 450;
sprite.render();

Sprite​.animations

An object of Animations from a SpriteSheet to animate the sprite. Each animation is named so that it can can be used by name for the sprites playAnimation() function.

let { Sprite, SpriteSheet } = kontra;

let spriteSheet = SpriteSheet({
  // ...
  animations: {
    idle: {
      frames: 1,
      loop: false,
    },
    walk: {
      frames: [1,2,3]
    }
  }
});

let sprite = Sprite({
  x: 100,
  y: 200,
  animations: spriteSheet.animations
});

sprite.playAnimation('idle');
import { Sprite, SpriteSheet } from 'path/to/kontra.mjs';

let spriteSheet = SpriteSheet({
  // ...
  animations: {
    idle: {
      frames: 1,
      loop: false,
    },
    walk: {
      frames: [1,2,3]
    }
  }
});

let sprite = Sprite({
  x: 100,
  y: 200,
  animations: spriteSheet.animations
});

sprite.playAnimation('idle');
import { Sprite, SpriteSheet } from 'kontra';

let spriteSheet = SpriteSheet({
  // ...
  animations: {
    idle: {
      frames: 1,
      loop: false,
    },
    walk: {
      frames: [1,2,3]
    }
  }
});

let sprite = Sprite({
  x: 100,
  y: 200,
  animations: spriteSheet.animations
});

sprite.playAnimation('idle');

Sprite​.collidesWith(​object)

Check if the sprite collide with the object. Uses a simple Axis-Aligned Bounding Box (AABB) collision check. Takes into account the sprites anchor.

NOTE: Does not take into account sprite rotation. If you need collision detection between rotated sprites you will need to implement your own collidesWith() function. I suggest looking at the Separate Axis Theorem.

let { Sprite } = kontra;

let sprite = Sprite({
  x: 100,
  y: 200,
  width: 20,
  height: 40
});

let sprite2 = Sprite({
  x: 150,
  y: 200,
  width: 20,
  height: 20
});

sprite.collidesWith(sprite2);  //=> false

sprite2.x = 115;

sprite.collidesWith(sprite2);  //=> true
import { Sprite } from 'path/to/kontra.mjs';

let sprite = Sprite({
  x: 100,
  y: 200,
  width: 20,
  height: 40
});

let sprite2 = Sprite({
  x: 150,
  y: 200,
  width: 20,
  height: 20
});

sprite.collidesWith(sprite2);  //=> false

sprite2.x = 115;

sprite.collidesWith(sprite2);  //=> true
import { Sprite } from 'kontra';

let sprite = Sprite({
  x: 100,
  y: 200,
  width: 20,
  height: 40
});

let sprite2 = Sprite({
  x: 150,
  y: 200,
  width: 20,
  height: 20
});

sprite.collidesWith(sprite2);  //=> false

sprite2.x = 115;

sprite.collidesWith(sprite2);  //=> true

If you need a different type of collision check, you can override this function by passing an argument by the same name.

// circle collision
function collidesWith(object) {
  let dx = this.x - object.x;
  let dy = this.y - object.y;
  let distance = Math.sqrt(dx * dx + dy * dy);

  return distance < this.radius + object.radius;
}

let sprite = Sprite({
  x: 100,
  y: 200,
  radius: 25,
  collidesWith: collidesWith
});

let sprite2 = Sprite({
  x: 150,
  y: 200,
  radius: 30,
  collidesWith: collidesWith
});

sprite.collidesWith(sprite2);  //=> true
// circle collision
function collidesWith(object) {
  let dx = this.x - object.x;
  let dy = this.y - object.y;
  let distance = Math.sqrt(dx * dx + dy * dy);

  return distance < this.radius + object.radius;
}

let sprite = Sprite({
  x: 100,
  y: 200,
  radius: 25,
  collidesWith: collidesWith
});

let sprite2 = Sprite({
  x: 150,
  y: 200,
  radius: 30,
  collidesWith: collidesWith
});

sprite.collidesWith(sprite2);  //=> true
// circle collision
function collidesWith(object) {
  let dx = this.x - object.x;
  let dy = this.y - object.y;
  let distance = Math.sqrt(dx * dx + dy * dy);

  return distance < this.radius + object.radius;
}

let sprite = Sprite({
  x: 100,
  y: 200,
  radius: 25,
  collidesWith: collidesWith
});

let sprite2 = Sprite({
  x: 150,
  y: 200,
  radius: 30,
  collidesWith: collidesWith
});

sprite.collidesWith(sprite2);  //=> true

collidesWith Parameters

object

Object. Object to check collision against.

collidesWith Return value

true if the objects collide, false otherwise. Will return null if the either of the two objects are rotated.

Sprite​.color

The color of the sprite if it was passed as an argument.

Sprite​.context

The context the sprite will draw to.

Sprite​.currentAnimation

The currently playing Animation object if animations was passed as an argument.

Sprite​.ddx

X coordinate of the acceleration vector.

Sprite​.ddy

Y coordinate of the acceleration vector.

Sprite​.draw(​)

Draw the sprite at its X and Y position. This function changes based on the type of the sprite. For a rectangle sprite, it uses context.fillRect(), for an image sprite it uses context.drawImage(), and for an animation sprite it uses the currentAnimation render() function.

If you override the sprites render() function with your own render function, you can call this function to draw the sprite normally.

let { Sprite } = kontra;

let sprite = Sprite({
 x: 290,
 y: 80,
 color: 'red',
 width: 20,
 height: 40,

 render: function() {
   // draw the rectangle sprite normally
   this.draw();

   // outline the sprite
   this.context.strokeStyle = 'yellow';
   this.context.lineWidth = 2;
   this.context.strokeRect(this.x, this.y, this.width, this.height);
 }
});

sprite.render();
import { Sprite } from 'path/to/kontra.mjs';

let sprite = Sprite({
 x: 290,
 y: 80,
 color: 'red',
 width: 20,
 height: 40,

 render: function() {
   // draw the rectangle sprite normally
   this.draw();

   // outline the sprite
   this.context.strokeStyle = 'yellow';
   this.context.lineWidth = 2;
   this.context.strokeRect(this.x, this.y, this.width, this.height);
 }
});

sprite.render();
import { Sprite } from 'kontra';

let sprite = Sprite({
 x: 290,
 y: 80,
 color: 'red',
 width: 20,
 height: 40,

 render: function() {
   // draw the rectangle sprite normally
   this.draw();

   // outline the sprite
   this.context.strokeStyle = 'yellow';
   this.context.lineWidth = 2;
   this.context.strokeRect(this.x, this.y, this.width, this.height);
 }
});

sprite.render();

Sprite​.dx

X coordinate of the velocity vector.

Sprite​.dy

Y coordinate of the velocity vector.

Sprite​.height

The height of the sprite. If the sprite is a rectangle sprite, it uses the passed in value. For an image sprite it is the height of the image. And for an animation sprite it is the height of a single frame of the animation.

Setting the value to a negative number will result in the sprite being flipped across the horizontal axis while the height will remain a positive value.

Sprite​.image

The image the sprite will use when drawn if passed as an argument.

Sprite​.init(​properties)

Use this function to reinitialize a sprite. It takes the same properties object as the constructor. Useful it you want to repurpose a sprite.

init Parameters

properties

Object. Properties of the sprite.

Sprite​.isAlive(​)

Check if the sprite is alive. Primarily used by Pool to know when to recycle an object.

isAlive Return value

true if the sprites ttl property is above 0, false otherwise.

Sprite​.playAnimation(​name)

Set the currently playing animation of an animation sprite.

let { Sprite, SpriteSheet } = kontra;

let spriteSheet = SpriteSheet({
  // ...
  animations: {
    idle: {
      frames: 1
    },
    walk: {
      frames: [1,2,3]
    }
  }
});

let sprite = Sprite({
  x: 100,
  y: 200,
  animations: spriteSheet.animations
});

sprite.playAnimation('idle');
import { Sprite, SpriteSheet } from 'path/to/kontra.mjs';

let spriteSheet = SpriteSheet({
  // ...
  animations: {
    idle: {
      frames: 1
    },
    walk: {
      frames: [1,2,3]
    }
  }
});

let sprite = Sprite({
  x: 100,
  y: 200,
  animations: spriteSheet.animations
});

sprite.playAnimation('idle');
import { Sprite, SpriteSheet } from 'kontra';

let spriteSheet = SpriteSheet({
  // ...
  animations: {
    idle: {
      frames: 1
    },
    walk: {
      frames: [1,2,3]
    }
  }
});

let sprite = Sprite({
  x: 100,
  y: 200,
  animations: spriteSheet.animations
});

sprite.playAnimation('idle');

playAnimation Parameters

name

String. Name of the animation to play.

Sprite​.position

The sprites position vector. The sprites position is its position in the world, as opposed to the position in the viewport. Typically the position in the world and the viewport are the same value. If the sprite has been added to a tileEngine, the position vector represents where in the tile world the sprite is while the viewport represents where to draw the sprite in relation to the top-left corner of the canvas.

Sprite​.render(​)

Render the sprite. Calls the sprites draw() function.

Sprite​.rotation

The rotation of the sprite around the origin in radians.

Sprite​.sx

The X coordinate of the camera. Used to determine viewX.

Sprite​.sy

The Y coordinate of the camera. Used to determine viewY.

Sprite​.ttl

How may frames the sprite should be alive. Primarily used by Pool to know when to recycle an object.

Sprite​.update(​[dt])

Update the sprites position based on its velocity and acceleration. Calls the sprites advance() function.

update Parameters

dt Optional

Number. Time since last update.

Sprite​.velocity

The sprites velocity vector.

Sprite​.viewX

Readonly. X coordinate of where to draw the sprite. Typically the same value as the position vector unless the sprite has been added to a tileEngine.

Sprite​.viewY

Readonly. Y coordinate of where to draw the sprite. Typically the same value as the position vector unless the sprite has been added to a tileEngine.

Sprite​.width

The width of the sprite. If the sprite is a rectangle sprite, it uses the passed in value. For an image sprite it is the width of the image. And for an animation sprite it is the width of a single frame of the animation.

Setting the value to a negative number will result in the sprite being flipped across the vertical axis while the width will remain a positive value.

Sprite​.x

X coordinate of the position vector.

Sprite​.y

Y coordinate of the position vector.