Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon

22. June 2016

 

Welcome to a new tutorial series covering the Defold engine, recently released for free use by King.  You can learn more about the Defold Engine in this video which contains a quick hands on.  It’s a powerful, cross platform Lua powered game engine for 2D game development.  This tutorial series will ultimately walk through all aspects of using the Defold game engine, in both text and video formats.  All of the assets used in creating these tutorials is available on the Patreon dropbox, although I will make source and asset files available as they are needed in text tutorials.  This first tutorial simply walks through getting the Defold engine installed and creating our first project.

 

You can watch the video version of this tutorial here or embedded down below.

 

Getting And Installing Defold Engine

 

Getting started with the Defold engine is very easy, however you will need to log in to Defold.com using a Google account.  First head on over to Defold.com and click the Get Defold button.

image

 

At this point you will have to log in using a Google account.  Once authenticated, you will be redirected to the Defold dashboard.  There are a number of download links available on this page.  Simply pick your appropriate platform:

image

 

This will download an archive file, extract the contents somewhere.

image

 

Defold is run by double clicking the Defold executable.  Before doing so however, let’s create a new project.

 

Creating a New Project in Defold

 

Creating a new Defold project is currently done using the Defold dashboard.  On the left hand sidebar of the dashboard, locate the Add Project button and click it.

image

 

You will now be brought to a very simple configuration form:

image

 

Name your project and click Save.  In my case I am creating a blank project, however Defold have made some sample projects available as a starting point.  If you would rather start there check “Yes, show me your tutorials”.  You will be presented with a list of options:

image

 

Your project is now available.  Let’s load the Editor.  In the folder you extracted Defold, double click the Defold executable.

 

Loading Your Project

 

Now with the editor open, select File->Open Project.

image

 

A list of available projects should now be available.

image

 

Select your newly created project and click Next.  Behind the scenes Defold is creating a git repository for your game.  Since this is the first “checkout”, you need to create a new branch.  Click New Branch then call it V1 or whatever name makes sense to you.

image

 

Defold will now download your project.  Here is the project structure of an empty new project:

image

 

Double click game.project to edit many game specific configuration setting:

image

 

Although our “game” doesn’t actually do anything, you can run it by hitting Ctrl+B or via the Project Menu:

image

 

Certainly not the most exciting game, but it’s a start!

image

 

Managing Your Projects

 

Back in the Defold dashboard, you can edit and delete your projects as well as add additional users.  Your project(s) should now appear on the left hand side of the dashboard, like so:

image

 

Click the gears icon above your project will bring you to the configuration section:

image

 

Clicking Team enables you to add users to your project:

image

 

Of course, they will have to authenticate using Google as well.

 

Finally by clicking Settings you have the ability to change the name and description of your project, as well as delete it entirely:

image

 

Code Hosted on Defold’s Server??? DEALBREAKER!

 

Don’t like the idea of your git repository behind hosted on Defold’s servers?  Well that’s an understandable concern and using the above process, this is exactly what happens.  When you create a project, it’s created as a Git repository on Defold’s servers and when you open it, you are downloading (or more accurately, checking out) to your local server).  It’s understandable that this isn’t for everyone.  Fortunately there is an alternative.

I am not going into details here, but if you want to bypass Defold’s servers complete, follow this guide here.

 

The Video

 

Programming , ,

27. May 2016

 

Welcome back to our ongoing tutorial series on using the Heaps framework with the Haxe programming language.  In the first tutorial we covered the configuration and programming a simple game using Heaps.  Then we covered the basics of 2D graphics in the next tutorial.  In this tutorial we are going to look at using 2D animation in Heaps.  We are going to cover three specific ways, first using a sequence of images for each individual frame of animation, second using a single simple spritesheet image and finally we are going to look at using a texture atlas.  All of the images used in this tutorial are available here, while the project files, source, images etc. are all available to Patreon backers.

 

As always there is a HD video version of this tutorial available here and embedded below.

 

First copy the animation frames into the resource folder.  Each is named along the lines of walk01, walk02, walk03, etc like so:

image

 

Now let’s jump into the code.  The process is almost identical to the sprite handling process from the previous tutorial:

import h2d.Anim;
import h2d.Bitmap;
import h2d.Sprite;
import h2d.Text;
import h2d.Tile;
import hxd.Res;
import hxd.res.Font;

import js.Lib;

import hxd.App;
class Main extends App {
	
	
	var animation:Anim;
	
	override function init() {
		Res.initEmbed();
		var tiles = new Array<Tile>();
		
		tiles.push(Res.walk01.toTile());
		tiles.push(Res.walk02.toTile());
		tiles.push(Res.walk03.toTile());
		tiles.push(Res.walk04.toTile());
		tiles.push(Res.walk05.toTile());
		tiles.push(Res.walk06.toTile());
		tiles.push(Res.walk07.toTile());
		tiles.push(Res.walk08.toTile());
		tiles.push(Res.walk09.toTile());
		tiles.push(Res.walk10.toTile());
		tiles.push(Res.walk11.toTile());
		tiles.push(Res.walk12.toTile());
		tiles.push(Res.walk13.toTile());
		tiles.push(Res.walk14.toTile());
		tiles.push(Res.walk15.toTile());
		tiles.push(Res.walk16.toTile());
		
		animation = new Anim(tiles, 10, s2d);
	}
	
	override function update(dt:Float) {
	}
	
	static function main() {
		new Main();
	}
	
}

 

Here we populate an array of type Tile with all of the images.  Remember Heaps will automatically make available any resource type with an appropriate loader.  Finally we pass this array to the constructor of Anim.  Anim is a special kind of drawable that contains several tiles that represent individual frames of animation.  Also in the constructor we pass along the frame rate to play the animation at, as well as the parent to play the animation relative to, in this case the default scene, s2d.  When you run this code you should see:

GIF

Pretty simple eh?

 

It’s also quite common to want to group all of your sprites together in a single image.  The following example does exactly that using this evenly spaced spritesheet (click for full sized image).  Just be aware, this code requires the width and height of each tile to be the same size.

animation

 

Now the code:

	override function init() {
		Res.initEmbed();
		
		var tileSrc = Res.animation.toTile();
		var tiles = tileSrc.grid(512);
		
		animation = new Anim(tiles, 10, s2d);
		animation.speed = 5;
	}

 

This code has basically the exact same end result.  Basically we load the entire spritesheet into a single tile, then split it into a number of smaller tiles using the grid() method, passing in the dimension to cut by.  Hopefully in the future this function will be updated to take both a width and a height value, removing the square requirement.  As you can see from this example, you can modify the Anim object after the fact, changing the animation speed, it’s position, rotation, scale etc.

 

One final option is to use an Atlas.  An Atlas is basically another form of spritesheet, but instead of being fixed dimensions, it comes with a text description file that says where each frame of animation within the texture is.  This allows you to more tightly store your images in a single image.  In terms of creating an atlas file, two options are LibGDX’s TexturePacker or CodeAndWeb’s TexturePacker.  Of course you could create the file by hand if you preferred.  Now some more code:

	override function init() {
		Res.initEmbed();

		var frame = Res.animationAtlasv1.get("walk01");
		
		var bmp = new Bitmap(frame, s2d);
		bmp.x = 400;
	}

 

As you can see, there is also a loader for Atlas files, so it’s simply a matter of accessing it via the Res interface.  In this particular example we are retrieving a single frame of animation that we use to populate a Bitmap and display on screen.  The Atlas loader also has the option of return an Anim object if preferred.

 

The Video

Programming

17. May 2016

 

In our previous tutorial looking at the Heaps game framework, we looked at creating an initial application.  As part of that tutorial we used s2d to draw some text on the screen.  Today we are going to look a bit closer at using 2D graphics with Heaps.  Let’s start straight off with a simple example:

import h2d.Bitmap;
import h2d.Sprite;
import h2d.Text;
import h2d.Tile;
import hxd.Res;
import hxd.res.Font;

import js.Lib;

import hxd.App;
class Main extends App {
	
	override function init() {
		
		// Example one, create a new Bitmap using a Tile
		Res.initEmbed();
		var logo = Res.logo.toTile();
		var bitmap = new Bitmap(logo, s2d);
		
	}
	
	override function update(dt:Float) {
	}
	
	static function main() {
		new Main();
	}
	
}

 

When we run this example:

image

For this example to work you need to copy an jpg, gif or png file named logo to the resource directory.  Don’t forget you need to tell Haxe where this directory is using the –D resourceDir flag (see previous tutorial for more information ).  In this example we convert the resource to a Tile object, which you can think of as a rectangular region within an image (even if it encompasses the entire image).  Finally we used this tile to create a Bitmap object, which is brings together the thing to draw ( the Tile ) and where to draw it (the Sprite). More on these later.  As before to display it on screen the bitmap is parented to the s2d object, which is a Scene object that is created for us automatically.


Let’s look at another quick source example, the performs a very similar task:

import h2d.Bitmap;
import h2d.Sprite;
import h2d.Text;
import h2d.Tile;
import hxd.Res;
import hxd.res.Font;

import js.Lib;

import hxd.App;
class Main extends App {
	
	override function init() {
		
		// Example two, create a bitmap manually using BitmapData 
		and draw it to screen.
		Res.initEmbed();
		var logoBitmapData = Res.logo.toBitmap();
		var bitmap = Bitmap.create(logoBitmapData);
		s2d.addChild(bitmap);
		
		// Set the pivot point of our bitmap so it is positioned 
		relative to it's center
		bitmap.tile.dx = -Math.round(bitmap.tile.width / 2 );
		bitmap.tile.dy = -Math.round(bitmap.tile.height / 2);
		// Now center the bitmap to the screen
		bitmap.x = s2d.width / 2;
		bitmap.y = s2d.height / 2 ;
	}
	
	override function update(dt:Float) {
	}
	
	static function main() {
		new Main();
	}
	
}

 

And running this one...

image

 

Here we again create a Bitmap to be drawn on screen, but this time using a different process.  In the first example (which is that way you would do things 99% of the time) we loaded the resource as a Tile.  In this example we instead load it using the toBitmap() method.  This is VERY VERY VERY confusing, and is why I decided to show it as an example.  toBitmap() does NOT create a Bitmap object, instead it creates a BitmapData object.  This naming convention was quite poorly chosen in my opinion and leads to a great deal of confusion.  BitmapData can be thought of the raw bytes of information that go together to make all the various pixels in our bitmap.  BitmapData is stored in system memory and is extremely slow to work with.  That said, you can easily manipulate this information, so if for example you wanted to convert all of the individual pixels to grayscale, you could.

Another change here is we didn’t set the Bitmap’s parent (s2d) during construction.  Instead we manually add the newly created bitmap to our scene by calling addChild().  This function will take any Sprite derived class.  We will get back to that in a second, but it’s an important concept to understand.  This second example shows a couple other key concepts.  Notice how we set the position .x and .y?  Well these are simple pixel coordinates to represent where the image should be drawn relative to the origin of it’s parent (s2d in this case).  The origin by default is the top left corner.  In this example we set the pivot point (or origin) by specifying dx and dy.  These are delta values that tell you where drawing calls are made relative to.  In this case we will perform drawing calls on this object relative to it’s mid point.

 

That’s about all I want to cover at this point in time, but there are a few key Heaps classes we should understand before moving on.

 

Sprite

If you come from other game engines, this terminology is very confusing.  Almost universally a Sprite represents and image ( bitmap or texture in memory ) and the position to draw it at.  In heaps however, a Sprite is only about the position of the object. Sprite is the only type of object that can be added to Layer (and thus Scene) ‘s addChild() method call. 

 

Drawable

Drawable inherits from Sprite and is the parent class for things that can actually be drawn on screen.  Bitmap inherits from this class, but so to does Text which we used earlier, as does Anim and Graphics.

 

Scene

s2d is an instance of Scene which is ultimately the root of the 2D scene graph.  At it’s core, Scene is actually a Sprite itself ( via Layer ), but it also holds a special object called Stage and is capable of responding to a number of UI events, as we will see in an upcoming tutorial.

 

Tile

This is another one of those things can be a bit confusing.  A Tile is a rectangle within a texture or image, but ultimately represents a source rectangle that is going to be displayed.  For example, the tile of a bitmap could represent only a portion of the source image.  Consider the following change to our original source:

	override function init() {
		Res.initEmbed();
		var logo = Res.logo.toTile();
		var bitmap = new Bitmap(logo, s2d);
		bitmap.tile.setSize(Math.round(bitmap.tile.width / 2),	
		Math.round(bitmap.tile.height / 2));
	}

 

When this code is run we get:

image

 

The underlying image of our Bitmap is unchanged, but we are only using a quarter of it because we shrank the dimensions of the tile.  This Tile approach is handy when dealing with sprite sheets, where you have several different frames of animation in a single source texture.  We will see this process in a later tutorial.

Programming

5. May 2016

 

Introduction

Welcome to the first part of a multipart tutorial series on creating games using the Haxe programming language with the Heaps graphics engine.  Heaps is under development by Nicolas Cannasse, the guy that created the Haxe language in the first place.  In his own words:

Heaps is a cross platform graphics engine designed for high performance games. It's designed to leverage modern GPUs that are commonly available on both desktop and mobile devices. The framework currently supports HTML5 WebGL, Flash Stage3D, native Mobile (iOS and Android) and Desktop with OpenGL. 

Heaps is a very cool library, but not an incredibly well documented one.  So that’s where this tutorial series comes in.  We are going to look at creating 2D then 3D graphics using the Heaps engine.  For this series I will be doing both text and video versions of each tutorial.  The video version of this tutorial is available here.

 

Setting Up Your Haxe Development Environment

This tutorial is going to assume you are using Windows, if you are on another operating system, the steps are going to vary slightly.

First head to Haxe.org/download and download the appropriate Haxe installer for the most reason version.

image 

In my case I am going with the Windows Installer.  Run the executable and say yes to any security messages you receive.  You want to install everything like so:

image

 

Install where ever you like:

image

 

Verify your install worked correctly.  Fire up a command prompt and type haxelib version:

image

 

That was easy, eh?  Next you will probably want an IDE or Editor.  Personally I am using Haxe Develop, a special port of Flash Develop.  This is a Windows only IDE though.  Another option is Visual Studio Code with the Haxe language extensions.

 

Finally we need to install the Heaps library.  It’s not registered with Haxelib yet, so we currently have to install it from Github.  Run the command:

 

haxelib git heaps https://github.com/ncannasse/heaps.git

image

 

And done.

 

Creating a Hello World application

Now let’s create our first application to make sure everything is up and running correctly.  A simple hello world app.

Assuming you are using HaxeDevelop, go ahead and create a new project via Project->New Project

image

 

I created a JavaScript project like:

image

 

Inside our project folder, we need to create a folder for our resources.  I simply created a directory called res.  Simply right click your project in the Project panel and select Add->New Folder...

image

 

Next we need a TTF file, I personally used this font.  Simply download that zip and copy the ttf file into the newly created res directory.  You can open an Explorer window to that directory by right clicking it and selecting Explore.  I personally renamed it to not be all caps, it should work either way though.  If you are using HaxeDevelop, your project should look something like this:

image

 

We have two final bits of configuration.  First we need to text HaxeDevelop that we use the Heaps library, and that the resource folder is named Res.  Right click your project and select Properties

image

 

Next select the Compiler Options tab.  First add an entry to Compiler options with the value –D resourcePath=”res”.  Then add a value to Libraries of heaps.  That’s it, click Apply then Ok.

image

 

Finally some code!  First we need a WebGL canvas for our application to run in.  Simply open up index.html located in the Bin folder and add a canvas.  Your code should look something like:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8"/>
	<title>JSTest</title>
	<meta name="description" content="" />
</head>
<body>
	<canvas id="webgl" style="width:100%;height:100%"></canvas>
	<script src="JSTest.js"></script>
</body>
</html>

 

Now we need to edit our main Haxe code.  By default it will be called Main.hx and it’s the entry point (and entirety) of our program.  Enter the following code:

import h2d.Text;
import hxd.Res;
import hxd.res.Font;
import js.Lib;

class Main extends hxd.App {
        var text : Text;

		// Called on creation
        override function init() {
			// Initialize all loaders for embeded resources
			Res.initEmbed();
			// Create an instance of wireframe.tff located in our res folder, then create a font2d of 128pt size
			var font = Res.wireframe.build(128);
			// Create a new text object using the newly created font, parented to the 2d scene
            text = new Text(font, s2d);
			// Assign the text
			text.text = "Hello World";
			// Make it read, using hex code ( RR GG BB, each two hex characters represent an RGB value from 0 - 255 )
			text.textColor = 0xFF0000;
        }

		// Called each frame
        override function update(dt:Float) {
			// simply scale our text object up until it's 3x normal size, repeat forever
			var scaleAmount = 0.01;
			if (text.scaleX < 3.0) text.setScale(text.scaleX + scaleAmount);
			else text.setScale(1);
			
        }

        static function main() {
            new Main();
        }
    }

Now go ahead and run your code by either hitting F5 or click this button image

You should see:

GIF

 

Congratulations, your first Haxe programming using the Heaps library.  Next up, we will jump into 2D graphics with Heaps.

 

Video

Programming , ,

25. April 2016

 

One of the major advantages to working in 3D is once you have your character modeled and rigged, creating new animations is simply a matter of defining a series of poses on a timeline.  Animations are generally defined by moving a series of bones controlling your mesh, which in turn are powered by a system called inverse kinematics.  IK is basically a fancy way of saying “move an end bone and the computer will calculate how all the other bones in the chain will respond” enabling you to animate by positioning the foot forimage example and the ankle, knee and hip will rotate appropriately.  It’s a pretty powerful way to perform animation and every single major 3D application implements IK (and FK – forward kinematics).

 

In the land of 2D art, the process is often quite different.  Generally the approach here is to generate a sprite sheet, which is a sequence of slightly altered versions of the same character, which played in sequence results in an animation.  If you ever done a flipbook animation at the top corner of any of your textbooks, you already have the process of traditional 2D animation down.  There are other techniques such as onion skinning and rotoscoping to aid in the animation process, but it still remains time intensive.  If only there was some way to take the 3D worlds bone based animations and apply them to generating 2D art?  Well, there is... Spine.

 

Today we are going to look inside Spine, look at the art generation process, how to make sprite graphics that are animation ready, define an animation, then perhaps most importantly, play that animation back in our game engine of choice.  Since Spine itself is built over top of the LibGDX library (by one of the frameworks founders to boot), therefore I suppose a LibGDX example makes the most sense.  If you are bored, the story of how Spine came to be is an interesting read.

 

Full disclosure, I requested a review license in order to get hands on time with Spine.  Additionally some of the assets I am using in this demonstration are part of asset packs available for purchase and aren’t my creation.  Spine is commercial software, ranging in price from $70 for the essentials version, $300 for professional and $2200 for enterprise (which is tied to your companies revenue).  There is a free trial available and capable of doing everything we are about to do below except export and run in code.  Without further ado, let’s jump in.  As is often the case on GameFromScratch, if you prefer a video version one is available here as well as embedded below.

 

Meet Spine

Here is the main Spine interface:

image

 

It’s actually an exercise in simplicity which I appreciate.  It also supports UI scaling, so works well on high DPI displays, something far too many applications suck at, so I also appreciate that.  The left hand viewport is where the magic happens, this is where you compose your characters and animations, while on the right hand side you’ve got your project hierarchy a scene graph of sorts.  The primary UI is across the bottom of the screen.  You can easily pan and zoom around the display using a combination or RMB and Ctrl + RMB.  There is some additional complexity hidden away behind this menu:

image

 

But most of the time, what you see is actually all that you need.  It’s a very clean and simple UI.  Notice in the top left corner it says SETUP.  This is because you are currently in Setup mode.  Once our Sprite has been assembled and our bones have been arranged ( more on this in a moment ), we can then switch in to animation mode by clicking SETUP.

image

In animation mode, its all about posing our character.  Notice SETUP changes to ANIMATE and our interface changes slightly.  Now we have a timeline across the bottom of the screen.  We will get back to that in a moment.

 

Creating Spine Ready Sprites

Creating a sprite that is ready to be animated in Spine is pretty close to traditional sprite based animation with two major exceptions.  First, you cut your image up into several different pieces.  You can draw your sprite as a single image if you wish, but once you are done you need to cut it into several different animatable pieces.  Consider the sprite from the above screenshots:

image

This looks like a single drawn sprite, but it’s actually made up for several pieces arranged together.  If you look in the images section of the hierarchy, you can see it’s actually composed of several different images:

image

 

Again, you can draw your sprite how you normally would, but each animatable piece will need to be cut up to proceed in Spine.  This leads to our second requirement...  you also need to draw parts of the images that are normally obscured.  Again, using this example, even if the upper arm isn’t full shown due to being obscured by the body you still need to draw the entire arm, as the visibility can change as the sprite moves, for example:

imageimage

 

So when drawing the pieces of your sprite, you have to think about the depth as well.  Here for example are all the pieces that go together to make this character:

image

 

Rigging Your Character

Next up comes perhaps the most time intensive portion of working with Spine, rigging you character.  You can think of this as arranging all the various images together to create your character, while defining the underlying armature (fancy word for skeleton).  We will do a very simple skeleton, just to demonstrate the process.  You will notice in the tree view that there is a root node under our skeleton:

image

 

This is the very base of the skeleton and all bones are parented to it ultimately.  From here we need to create a root bone, it’s very common to start from the hips, which is what we will do.  Using the create tool, we will quickly create a simple leg skeleton:

image

Click once to set the start of the skeleton, then move the mouse and click again to set the first bone.  Now move down slightly and set another bone, like so:

image

In the hierarchy I rename the bones to values that make sense.

image

Now that we have bones, let’s attach some images to each.  From the images section you can simply drag the appropriate image onto the bone, like so:

image

You will be prompted if you want to go ahead with it:

image

 

The image is now parented to that bone.  By selecting the image you can now transform, rotate and resize it so it best matches the underlying bone:

image

You can also modifying the bone length by hovering over the tip, like so:

GIF

 

Now repeat for the lower bone, like so:

image

 

You end up with a hierarchy like:

image

 

Extremely simple, but the character is rigged, well, the leg is anyways.

 

Creating an Animation

 

Now that we have a very simple animatable character, let’s now switch over to ANIMATE mode.  In the tree view, you should see a section called Animations.  There may be a default one there, otherwise create one using the New Animation button that appears when animation is selected:

image

image

 

Keyframed animation is pretty simple in concept.  You will notice at the bottom of the screen there is now a Dopesheet view:

image

 

Your animation is composed of a set of “key” frames.  That is, you post your character and take a snapshot of the location/rotation/scale of a given bone, then advance the timeline to a different value and repeat the process.  The computer then interpolates between keyframes to create a smooth animation.  You can turn “autokey” on, so that any changes you make in the editing window automatically set a key.  Otherwise you can manually create the key by clicking the green key to the right of each transform:

image

 

Set a key for the default rotate, translate and scale values, or use Autokey.  Next advance the timeline to say 5, like so:

image

 

Next using rotations, manipulate each bone, like so:

gif2

 

Advance the timeline slightly more, then repeat the process all over again.  You can control the playback of your animation using these simple VCR style controls:

image

 

Here is a very simple and crude kicking animation:

gif3

 

Another cool thing you can do is add Events as part of your timeline, like so:

image

image

Enabling you to create events that can be fired in code, allowing you to incorporate programmatic aspects into your animations, such as playing a footstep audio effect.  We will see this process shortly.

 

Exporting the Animation

Now that we’ve got an animation to use in our game, it’s time to export it.  Here there are a couple of choices. 

image

 

You can export your results as a video, a sequence of images or as data.  If you chose to export as an image you can actually have some rather advanced controls, including generating a texture atlas (directly usable in LibGDX) or sprite sheet:

image

 

With results like:

skeleton-kick

 

This approach can be utilized in just about every single kind of game engine available today.  However, where Spine shines is when you chose to export as data instead.  This is where runtimes come in.  These are essentially libraries or code for the various game engines that enable you to use spine format natively.  Full source is available on github and runtimes exist for most 2D engines available including Unity, LibGDX, Love, MonoGame, Torque2D, Cocos2d-x and many more.  In this example I will be using LibGDX.

 

In this case I’m going to export to JSON and generate a texture atlas using the following settings:

image

 

Now let’s break out some code.

 

Using Spine In Game

As mentioned earlier Spine have several runtimes available on github.  In the case of the LibGDX project, you simply have to copy the code into your appropriate source code folder.  Assuming you created a project using the setup utility, this means copying the contents of esotericsoftware to your core\src\com directory.  Then I wrote the following code, adapted from one of their LibGDX examples.

Make sure that you’ve exported your assets and created the atlas in your working directory, most likely \core\assets.  Then use the following code:

package com.gamefromscratch;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.esotericsoftware.spine.*;

public class Spine2 extends ApplicationAdapter {
    private OrthographicCamera camera;
    private SpriteBatch batch;
    private SkeletonRenderer renderer;
    private TextureAtlas atlas;
    private Skeleton skeleton;
    private AnimationState state;

	public void create () {
		camera = new OrthographicCamera();
        camera.setToOrtho(false);
		batch = new SpriteBatch();
		renderer = new SkeletonRenderer();
		renderer.setPremultipliedAlpha(true); // PMA results in correct blending without outlines.

		atlas = new TextureAtlas(Gdx.files.internal("skeleton.atlas"));
		SkeletonJson json = new SkeletonJson(atlas);
		SkeletonData skeletonData = json.readSkeletonData(Gdx.files.internal("skeleton.json"));
		skeleton = new Skeleton(skeletonData);
		skeleton.setPosition(0, 0);

		AnimationStateData stateData = new AnimationStateData(skeletonData);
		state = new AnimationState(stateData);

        // Set up an animation listener so we can respond to custom events or completion
        final AnimationState.TrackEntry track = state.setAnimation(0, "kick", false);
        track.setListener(new AnimationState.AnimationStateListener() {
            @Override
            public void event(int trackIndex, Event event) {
                // Check for the "half" event we defined in the editor
                if(event.getString().equals("half"))
                    System.out.println("Half way baby");
            }

            @Override
            public void complete(int trackIndex, int loopCount) {
                // or the complete event (not END!) when done, fire the idle animation instead
                state.setAnimation(0,"idle",false);
            }

            @Override
            public void start(int trackIndex) {
            }

            @Override
            public void end(int trackIndex) {
            }
        });
	}

	public void render () {
		state.update(Gdx.graphics.getDeltaTime()); // Update the animation time.
		state.apply(skeleton);
		skeleton.updateWorldTransform();

        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
		camera.update();
		batch.getProjectionMatrix().set(camera.combined);
		batch.begin();
		renderer.draw(batch, skeleton);
		batch.end();
	}

	public void dispose () {
		atlas.dispose();
	}
}

 

When you run this code...

gif4

 

In the above code example you can see how you can handle an event you defined in Spine.  Otherwise it’s pretty simply to load and play animations on a character developed in Spine.  There is a comprehensive API, I’ve only touched on a very small part of it here due to space (this is already pretty long...).  There are also several features I never got to mention such as free form deformation ( useful for shapes such as capes ), swappable skins, place able props, etc..  If you are doing 2D animation, Spine is certainly a product you should check it.  Spine is by no means the only option when it comes to 2D animation in games, Spriter and Creature are two other popular alternatives.  It is however a very good option.

 

The Video

Art, Programming , ,

Month List

Popular Comments