Create a sprite engine

    Once upon a time, in my debut post , I promised to talk about creating sprite animations with sorting by depth ... Well, promises need to be kept :)


    And so, today I will talk about creating a simple sprite engine with support for sorting by depth.
    First, let's create a Sprite class :

    Copy Source  | Copy HTML
    1. function Sprite (_img, _frames) {
    2.     this.img = _img;
    3.     this.frames = _frames;
    4.     this.frameWidth = _img.width / _frames;
    5. }


    When creating a sprite, we pass a pointer to our picture and the number of frames of the animation, the width of one frame will be calculated independently. Oh yes, the pictures that I will use for the test:
    image
    image
    image
    Now you need to download these images and create sprites:

    Copy Source  | Copy HTML
    1. var loaded = 0;
    2. var allImgs = 3;
    3. function imgonload () {
    4.     loaded ++;
    5.     if (loaded == allImgs) {
    6.         afterLoad ();
    7.     }
    8. }
    9. var img1 = new Image ();
    10. img1.src = 'img1.png';
    11. img1.onload = imgonload;
    12. var img2 = new Image ();
    13. img2.src = 'img2.png';
    14. img2.onload = imgonload;
    15. var img3 = new Image ();
    16. img3.src = 'img3.png';
    17. img3.onload = imgonload;
    18. var spr1, spr2, spr3;
    19. function afterLoad () {
    20.     spr1 = new Sprite (img1, 3);
    21.     spr2 = new Sprite (img2, 3);
    22.     spr3 = new Sprite (img3, 3);
    23. }


    This code is also very simple, I will not dwell on it.
    Now create SpriteEngine - it will be he who will be responsible for the rendering of our sprites.

    Copy Source  | Copy HTML
    1. function SpriteEngine (_layers) {
    2.     this.layers = _layers;
    3.     this.renderList = []; // Queue array for rendering
    4.     this.ctx;
    5.     this.startRender = function (_ctx) {
    6.         this.ctx = _ctx;
    7.         this.renderList.length = 0;
    8.         for (var i = 0; i <this.layers; i ++) {
    9.             this.renderList [i] = [];
    10.         }
    11.     }
    12.     this.drawSprite = function (_s, _x, _y, _frame, _layer) {
    13.         // Calculate which piece to draw and add 
    14.         // this is a queue for rendering
    15.         if (_frame <= _s.frames) {
    16.             this.renderList [_layer-1] .push ({
    17.                 img: _s.img,
    18.                 x: _x, y: _y,
    19.                 xonimg: _frame * _s.frameWidth,
    20.                 yonimg: 0,
    21.                 imgwidth: _s.frameWidth,
    22.                 imgheight: _s.img.height
    23.             });
    24.         }
    25.     }
    26.     this.endRender = function () {
    27.         // Here we actually draw
    28.         for (var i = 0; i <this.layers; i ++) {
    29.             for (var j = 0; j <this.renderList [i] .length; j ++) {
    30.                 var e = this.renderList [i] [j];
    31.                 this.ctx.drawImage (e.img, e.xonimg, e.yonimg, e.imgwidth, e.imgheight, ex, ey, e.imgwidth, e.imgheight);
    32.             }
    33.         }
    34.     }
    35. }


    Questions may arise about the renderList , which is essentially an “array of arrays” (two-dimensional tobish). The first array stores the layer, the second - objects with parameters for rendering.
    Now I’ll add the creation of SpriteEngin'a, the drawing of our sprites and the regularly increasing variable frame which is responsible for the current frame of the animation:

    Copy Source  | Copy HTML
    1. ...
    2. var frame = 0;
    3. setInterval (function () {
    4.     if (frame <2) {
    5.         frame ++;
    6.     } else {
    7.         frame = 0;
    8.     }
    9. }, 500);
    10. var ctx = document.getElementById ('c'). getContext ('2d');
    11. var se = new SpriteEngine (3);
    12. ...
    13. function afterLoad () {
    14.         ...
    15.     setInterval (function () {
    16.         ctx.fillStyle = '# 007F46';
    17.         ctx.fillRect (0, 0, 640, 480);
    18.         se.startRender (ctx);
    19.         se.drawSprite (spr1, 100, 100, frame, 3);
    20.         se.drawSprite (spr2, 116, 116, frame, 2);
    21.         se.drawSprite (spr3, 132, 132, frame, 1);
    22.         se.endRender ();
    23.     }, 25);
    24. }


    We save, catch bugs and voila :) It should be noted that the numbering of layers begins with 1, and the larger the number of the layer, the “farther” it is from us. We transfer the maximum number of layers when creating SpriteEngine.

    Sources - tyk .
    PS: If someone floods somewhere - I will be grateful :)

    Also popular now: