Fork me on GitHub

Coquette


A micro framework for JavaScript games.

Handles collision detection, the game update loop, canvas rendering, and keyboard and mouse input.

Get the code

Example

A game where you, the valiant player, must find a person of indeterminate gender in distress so you can take them away from all this. Click on the game, then press the up arrow key to play.

The HTML below defines a canvas element and loads in Coquette and the game code.

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript" src="../../coquette.js"></script>
    <script type="text/javascript" src="game.js"></script>
  </head>
  <body><canvas id="canvas"></canvas></body>
</html>

The game code:

var Game = function() {
  this.c = new Coquette(this, "canvas", 500, 150, "#000");

  // paramour
  this.c.entities.create(Person, { center: { x:250, y:40 }, color:"#099" });

  // player
  this.c.entities.create(Person, { center: { x:256, y:110 }, color:"#f07",
    update: function() {
      if (this.c.inputter.isDown(this.c.inputter.UP_ARROW)) {
        this.center.y -= 0.4;
      }
    },

    collision: function(other) {
      other.center.y = this.center.y; // follow the player
    }
  });
};

var Person = function(game, settings) {
  this.c = game.c;
  for (var i in settings) {
    this[i] = settings[i];
  }

  this.size = { x:9, y:9 };
  this.draw = function(ctx) {
    ctx.fillStyle = settings.color;
    ctx.fillRect(this.center.x - this.size.x / 2,
                 this.center.y - this.size.y / 2,
                 this.size.x,
                 this.size.y);
  };
};

window.addEventListener('load', function() {
  new Game();
});

Demos

Four demos are included in this repository:

Spinning shapes

Coquette handles collision detection for rotated entities. It also handles mouse (and keyboard) input. Try dragging a shape in the demo below.

Box2D physics

A game that uses the Box2D physics engine. Click the image to play.

Left Right Space

A complete game. Click the image to play.


Reference

Instantiate Coquette

Pass in:

var YourGame = function() {
  this.c = new Coquette(this, "canvas", 150, 150, "#000");
};

Modules

When you instantiate Coquette, you get an object that has five modules. You can use these modules in your game.

Entities

Keeps track of all the entities in the game: the player, enemies, obstacles.

Define an entity

Most entities will have these attributes:

And these methods:

For example:

var Block = function(game, settings) {
  this.game = game;
  this.center = settings.center;
  this.size = settings.size;
  this.angle = 30;
};

Block.prototype = {
  update: function(timeSinceLastTick) {
    this.center.x += 0.02 * timeSinceLastTick;
    this.center.y += 0.02 * timeSinceLastTick;
  },

  draw: function(canvasCtx) {
    ctx.fillStyle = "black";
    ctx.fillRect(this.center.x - this.size.x / 2,
                 this.center.y - this.size.y / 2,
                 this.size.x,
                 this.size.y);
  }
};

See the Collider section for instructions on enabling collision detection.

Create an entity

Call c.entities.create() with:

Returns the created entity.

var Block = function(game, settings) {
  this.game = game;
  this.center = settings.center;
  this.size = settings.size;
  this.angle = 0;
};

var myBlock = c.entities.create(Block, {
  center: { x: 5, y: 10 },
  size: { x: 10, y: 30 }
});
Destroy an entity

Call c.entities.destroy() with:

c.entities.destroy(myBlock);
Get all the entities in the game
var all = c.entities.all();
Get all the entities of a certain type
var invaders = c.entities.all(Invader);

Inputter

Handles keyboard and mouse input from the player.

Find out if a certain key or mouse button is down
var leftArrowDown = c.inputter.isDown(c.inputter.LEFT_ARROW);
var rightMouseDown = c.inputter.isDown(c.inputter.RIGHT_MOUSE);
Find out if a certain key or mouse button is pressed

This returns true for the tick following the key going down. In subsequent ticks, it returns false until the key is released and pressed down again.

var leftArrowPressed = c.inputter.isPressed(c.inputter.LEFT_ARROW);
var rightMousePressed = c.inputter.isPressed(c.inputter.RIGHT_MOUSE);
Run a function every time the mouse is moved
c.inputter.bindMouseMove(function(position) {
  console.log("The mouse is at", position.x, position.y);
});

position is relative to the game canvas. If the mouse pointer is in the top left corner, position will be { x: 0, y: 0 }.

Get the current mouse position
var position = c.inputter.getMousePosition();

position is relative to the game canvas. If the mouse pointer is in the top left corner, position will be { x: 0, y: 0 }.

Renderer

Holds the canvas drawing context. Calls draw() on the main game object and all the game entities.

Draw an entity

See the Define an Entity sub-section of the Entities section.

Get the canvas drawing context
var ctx = c.renderer.getCtx();
ctx.fillStyle = "#f00";
ctx.fillRect(0, 0, 10, 10);
Set the order that entities are drawn

When you create your entities, set an integer zindex attribute on them. An entity with a higher zindex will get drawn on top of an entity with a lower zindex. The default zindex is 0.

var BackgroundTile = function() {
  this.zindex = -1;
};

var Player = function() {
  this.zindex = 0;
};

c.entities.create(BackgroundTile, {});
c.entities.create(Player, {}); // drawn on top
Move the view

You can use c.renderer.setViewCenter() to move the view around the world. For example, to make the view follow a specific object, you could call setViewCenter(specificObj.center) in the update() function of your game:

var Game = function() {
  var c = new Coquette(this, "canvas", 500, 500, "#000");
  var specialObject = c.entities.create(SpecialObject, {});

  this.update = function() {
    c.renderer.setViewCenter(specialObject.center);
  };
};

Collider

Reports when entities collide.

Entity setup

To make an entity support collisions, put these attributes on it:

And, optionally, these methods:

For example:

var Player = function() {
  this.center = { x: 10, y: 20 };
  this.size = { x: 50, y: 50 };
  this.boundingBox = c.collider.CIRCLE;
  this.angle = 0;
};

Player.prototype = {
  collision: function(other, type) {
    if (type === c.collider.INITIAL) {
      console.log("Ow,", other, "hit me.");
    } else if (type === c.collider.SUSTAINED) {
      console.log("Ow,", other, "is still hitting me.");
    }
  },

  uncollision: function(other) {
    console.log("Phew,", other, "has stopped hitting me.");
  }
};

Licence

The code is open source, under the MIT licence.