A micro framework for JavaScript games.
Handles collision detection, the game update loop, canvas rendering, and keyboard and mouse input.
$ 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. 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(); });
Five demos are included in this repository:
Coquette handles collision detection for rotated entities. It also handles mouse (and keyboard) input. Try dragging a shape in the demo below.
A 2D racing game. Click to play.
A game that uses the Box2D physics engine. Click to play.
Pass in:
"canvas"
."#000"
.var YourGame = function() { this.c = new Coquette(this, "canvas", 150, 150, "#000"); };
When you instantiate Coquette, you get an object that has five 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(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.
Call c.entities.create()
with:
Block
.{ center: { x: 5, y: 10 }, size: { x: 10, y: 30 } }
.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 } });
Call c.entities.destroy()
with:
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 = { collision: function(other) { console.log("Ow,", other, "hit me."); } };
The code is open source, under the MIT licence.