Once upon a time, in my
debut post , I promised to talk about creating sprite animation with sorting by depth ... Well, promises must 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- function Sprite (_img, _frames) {
- this .img = _img;
- this .frames = _frames;
- this .frameWidth = _img.width / _frames;
- }
')
When creating a sprite, we pass a pointer to our image and the number of animation frames, the width of one frame is calculated by itself. Oh yeah, the pictures that I will use for the test:



Now you need to load these images and create sprites:
Copy Source | Copy HTML- var loaded = 0 ;
- var allImgs = 3 ;
- function imgonload () {
- loaded ++;
- if (loaded == allImgs) {
- afterLoad ();
- }
- }
- var img1 = new Image ();
- img1.src = 'img1.png' ;
- img1.onload = imgonload;
- var img2 = new Image ();
- img2.src = 'img2.png' ;
- img2.onload = imgonload;
- var img3 = new Image ();
- img3.src = 'img3.png' ;
- img3.onload = imgonload;
- var spr1, spr2, spr3;
- function afterLoad () {
- spr1 = new Sprite (img1, 3 );
- spr2 = new Sprite (img2, 3 );
- spr3 = new Sprite (img3, 3 );
- }
This code is also very simple, I will not dwell on it.
Now we create SpriteEngine - it will be responsible for the render of our sprites.
Copy Source | Copy HTML- function SpriteEngine (_layers) {
- this .layers = _layers;
- this .renderList = []; // Queue Array For Render
- this .ctx;
- this .startRender = function (_ctx) {
- this .ctx = _ctx;
- this .renderList.length = 0 ;
- for ( var i = 0 ; i < this .layers; i ++) {
- this .renderList [i] = [];
- }
- }
- this .drawSprite = function (_s, _x, _y, _frame, _layer) {
- // Calculate which piece to draw and add
- // this is in the queue for rendering
- if (_frame <= _s.frames) {
- this .renderList [_layer- 1 ] .push ({
- img: _s.img,
- x: _x, y: _y,
- xonimg: _frame * _s.frameWidth,
- yonimg: 0 ,
- imgwidth: _s.frameWidth,
- imgheight: _s.img.height
- });
- }
- }
- this .endRender = function () {
- // Actually draw here
- for ( var i = 0 ; i < this .layers; i ++) {
- for ( var j = 0 ; j < this .renderList [i] .length; j ++) {
- var e = this .renderList [i] [j];
- this .ctx.drawImage (e.img, e.xonimg, e.yonimg, e.imgwidth, e.imgheight, ex, ey, e.imgwidth, e.imgheight);
- }
- }
- }
- }
There may be questions about the
renderList , which is essentially an “array of arrays” (a two-dimensional tobish). The first array stores the layer, the second - objects with parameters for rendering.
Now I’ll add the creation of SpriteEngin, the rendering of our sprites and the regularly increasing
frame variable that is responsible for the current frame of the animation:
Copy Source | Copy HTML- ...
- var frame = 0 ;
- setInterval ( function () {
- if (frame < 2 ) {
- frame ++;
- } else {
- frame = 0 ;
- }
- }, 500 );
- var ctx = document.getElementById ( 'c' ). getContext ( '2d' );
- var se = new SpriteEngine ( 3 );
- ...
- function afterLoad () {
- ...
- setInterval ( function () {
- ctx.fillStyle = '# 007F46' ;
- ctx.fillRect ( 0 , 0 , 640 , 480 );
- se.startRender (ctx);
- se.drawSprite (spr1, 100 , 100 , frame, 3 );
- se.drawSprite (spr2, 116 , 116 , frame, 2 );
- se.drawSprite (spr3, 132 , 132 , frame, 1 );
- se.endRender ();
- }, 25 );
- }
We save, catch bugs and voila :) It should be noted that the numbering of the layers starts from 1, and the more the layer number, the “farther” it is from us. We transfer the maximum number of layers when creating SpriteEngine.
Sources -
tyk .
PS: If someone pours somewhere - I will be grateful :)