Creating An Eternal Animation With Crafty.js

Crafty.js is not a game engine but a game framework, as says his developer Louis Stow. And in fact, Crafty.js is a tool that helps creating web games using only Open Web technologies (meaning, HTML, JS and CSS).

I discovered it recently, and it seemed interesting to me for our Web Game Engine project (I’ll be telling more about it soon), so I tried it out. Well, it appears to me that, as many young tools, the documentation is still not very complete, and so it’s not really easy to get Crafty to work fully. The real things that are missing in my opinion are examples of functional source code. And as I was doing some experiments on my own, I thought I could participate by giving some of those missing examples.

So, here we go: I set up a GitHub repository called crafty-examples. There is only a single example for the moment, but others will come as I will continue to work on Crafty. Let’s go a little further in the Crafty world, and explain how this first example works.

Component / Entity Model

The first and most important thing to understand if you want to go deep with Crafty is the Component / Entity model. This model seems to be particularly suitable to games. Basically, every object in the game is an Entity that is composed of many Components. An empty Entity does almost nothing, but every Component that is added to it extends its functionalities. Using this model, you avoid the problems induced by a classical hierarchical architecture, and get a very flexible code. To learn more about this model, I invite you to read Evolve Your Hierarchy by Mick West.

Creating a Component

Crafty comes with the main components you will need (check the API documentation out), but you will surely have to extend it with your own sooner or later. Creating a new Component is very simple :

Crafty.c("my_component_id", function() {
    // Here we define our component

The Crafty.c() function creates a new Component and adds it to the Crafty core object so you can use it later. The Crafty.e() function creates and returns a new Entity, that is an object you will manipulate and often display on your game.

Let’s take a look at the Animation example I was talking about:

// Declare a Component called "animation"
    Crafty.c("animation", {
        init: function() {
            // If the "animate" component is not added to this one, then add it
            if (!this.has("animate"))


There is already an Animate Component in Crafty, but it plays the animation once, then stops it if nothing is done. I wanted to have a component that plays an animation eternally. A cool thing about the Components is that one can contain some others: in the init() function of my Animation component, I check if it contains the Animate component, and if not, I add it so I can use it.

Note: the init() function of a component is automatically called when the Component is constructed.

Crafty Events

Now we have a component that can be animated (thanks to the Animate component), we have to relaunch the animation when it is finished. To do that, we will bind a function to the “enterframe” event. This event is fired every time a frame is displayed. That means, if you set 50 as frame rate in the Crafty.init() method, then the “enterframe” will be fired 50 times in a second.

// Bind the "enterframe" event, called every time the frame is displayed
this.bind("enterframe", function() {
    // If the animation is not playing anymore, then reload it
    if (!this.isPlaying("anim"))
        this.sprite(4, 0, 1, 1);   // Go back to the first sprite of the animation
        this.animate("anim", 20);  // Launch the animation, changing sprite every 20ms

What I am doing here is simple too: every frame, I check if the animation is still playing (the this.isPlaying() method comes from the Animate component), and if not, I reset the sprite to the first then launch the animation once again.

Some details about the parameters: “anim” is the name of the currently playing animation. Here I only have one so it works, but in a real case that code would be awful. Same thing for the sprite() parameters, which are hard-coded here for simplicity, but should absolutely not be!

Using our Entity

Okay, we built a cool Component that can infinitely animate some sprites. Now we have to use it, and to do so, we have to create a new Entity.

// Create a new entity which is a mino (previously declared sprite),
// an animation (previously declared component), a 2D and a DOM element.
var mino = Crafty.e("2D, DOM, mino, animation")
    .attr({x: 0, y: 0, w: 128, h: 128}) // Set the position
    .animate("anim", 5, 0, 11);         // Create the "anim" animation,
                                        // starting from coordinate x=5 and going to x=11, with y=0

As you can see in this code, Crafty methods can be chained as with jQuery for example. Here we create a new Entity containing 4 Components: 2D (for the position), DOM (so it can be displayed), mino (the sprite resource declared previously in the code) and animation (the component we just created). The animate() method creates the animation called “anim”, which goes from column x=5 to x=11 on the row y=0.

And that’s it! We have a beautiful minotaur running on our browser.

To Crafty or not to Crafty?

Crafty.js looks great to create web browser games. I still don’t know if it will be useful for our own game engine project, but there are surely good things to take from this tool. As you may see from this example, it’s not hard to do simple cool stuff, but I hope it will be easier with a tutorial like this one.

Oh, and Crafty is still very young, maybe it’s not a good idea to use it now in a “big” project. Hum. Well, I guess if we use WebSockets, we can certainly use Crafty!

To go further…

This entry was posted in Tools. Bookmark the permalink.

2 Responses to Creating An Eternal Animation With Crafty.js

  1. Pingback: Les tweets qui mentionnent Creating An Eternal Animation With Crafty.js | Programmateur --

  2. Nathan says:

    Thanks for the tutorial! I don’t think it’s the current version, but your explanations really helped me wrap my mind around it. Thanks again!

Leave a Reply to Nathan Cancel reply

Your email address will not be published. Required fields are marked *


You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>