viernes, 4 de mayo de 2012

Space Invaders Game using Crafty.js

I created a Space Invaders game located around the Faculty of Informatics of Iasi, as an assignment for the subject Client Side Web Applications Development (CLIW). Here you have FIIInvaders.

The game is a good example of the capabilities of Crafty.js, although it doesn't boast each and everyone of them.

viernes, 6 de enero de 2012

Sprite.js vs Crafty.js


First I'll define both with as much detail as I possibly can...


Sprite.js is a framework that lets you create animations and games using sprites in an efficient way. Its purpose is to allow a common framework for desktop and mobile browsers and use the latest technology available on each platform.

It's centered on animation making, and it doesn't provide all the possible features other provide.
It does provide detailed animation making via sprites (2D with both Parallel and Isometric views being available), basic physics, sprite collision detection, a couple of explosion special effects, time tracking through Ticker objects , ample and simple input control (keyboard, mouse and touchscreen), layers, events, dynamic background support (background that moves around. Sort of keeping a character static and moving the background instead. It preloads it for better efficiency), basic euclidean geometry operations, and path finding.
It is cross browser compatible (tested on WebKit, Firefox, Android phones, Opera and IE9).
Works with both DOM and Canvas. It's relatively lightweight (45.2KB) and doesn't have a compressed version.




Crafty is a lightweight, modular JavaScript game engine designed to easily produce high quality games. Includes a large variety of components such as animation, event management, redraw regions, collision detection, sprites and more.

Boasts the Entity/Component system (a modular, easier and faster to program with approach), animation making via sprites (2D with both Parallel and Isometric views available), multiple graphics support (text, images, sprites...), collision detection, events, input control (keyboard and mouse), audio, basic euclidean geometry operations, and a random number generator.
Boasts being cross browser compatible in all modern browsers. Works with both DOM and Canvas. It weighs 140KB and may surprise you it calls itself lightweight, but it provides a minified and compressed version that lowers it to 14.5KB!




All right, now that you have an idea of what they are, lets get our hands dirty, I'll present first a basic skeleton (in case you're like me, and like to have a fast starting point and test libraries for yourself) and then the basics of a shooter.


A basic skeleton for Sprite.js:

<!DOCTYPE html>
<html>
<head>
<title>
Testing...
</title>
<meta name="viewport" content="user-scalable=no, width=device-width">
</head>
<body>
<p>
This is a paragraph
</p>
<span id="debug"></span>
</body>
</html>




A basic skeleton for Crafty.js:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript" src="crafty.js"></script>
<script type="text/javascript" src="game.js"></script>
<title>Crafty.js Skeleton</title>
<style>
body, html { margin:0; padding: 0; overflow:hidden; font-family:Arial; font-size:20px }
#cr-stage { border:2px solid black; margin:5px auto; color:white }
</style>
</head>
<body>
</body>
<script>
window.onload = function ()
{
//start crafty
Crafty.init(400, 336);
//Crafty.canvas.init();
};
</script>
</html>



A basic shooter (press F5 if the link appears blank) for Sprite.js:

<!DOCTYPE html>
<html>
<head>
<title>
The basics of a shooter
</title>
<meta name="viewport" content="user-scalable=no, width=device-width">
</head>
<body>
<span id="debug"></span>
</body>
<script src="./sprite.js"></script>
<script>
window.onload = function()
{
// Size of the viewport
var viewportX = window.innerWidth;
var viewportY = window.innerHeight;

// Stablishing the scene
var result = document.getElementById('result');
var scene = sjs.Scene({w:viewportX,h:viewportY});

var input = scene.Input();

var lastMouseX = input.mouse.position.x;
var lastMouseY = input.mouse.position.y;

var background = scene.Sprite();

var crosshair = scene.Sprite('crosshair.png');
var crosshairSizeX = 50;
var crosshairSizeY = 50;
crosshair.size(crosshairSizeX, crosshairSizeY);

function paint()
{
// Setting up the background
background.position(0,0);
background.size(viewportX,viewportY);
background.setColor('#000');
background.update();

// Drawing a crosshair
// First update the position depending on the mouse
if((lastMouseX != input.mouse.position.x)||(lastMouseY != input.mouse.position.y))
{
lastMouseX = input.mouse.position.x;
lastMouseY = input.mouse.position.y;
}

// Then it's actually drawn
crosshair.position(lastMouseX-(crosshairSizeX/2), lastMouseY-(crosshairSizeY/2));
crosshair.update();

// Now we only need to randomly generate enemies and check positions on click to have a basic shooter!
};

// Stablish the game loop, repaint every 30 ms
var ticker = scene.Ticker(30, paint);
ticker.run();
};
</script>
</html>






A basic shooter for Crafty.js:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript" src="crafty.js"></script>
<title>
The basics of a shooter
</title>
<style>
body, html { margin:0; padding: 0; overflow:hidden; font-family:Arial; font-size:20px }
#cr-stage { border:0px solid black; margin:0px auto; color:white }
</style>
</head>
<body>
</body>
<script>
window.onload = function ()
{
// Size of the viewport
var viewportX = Crafty.DOM.window.width;
var viewportY = Crafty.DOM.window.height;

// Start crafty
Crafty.init(viewportX, viewportY);

// Turn the sprite map into usable components
Crafty.sprite(50, "crosshair.png", {crosshair: [0,0]});

Crafty.scene("main", function ()
{
// Black background
Crafty.background("#000");
Crafty.load("crosshair.png");

var crosshair = Crafty.e("2D, DOM, crosshair").attr({x: -100, y: -100});

function repaintCrosshair(e)
{
var pos = Crafty.DOM.translate(e.clientX-25, e.clientY-25);

crosshair.x = pos.x;
crosshair.y = pos.y;
}

// Every time the event is fired (because the mouse was moved) the crosshair is repainted
Crafty.addEvent(this, Crafty.stage.elem, "mousemove", repaintCrosshair);
}
);

Crafty.scene("main");
};
</script>
</html>





Conclusion:

After having played with both engines, I can come to the conclusion that Sprite.js is better when dealing with animations or simple games, and Crafty.js excels at building complex games that require large amounts of code.

Sprite.js makes your life extremely easy when dealing with physics and animations, and being able to work with touchscreens gives it a fair advantage when aiming towards the cell phone market.

Crafty.js boasts the Entity/Component Model, that allows you to simplify the complex abstractions that a bigger game implies. We can make an analogy with the classic Object Orientated Programming by comparing Components to Classes and Entities to Instancies.

In fact, when working with Crafty, before defining the Scene, you can define Components, that will define an abstract element of the game (such an NPC) with both data members and methods, and later, once the Scene is defined, create an Entity (instantiate the Component) to get an object that will be able to provide the defined behaviour in a very fast and simple way.

In order to clarify this model's use, I will provide a simple piece of script, where you can see both the use of Components and Entities:

Crafty.c("MyClass",
{
_PrivateDataMember: 0,
PublicDataMember: 0,

init: function()
{
// A constructor
},

aMethod: function()
{
// Some code...
}
});





Crafty.scene("MyScene", function()
{
// Instantiate MyClass
var myInstance = Crafty.e("MyClass");

// Now use its interface...
myInstance.aMethod();
});



Summary


Here you can find a presentation that summarizes this entry.



Reference