^

Monday, January 27, 2014

HTML5 RPG TUTORIAL - Sprites and Animation [Crafty]



Hi, this is the third part of the long tutorial "HTML5 RPG TUTORIAL" for Crafty. In this part, we will learn how to manage sprites and animation with crafty, and how to implement it to the real role-playing games.


You can visit another part of this tutorial here:

4. Controlling Player Movement
5. Collision Detection
6. Moving NPC

Actually, I want to apologize to you all, for abandoned this blog for very loooong time. And now here I am back, with new spirit. New spirit to share my knowledge to the world! And spirit to keep writing high quality post that will help you all on creating your own games. So, shall we?

Sprites


OK, in this post we will talk about sprites, and animation using Crafty right? Before we do the animation, first we must now what Sprites is. Sprites is like part of animation, frame per frame, that make walk animation like walking. If you want to make walk animation, so you must have walk sprites first, that contains picture of someone walking frame per frame. Well, lets just see the example of Sprites. I know this sprite is so ugly, because I created it my self, so lets get along with it. Here it is, Ninja Walking Sprites by me :D



So, do you get an idea what sprite is now, right? This is 8 frame walking sprites. You can also use 4 frame walking sprites, its up to you. But more frames mean more smoother the animation. Just remember that.


Before we use sprites on tilesets or animation, we must define it first on Crafty. Here is the code to define the sprites on Crafty.
Crafty.sprite(64, "img/Ninja-Walk-8.png",
{ ninja: [0,0] });

It'll define new sprite 64 x 64 pixels from "img/Ninja-walk-8.png" and name it ninja on the first column and row.

Tilesets


Well, almost all RPG games terrains, lands, walls, and other objects are made up from tiles. All tiles that's been used on the games, collected into one big image, that is Tilesets. Tilesets is like Sprites but it's not meant to be animated (sorry if I'm wrong but, you get the differences right?). Here are some tilesets that I created with Gimp.




With that tilesets above, we can create something like this.



We can create a stage in Crafty from tilesets with this code:
Crafty.sprite(32, 48, "img/Sprites.png", 
{
  grass_one:[0,0], 
  grass_two:[1,0], 
  cloud_one:[2,0], 
  cloud_two:[3,0], 
  star:[4,0], 
  tree:[5,0]
});

With that code, we'll define new sprite from the image and divide it by 32 x 48 pixels. Then we create tilesets with name and its position (on column and row). So, grass_one will go to sprite on first row and first column, cloud_one will go to sprite on first row and third column, etc.

To place tiles from tilesets on stage, we can add tiles name when we create the entity. This code is an example how we do that.
terrain[0][0] = Crafty.e("Terrain, grass_one").attr({x:10, y:200});

Animation


This is where we are going to make that sprites animate. We are going to use Walking Ninja Sprites and animate it with Crafty so, lets do it.

Before we animate an animation, we need to set up it first using "reel" function. We need to add "SpriteAnimation" component to use "reel". Here is the code to setup walk animation from ninja sprite. 

.reel("animation_name", time_in_ms, from_column, from_row, total_column);
var Player = Crafty.e("Hero, ninja, SpriteAnimation").reel("walk", 1000,0,0,8);

And then we can animate it using this code.
Player.animate("walk",-1);

Demo Time!


Well, lets use all we just learned from this post, to create a stage from tilesets, and let that ninja walking on it. 

Here is the code for the demo:
<div id="game" style="border: 1px black solid;"></div>
<script src="https://googledrive.com/host/0B4jXBDxRv1t_dDQ3UHdGQ1JrZTg" type="text/javascript"></script>

<script>
Crafty.init(500,350, document.getElementById('game'));

Crafty.sprite(32, 48, "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMv-s_cqk2sotZGmsPYDXJiUvMht0ZwwnTVVUL1xShyphenhyphen8fTSUoDjFopZwPFmAfatgU4FOJDRZHPmhEtEqAGgdYJGDgacG5s3X70jEYRVB_2ACrHH4fo0YY4mGd1W-4Op_rFiXeiNy2Vbx0/s1600/Sprites.png", 
{grass_one:[0,0], 
grass_two:[1,0], 
cloud_one:[2,0], 
cloud_two:[3,0], 
star:[4,0], 
tree:[5,0]});

Crafty.sprite(64, "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEitBIl3EFIc6ve78sha1f1YwZO28T1ze0Ivs1hpcQqLvxOr-FDWiP8_9CiajCwT4knTWwIu56DhHIOAZ-FzdOvAoRim7W1cIa17xNc6T2Gi3NHPihyfsRHvuvbqyqkO7pxKWZPontxAcXw/s1600/Ninja-Walk-8.png",
{ ninja: [0,0] });

Crafty.c("Hero", {
      init: function() {
          this.addComponent("2D, Canvas");
          this.w = 64;    // width
          this.h = 64;    // height
      }
});

Crafty.c("Terrain", {
      init: function() {
          this.addComponent("2D, Canvas");
          this.w = 32;    // width
          this.h = 48;    // height
      }
});

var terrain = new Array();
terrain[0] = new Array();
terrain[1] = new Array();
terrain[2] = new Array();

terrain[0][0] = Crafty.e("Terrain, grass_one").attr({x:10, y:200});
terrain[0][1] = Crafty.e("Terrain, grass_two").attr({x:42, y:200});
terrain[0][2] = Crafty.e("Terrain, grass_one").attr({x:74, y:200});
terrain[0][3] = Crafty.e("Terrain, grass_one").attr({x:106, y:200});
terrain[0][4] = Crafty.e("Terrain, grass_two").attr({x:138, y:200});
terrain[0][5] = Crafty.e("Terrain, grass_one").attr({x:170, y:200});

terrain[1][0] = Crafty.e("Terrain, cloud_one").attr({x:10, y:152});
terrain[1][1] = Crafty.e("Terrain, cloud_two").attr({x:42, y:152});
terrain[1][2] = Crafty.e("Terrain, cloud_one").attr({x:74, y:152});
terrain[1][3] = Crafty.e("Terrain, cloud_one").attr({x:106, y:152});
terrain[1][4] = Crafty.e("Terrain, cloud_two").attr({x:138, y:152});
terrain[1][5] = Crafty.e("Terrain, cloud_one").attr({x:170, y:152});

terrain[2][0] = Crafty.e("Terrain, star").attr({x:10, y:104});
terrain[2][1] = Crafty.e("Terrain, star").attr({x:42, y:104});
terrain[2][2] = Crafty.e("Terrain, star").attr({x:74, y:104});
terrain[2][3] = Crafty.e("Terrain, star").attr({x:106, y:104});
terrain[2][4] = Crafty.e("Terrain, star").attr({x:138, y:104});
terrain[2][5] = Crafty.e("Terrain, star").attr({x:170, y:104});


var Player = Crafty.e("Hero, ninja, SpriteAnimation").attr({x:74, y:136}).reel("walk", 1000,0,0,8);

Player.animate("walk",-1);
</script>

This is the images that I used:


Walking Ninja (Original Size)




Terrain Tilesets (Original Size)




Live Demo (New)



Everyday I'm Shuffling... :D

No comments:

Post a Comment