Giter Club home page Giter Club logo

sprite.js's Introduction

sprite.js v1.0.0

The sprite.js framework lets you create animations and games using sprites in an efficient way. The goal is to have common framework for Desktop and mobile browsers.

sprite.js has been tested on Chromium, Firefox, Android emulator, Opera and IE9.

For an example of the what the framework offers, have a look at the test files:

http://batiste.dosimple.ch/sprite.js/tests/

Example usage

Example of a basic use:

<script src="sprite.js"></script>

<script>
// set the Scene object
var scene = sjs.Scene({w:640, h:480});

// load the images in parallel. When all the images are
// ready, the callback function is called.
scene.loadImages(['character.png'], function() {

    // create the Sprite object;
    var sp = scene.Sprite('character.png');

    // change the visible size of the sprite
    sp.h=55;
    sp.w=30;
    // apply the latest visual changes to the sprite;
    sp.update();

    // change the offset of the image in the sprite (this works the opposite way of a CSS background)
    sp.offset(50, 50);

    // diverse transformations
    sp.move(100, 100);
    sp.rotate(3.14 / 4);
    sp.scale(2);
    sp.opacity = 0.8;

    sp.update();
});
</script>

Performance and different ways to draw

This library provides 2 rendering backends: HTML and canvas.

By default the HTML backend is used. The HTML backend displays sprites using DOM elements when the canvas backend draw the sprites on the canvas. Each layer of the application can have a different backend. This enable you to mix the 2 technics if needed.

To use canvas with a layer you need to specify it in the options:

var background = scene.Layer('background', {useCanvas:true});

The canvas will be automaticaly cleared by the game ticker. If you don't need it you can set the autoClear to false when building a layer:

var background = scene.Layer('background', {useCanvas:true, autoClear:false});

Performances on particle test can be quite different depending on the device and browser and plateform:

Browsers Chrome linux Opera linux Firefox linux HTC Desire (webkit) IE9
HTML backend 2000 60 500 120 30
Canvas backend 1300 100 300 80 600

Scene object

The scene object is where all the Sprites will be drawned. You always need to start by creating a scene:

var scene = sjs.Scene({w:640, h:680});

A list of the different methods available on the Scene object:

scene.loadImages(Arrar(<src>), callback)       // load the array of image source. When all is loaded, the callback is called.

scene.Layer(<name>, <options>)                 // build a Layer object, see next Layer section

scene.Sprite(<src>, <layer>)                   // build a Sprite object, see Sprite section

scene.Ticker(<tickDuration>, <paint function>) // build a Ticker object for this scene or reset the previous one

scene.reset()                                  // Delete all layer present in this scene, delete ticker.

scene.Cycle(<triplets>)                        // alias for sjs.Cycle, look at Cycle section

scene.Input()                                  // alias for sjs.Input, look at Input section

Sprite object public methods and attributes

To create a sprite you should use the scene.Sprite constructor:

var sprite = scene.Sprite(<src>, <layer>)

Both parameters are optionnal. If the layer is not specified, the default layer will be used. If you want to set the layer but not any image:

var sprite = scene.Sprite(false, <layer>)

You can also init any Sprite properties by passing an options object instead of the Layer object, eg:

var sprite = scene.Sprite("mysprite.png", {layer:layer, x:10, size:[20, 20], y:15})

For technichal and performance reasons Sprite's attributes needs to be changed using a setters method. The following attributes are READ ONLY:

sprite.x        // position of the sprite from the left corner of the scene
sprite.y        // position of the sprite from the top corner of the scene

sprite.w        // controls the visible surface of the image. To have a repeating sprite background
                // you can set the width or height value bigger than the size of the image.
sprite.h

sprite.xoffset  // offset in the image to start painting in the view surface
sprite.yoffset
sprite.xscale   // vertical and horizontal scaling
sprite.yscale
sprite.angle    // use radians
sprite.opacity  // use float in the range 0-1
sprite.color    // background color of the sprite. Use the rgb/hexadecimal CSS notation.

If you want to change any of those attributes use the following setters:

sprite.setX(10);
sprite.setY(12);
sprite.setW(32);
sprite.setH(32);
sprite.setXOffset(10); // offset in the image to start painting in the view surface
sprite.setYOffset(5);
sprite.setXScale(2);
sprite.setYScale(3);
sprite.setAngle(Math.PI / 2);
sprite.setColor('#333');
sprite.setOpacity(0.5);

Or one of those helper methods:

sprite.rotate(radians)
sprite.scale(x, y)      // if y is not defined, y take the same value as x
sprite.move(x, y)       // move the sprite in the direction of the provided vector (x, y)
sprite.position(x, y)   // set the position of the sprite
sprite.offset(x, y)
sprite.size(w, h)       // set the width and height of the visible sprite

Sprites comes with a bunch of methods to help you to implement a physic effects:

sprite.xv                // horizontal velocity
sprite.yv                // vertical velocity
sprite.rv                // radial velocity
sprite.applyVelocity()   // apply all velocities on the current Sprite
sprite.reverseVelocity() // apply all the negative velocities on the current Sprite

sprite.applyXVelocity()    // apply the horizontal xv velocity
sprite.applyYVelocity()    // apply the vertical yv velocity
sprite.reverseXVelocity()  // apply the horizontal xv velocity negatively
sprite.reverseYVelocity()  // apply the vertical yv velocity negatively

sprite.isPointIn(x, y)      // return true if the point (x, y) is within the sprite surface

sprite.collidesWith(sprite) // return true if the sprite is in collision with the other sprite

sprite.collidesWithArray([sprites]) // Search in  an array of sprite for a colliding sprite.
                                    // If found, a sprite is returned.

sprite.distance(sprite)     // return the distance between 2 sprite center
sprite.distance(x, y)       // return the distance between the sprite center and the point (x, y)

There is also 2 methods that can help to create special effects. You can use explode2 to separate the current sprite in 2 parts:

// Return 2 new sprites split the sprite in half according to the position. 
// Default value for position is half the size of the sprite.
[sprite1, sprite2] = sprite.explode2(<position>, <bool horizontal>, <layer>)

// Return 4 new sprites that are the split from the center (x, y). 
// Default value for the center is the center of the sprite.
[sprite1, sprite2, sprite3, sprite4] = sprite.explode4(<x>, <y>, <layer>)

Other important methods:

sprite.loadImg(src, <bool resetSize>)    // change the image sprite. The size of the sprite will be reseted by
                                         // the new image if resetSize is true.

sprite.remove // Remove the dom element if the HTML backend is used and facilite the garbage collection of the object.


sprite.canvasUpdate(layer)  // draw the sprite on a given Canvas layer. This doesn't work with an HTML layer.

To update any visual changes to the view you should call the "update" method:

Sprite.update()

With a canvas backend, the surface will be automaticaly cleared before each game tick. You will need to call update to draw the sprite on the canvas again. If you don't want to do this you can set the layer autoClear attribute to false.

SpriteList object

SpriteList is a convenience list type object that enable you to delete and add sprites without having to care about indexes and for loop syntax:

var sprite_list = sjs.SpriteList(<array of sprites>)

sprite_list.add(sprite || array of sprite)  // add to the list
sprite_list.remove(sprite)                  // delete from the list
sprite_list.iterate()                       // iterate on the entire list then stops
sprite_list.list.length                     // length of the list
sprite_list.list                            // the actual list of sprite

Example of use:

var crates = sjs.SpriteList([crate1, crate2]);

var crate;
while(crate = crates.iterate()) {
    crate.applyVelocity();
    if(crate.y > 200) {
        // remove it from the list
        crates.remove(crate);
        // remove it from the DOM
        crate.remove();
    }
}

Ticker object

Keeping track of time in javascript is tricky. Sprite.js provides a Ticker object to deal with this issue.

A ticker is an object that keeps track of time properly, so it's straight forward to render the changes in the scene. The ticker gives accurate ticks. A game tick is the time between every Sprites/Physics update in your engine. To setup a ticker:

function paint() {

    myCycles.next(ticker.lastTicksElapsed);
    // do your animation and physic here

}
var ticker = scene.Ticker(35, paint); // we want a tick every 35ms
ticker.run();

ticker.pause();
ticker.resume();

lastTicksElapsed is the number of ticks elapsed during 2 runs of the paint function. If performances are good the value should be 1. If the number is higher than 1, it means that there have been more game ticks than calls to the paint function since the last time paint was called. In essence, there were dropped frames. The game loop can use the tick count to make sure it's physics end up in the right state, regardless of what has been rendered.

Cycle object

A cycle object handles sprite animations by moving the offsets of the sprite. A cycle is defined by list of tuples: (x offset, y offset, game tick duration), and the sprites the cycle applies to. this is a cycle with 3 position, each lasting 5 game ticks:

var cycle = scene.Cycle([[0, 2, 5],
                          [30, 2, 5],
                          [60, 2, 5]);
var sprite = scene.Sprite("walk.png");
cycle.addSprite(sprite);

var sprites = [sprite1, sprite2];
cycle.addSprites(sprites);  // add an Array of sprites to the cycle

cycle.removeSprite(sprite); // remove the sprite from the cycle

cycle.next()         // apply the next cycle to the sprite
cycle.next(1, true)  // apply the next cycle *and* call update() on the sprites
cycle.next(2)        // apply the second next cycle to the sprite
cycle.goto(1)        // go to the second game tick in the triplet
cycle.reset()        // reset the cycle to the original position
cycle.repeat = false // if set to false, the animation will stop automaticaly after one run
cycle.done           // can be used to check if the cycle has completed
                     // stays false if cycle is set to repeat = true

cycle.update()       // calls update() on all the sprites in the cycle

Input object

The input object deals with user input. There are a number of flags for keys that will be true if the key is pressed:

var input  = scene.Input();
if(input.keyboard.right) {
    sprite.move(5, 0);
}

Input.keyboard is a memory of which key is down and up. This is a list of the flags available in the keyboard object:

keyboard.up
keyboard.right
keyboard.up
keyboard.down
keyboard.enter
keyboard.space
keyboard.ctrl

You also have access to those helpers on the input object:

input.arrows() // arrows return true if any directionnal keyboard arrows are pressed
input.keydown  // this is true if any key is down

If you need to know which key has just been pressed or released during the last game tick you can use those methods:

input.keyPressed('up')
input.keyReleased('up')

Layer object

If you need to separate you sprites into logical layers, you can use the Layer object:

var background = scene.Layer('background', options);

You should then pass the layer as the second argument of the contructor of your sprites:

var sprite = scene.Sprite('bg.png', background);

The layer object can take those options:

var options = {
    useCanvas:true,   // force the use of the canvas on this layer, that enable you to mix HTML and canvas
    autoClear:false   // disable the automatic clearing of the canvas before every paint call.
}

sprite.js's People

Contributors

ardcore avatar runeh avatar cosimo avatar batiste avatar greut avatar

Stargazers

tom zhou avatar

Watchers

tom zhou avatar James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.