coquette

A micro framework for JavaScript games.

Coquette

A micro framework for JavaScript games.

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

http://coquette.maryrosecook.com

  • Minified: https://github.com/maryrosecook/coquette/coquette-min.js
  • Single file: https://github.com/maryrosecook/coquette/coquette.js
  • GitHub: https://github.com/maryrosecook/coquette
  • $ npm install coquette

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. The code below appears in /demos/simple/. Open /demos/simple/index.html 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.= 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",
    updatefunction() {
      if (this.c.inputter.isDown(this.c.inputter.UP_ARROW)) {
        this.center.y -= 0.4;
      }
    },
 
    collisionfunction(other) {
      other.center.y = this.center.y; // follow the player 
    }
  });
};
 
var Person = function(gamesettings) {
  this.= 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();
});

Five demos are included in this repository:

  • /demos/spinning-shapes - an example of collisions between rotated entities.
  • /demos/racecar - a 2D racing game.
  • /demos/box2d-physics - a game that uses the Box2D physics engine.
  • /demos/leftrightspace - a complete game.
  • /demos/simple - the example at the top of this readme.

Pass in:

  • Your main game object.
  • The ID of the canvas element, e.g. "canvas".
  • The desired width of the canvas element.
  • The desired height of the canvas element.
  • The background colour of your game, e.g. "#000".
var YourGame = function() {
  this.= new Coquette(this, "canvas", 150, 150, "#000");
};

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

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

Most entities will have these attributes:

  • center: The center of the entity, e.g. { x: 10, y: 20 }
  • size: The size of the entity, e.g. { x: 50, y: 30 }
  • angle: The orientation of the entity in degrees, e.g. 30

And these methods:

  • update(timeSinceLastTick): Called every tick. You should change the state of the entity in this method.
  • draw(canvasCtx): Called every tick. You should draw the entity upright in this method. The drawing will automatically get rotated to the orientation indicated by angle.

For example:

var Block = function(gamesettings) {
  this.game = game;
  this.center = settings.center;
  this.size = settings.size;
  this.angle = 30;
};
 
Block.prototype = {
  updatefunction(timeSinceLastTick) {
    this.center.x += 0.02 * timeSinceLastTick;
    this.center.y += 0.02 * timeSinceLastTick;
  },
 
  drawfunction(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.

Call c.entities.create() with:

  • The constructor function of the entity you want to create, e.g. Block.
  • An optional settings object that will be passed into the constructor, e.g. { center: { x: 5, y: 10 }, size: { x: 10, y: 30 } }.

Returns the created entity.

var Block = function(gamesettings) {
  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 }
});

Call c.entities.destroy() with:

  • The entity you want to destroy, e.g. myBlock.
c.entities.destroy(myBlock);
var all = c.entities.all();
var invaders = c.entities.all(Invader);

Handles keyboard and mouse input from the player.

var leftArrowDown = c.inputter.isDown(c.inputter.LEFT_ARROW);
var rightMouseDown = c.inputter.isDown(c.inputter.RIGHT_MOUSE);

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);
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 }.

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 }.

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

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

  var ctx = c.renderer.getCtx();
  ctx.fillStyle = "#f00";
  ctx.fillRect(0, 0, 10, 10);

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 

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);
    };
  };

Reports when entities collide.

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

  • center: The center of the entity, e.g. { x: 10, y: 20 }.
  • size: The size of the entity, e.g. { x: 50, y: 30 }.
  • boundingBox: The shape that best approximates the shape of the entity, either c.collider.RECTANGLE or c.collider.CIRCLE.
  • angle: The orientation of the entity in degrees, e.g. 30.

And, optionally, this method:

  • collision(other): Called when the entity collides with another entity. Takes other, the other entity involved in the collision.

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 = {
  collisionfunction(other) {
    console.log("Ow,", other, "hit me.");
  }
};

Install Node.js and npm: https://github.com/isaacs/npm

Install the node dependencies and run the tests with:

$ cd path/to/coquette
$ npm install --dev
$ npm test