Today, we learn how to create animated character with sprite sheets, json and javascript.
We use the below sprites sheet:
https://raw.githubusercontent.com/mozilla/BrowserQuest/master/client/img/1/clotharmor.png
Copyright: Mozilla & Github
And json data: https://raw.githubusercontent.com/mozilla/BrowserQuest/master/client/sprites/clotharmor.json
Copyright: Mozilla & Github
{ "id": "clotharmor", "width": 32, "height": 32, "animations": { "atk_right": { "length": 5, "row": 0 }, "walk_right": { "length": 4, "row": 1 }, "idle_right": { "length": 2, "row": 2 }, "atk_up": { "length": 5, "row": 3 }, "walk_up": { "length": 4, "row": 4 }, "idle_up": { "length": 2, "row": 5 }, "atk_down": { "length": 5, "row": 6 }, "walk_down": { "length": 4, "row": 7 }, "idle_down": { "length": 2, "row": 8 } }, "offset_x": -8, "offset_y": -12 }
First step: analysis the structure of the json file and the sprite sheets
Seeing the json file, we can determine the size of a sprite sheet is 32x32px and there are 9 states of character:
- atk_right: attack right
- walk_right: walk right
- idle_right: idle right
- atk_up: attack up
- walk_up: walk up
- idle_up: idle up
- atk_down: attack down
- walk_down: walk down
- idle_down: idle down
Here are the sprite sheets: (scale 200%)
We test for the walk right state:
HTML
<canvas id="mycanvas" width="32" height="32"></canvas>
Javascript
var canvas = document.getElementById('mycanvas'), ctx = canvas.getContext('2d'), image = new Image(), json = {};//data json var state = 'walk_right';//9 states jQuery.getJSON("https://raw.githubusercontent.com/mozilla/BrowserQuest/master/client/sprites/clotharmor.json", function (data) { json = data.animations[state]; // length, row }); var numr = 1;//total images var n = 0;//number of images loaded image.onload = function () { n += 1; } image.src = 'https://raw.githubusercontent.com/mozilla/BrowserQuest/master/client/img/1/clotharmor.png'; var i = 0; //speed: milisecond per sprite sheet var Speed = 200; //frames per second var fps = 30; function demo() { //wait for load json and images if (n == numr && json.length) { ctx.drawImage(image, (i++) * 32, json.row * 32, 32, 32, 0, 0, 32, 32); if (i == json.length) i = 0; timestart = (new Date()).getTime(); } } setInterval(demo, 1000 / fps);
Result:
However, the sprites are overlapping, we must clear the previous sprite by using clearRec function.
ctx.clearRect(0, 0, canvas.width, canvas.height);
We receive the result below:
However, the character’s movement speed is too fast, we need to control the speed using time:
var canvas = document.getElementById('mycanvas'), ctx = canvas.getContext('2d'), image = new Image(), json = {};//data json var state = 'walk_right';//9 states jQuery.getJSON("https://raw.githubusercontent.com/mozilla/BrowserQuest/master/client/sprites/clotharmor.json", function (data) { json = data.animations[state]; // length, row }); var numr = 1;//total images var n = 0;//number of images loaded image.onload = function () { n += 1; } image.src = 'https://raw.githubusercontent.com/mozilla/BrowserQuest/master/client/img/1/clotharmor.png'; var i = 0; var timestart = (new Date()).getTime(); //speed: milisecond per sprite sheet var Speed = 200; //frames per second var fps = 30; function demo() { //wait for load json and images if (n == numr && json.length) { var delta = (new Date()).getTime() - timestart; if (delta >= Speed) { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.drawImage(image, (i++) * 32, json.row * 32, 32, 32, 0, 0, 32, 32); if (i == json.length) i = 0; timestart = (new Date()).getTime(); } } } setInterval(demo, 1000 / fps);
We receive the result below:
Try it yourself:
https://jsfiddle.net/sans_amour/cp11LL78/2/