chem
canvas-based game engine and toolchain optimized for rapid development.
Features
- Automatically creates a spritesheet for your assets and then
loads the assets at runtime.
- Provides convenient API for drawing animated sprites in a canvas
- Supports anchor points and rotation
- Write code in JavaScript or other compile-to-javascript
languages such as Coffee-Script.
- Uses browserify to compile
your code which allows you to harness the power of code on npm.
- For example, A* search
- Allows you to organize code modules using
require
and module.exports
syntax.
- Everything from code to spritesheet is compiled automatically
when you save.
- Handles main loop and frame skipping.
- Convenient API for keyboard and mouse input.
Usage
sudo apt-get install libcairo2-dev
cd my-project
npm install chem-cli
./node_modules/.bin/chem init
npm run dev
./node_modules/.bin/chem
See chem-cli for more information.
Synopsis
Layout
Source files
./chemfile.js
./src/main.js
./public/index.html
./assets/img/ship.png
./assets/img/explosion/01.png
...
./assets/img/explosion/12.png
Generated files
./public/main.js
./public/spritesheet.png
./public/animations.json
./src/main.js
var chem = require("chem");
var v = chem.vec2d;
chem.onReady(function () {
var canvas = document.getElementById("game");
var engine = new chem.Engine(canvas);
var batch = new chem.Batch();
var boom = new chem.Sound('sfx/boom.ogg');
var ship = new chem.Sprite('ship', {
batch: batch,
pos: v(200, 200),
rotation: Math.PI / 2
});
var shipVel = v();
var rotationSpeed = Math.PI * 0.04;
var thrustAmt = 0.1;
var fpsLabel = engine.createFpsLabel();
engine.on('update', function (dt, dx) {
ship.pos.add(shipVel);
if (engine.buttonState(chem.button.KeyLeft)) {
ship.rotation -= rotationSpeed * dx;
}
if (engine.buttonState(chem.button.KeyRight)) {
ship.rotation += rotationSpeed * dx;
}
var thrust = v(Math.cos(ship.rotation), Math.sin(ship.rotation));
if (engine.buttonState(chem.button.KeyUp)) {
shipVel.add(thrust.scaled(thrustAmt * dx));
}
if (engine.buttonState(chem.button.KeyDown)) {
shipVel.sub(thrust.scaled(thrustAmt * dx));
}
if (engine.buttonJustPressed(chem.button.KeySpace)) {
boom.play();
ship.setAnimationName('boom');
ship.setFrameIndex(0);
ship.on('animationend', function() {
ship.delete();
});
}
});
engine.on('draw', function (context) {
context.fillStyle = '#000000'
context.fillRect(0, 0, engine.size.x, engine.size.y);
batch.draw(context);
fpsLabel.draw(context);
});
engine.start();
canvas.focus();
});
./chemfile.js
exports.main = 'src/main';
exports.spritesheet = {
defaults: {
delay: 0.05,
loop: false,
anchor: "center"
},
animations: {
boom: {
frames: "explosion"
},
ship: {}
}
};
./public/index.html
<!doctype html>
<html>
<head>
<title>Chem Example</title>
</head>
<body style="text-align: center">
<canvas id="game" width="853" height="480"></canvas>
<p>Use the arrow keys to move around and space to destroy yourself.</p>
<script type="text/javascript" src="main.js"></script>
</body>
</html>
See the demo in action.
Demo Projects Using Chem
Developing With Chem
Chemfile
Start by looking at your chemfile
. This file contains all the instructions
on how to build your game.
This file, like every other source file in your game, can be in any compile-
to-JavaScript language (including JavaScript itself) that you choose.
Use any "compile to JS" language
Supported languages:
Getting Started
The first step is to require "chem":
var chem = require('chem');
chem.onReady(function() {
});
Vec2d Convention
As a convention, any Vec2d
instances you get from Chem are not clones.
That is, pay careful attention not to perform destructive behavior on the
Vec2d
instances returned from the API.
Not Using a Spritesheet
If you omit the spritesheet object in your chemfile, no spritesheet files
will be generated. Be sure to set chem.useSpritesheet = false
in your app code to avoiding attempting to load the missing resources.
Reference API Documentation
See doc/api.md.
History / Changelog
See doc/history.md.
Developing chem
See also chem-cli
sudo apt-get install libcairo2-dev
sudo npm link