{"id":451,"date":"2015-08-19T19:55:29","date_gmt":"2015-08-19T18:55:29","guid":{"rendered":"http:\/\/www.pixnbgames.com\/blog\/?p=451"},"modified":"2015-08-21T23:51:39","modified_gmt":"2015-08-21T22:51:39","slug":"frame-by-frame-animations-in-libgdx","status":"publish","type":"post","link":"https:\/\/www.pixnbgames.com\/blog\/libgdx\/frame-by-frame-animations-in-libgdx\/","title":{"rendered":"Frame by frame animations in LibGDX"},"content":{"rendered":"<h2 style=\"text-align: justify;\">Intoduction<\/h2>\n<p style=\"text-align: justify;\">When we need to animate our game objects, one of the methods we have is the frame by frame animations. It&#8217;s the classic animation method, and consists on drawing a serie of images that, when they are showed in sequence, it seems the element is doing some action.<\/p>\n<p style=\"text-align: justify;\"><a href=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2015\/08\/runner.gif\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-428\" src=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2015\/08\/runner.gif\" alt=\"runner\" width=\"80\" height=\"120\" \/><\/a>For example, if we want to show a running character, we should have a serie of images, each with a little advance over the previous image, so as when they are displayed them sequentially, we can see the character moving:<\/p>\n<p style=\"text-align: justify;\"><a href=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2015\/08\/charset.png\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-424\" src=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2015\/08\/charset.png\" alt=\"charset\" width=\"559\" height=\"240\" srcset=\"https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2015\/08\/charset.png 559w, https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2015\/08\/charset-300x129.png 300w\" sizes=\"(max-width: 559px) 100vw, 559px\" \/><\/a><\/p>\n<p>&nbsp;<br \/>\n&nbsp;<\/p>\n<h1 style=\"text-align: justify;\">Frame by frame animations in LibGDX<\/h1>\n<h2>La Animation class<\/h2>\n<p style=\"text-align: justify;\">The class responsible of the management of frame by frame animations is <code>Animation<\/code>. Its work involves in calculate the frame that must rendered at each time, being us the responsibles of draw the result.<\/p>\n<p style=\"text-align: justify;\">This class needs these four elements to work:<\/p>\n<ul>\n<li style=\"text-align: justify;\"><strong>Images that compose the animation.<\/strong> Each of this images is a frame of the animation.<\/li>\n<li style=\"text-align: justify;\"><strong>Time to wait between a frame and the next one.<\/strong><\/li>\n<li style=\"text-align: justify;\"><strong>Play mode.<\/strong> The possible modes are defined in the enum <code>Animation.PlayMode<\/code>. It tells to our <code>Animation<\/code> object the order in which the frames must be rendered. The possible modes are:\n<ul>\n<li style=\"text-align: justify;\"><code>NORMAL<\/code>: The frames are displayed from first to last. Without looping. So when the animation gets to the last frame, then always is returned the last frame.<\/li>\n<li style=\"text-align: justify;\"><code>REVERSED<\/code>: The frames are displayed from last to first. Without looping. So when the animation gets to the first frame, then always is returned the first frame.<\/li>\n<li style=\"text-align: justify;\"><code>LOOP<\/code>: The frames are displayed from first to last. With looping. So when the animation gets to the last frame, then starts again with the first one.<\/li>\n<li style=\"text-align: justify;\"><code>LOOP_REVERSED<\/code>: The frames are displayed from last to first. With looping. So when the animation gets to the first frame, then starts again with the last one.<\/li>\n<li style=\"text-align: justify;\"><code>LOOP_PINGPONG<\/code>: The frames are displayed from first to last. When it gets to the last one, it starts to draw from last to first, and then again from first to last, last to first, &#8230;, ping pong \ud83d\ude42<\/li>\n<li style=\"text-align: justify;\"><code>LOOP_RANDOM<\/code>: The frames are displayed randomly, without a defined order.<\/li>\n<\/ul>\n<\/li>\n<li style=\"text-align: justify;\"><strong>Elapsed time from the beginning of the animation.<\/strong> Each time we draw on screen, we must pass the elapsed time to the <code>Animation<\/code>, and it return us the frame to draw depending on the elapsed time and the play mode.<\/li>\n<\/ul>\n<p>&nbsp;<br \/>\n&nbsp;<\/p>\n<h2>Example<\/h2>\n<p style=\"text-align: justify;\">Normally, in videogames, each character will have several animations which will be drawn depending of character&#8217;s state (walking, running, jumping, etc.). In order to make this example the most clear possible, I will not use states, and I am going to show only one element with one animation.<\/p>\n<p>&nbsp;<\/p>\n<h3>Images<\/h3>\n<p style=\"text-align: justify;\">For this example i&#8217;m going to use the file (<a href=\"https:\/\/github.com\/angelnavarro\/Gdx-Animation-Example\/blob\/master\/android\/assets\/charset.png\" target=\"_blank\">charset.png<\/a>) which stores all the images that compose the animation:<\/p>\n<p style=\"text-align: justify;\"><a href=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2015\/08\/charset1.png\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-425\" src=\"http:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2015\/08\/charset1.png\" alt=\"charset\" width=\"552\" height=\"237\" srcset=\"https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2015\/08\/charset1.png 552w, https:\/\/www.pixnbgames.com\/blog\/wp-content\/uploads\/2015\/08\/charset1-300x129.png 300w\" sizes=\"(max-width: 552px) 100vw, 552px\" \/><\/a>Also I will make the file <a href=\"https:\/\/github.com\/angelnavarro\/Gdx-Animation-Example\/blob\/master\/android\/assets\/charset.atlas\" target=\"_blank\">charset.atlas<\/a>, knowing that each frame takes 80 pixels for width and 120 for height. In the atlas, I use the same name for all the frames, and I assign an index to each one of them. The file looks like this:<\/p>\n<pre lang=\"Json\" line=\"1\">charset.png\r\nformat: RGBA8888\r\nfilter: Linear,Linear\r\nrepeat: none\r\nrunning\r\n  rotate: false\r\n  xy: 0, 0\r\n  size: 80, 120\r\n  orig: 80, 120\r\n  offset: 0, 0\r\n  index: 0\r\nrunning\r\n  rotate: false\r\n  xy: 80, 0\r\n  size: 80, 120\r\n  orig: 80, 120\r\n  offset: 0, 0\r\n  index: 1\r\nrunning\r\n  rotate: false\r\n  xy: 160, 0\r\n  size: 80, 120\r\n  orig: 80, 120\r\n  offset: 0, 0\r\n  index: 2\r\n(continue ...)\r\n<\/pre>\n<p style=\"text-align: justify;\">This way, we can easily get all frames that compose the animation:<\/p>\n<pre lang=\"Java\">public class GdxAnimationExample extends ApplicationAdapter {\r\n    ...\r\n    \/\/ Atlas with all the frames defined in \"charset.atlas\"\r\n    private TextureAtlas charset;\r\n    ...\r\n    \r\n    @Override\r\n    public void create () {\r\n        ...\r\n        \/\/ Frames loading from \"charset.atlas\"\r\n        charset = new TextureAtlas( Gdx.files.internal(\"charset.atlas\") );\r\n        \r\n        \/\/ Getting the images for \"running\" animation\r\n        Array<AtlasRegion> runningFrames = charset.findRegions(\"running\");\r\n        ...\r\n    }\r\n    ...\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<h3>Building the animation<\/h3>\n<p style=\"text-align: justify;\">Once we have loaded the images that compose the animation, we can build it. For this example we want to play it for ever, so we use the play mode <code>PlayMode.LOOP<\/code>:<\/p>\n<pre lang=\"Java\">public class GdxAnimationExample extends ApplicationAdapter {\r\n    ...\r\n    \/\/ Time which each frame keeps on screen\r\n    private static float FRAME_DURATION = .05f;\r\n\r\n    \/\/ Running animation\r\n    private Animation runningAnimation;\r\n    ...\r\n    \r\n    @Override\r\n    public void create () {\r\n        ...\r\n        \/\/ Building of the animation\r\n        runningAnimation = new Animation(FRAME_DURATION, runningFrames, PlayMode.LOOP);\r\n        ...\r\n    }\r\n    ...\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<h3>Drawing each frame<\/h3>\n<p style=\"text-align: justify;\">At the time to draw, the object <code>runningAnimation<\/code> will return us the frame that we need to draw depending of the elapsed time. For this reason we have a local variable, <code>elapsed_time<\/code>, where we store the elapsed time from de beginning of the animation:<\/p>\n<pre lang=\"Java\">public class GdxAnimationExample extends ApplicationAdapter {\r\n    ...\r\n    \/\/ Frame that must be rendered at each time\r\n    private TextureRegion currentFrame;\r\n\r\n    \/\/ Elapsed time\r\n    private float elapsed_time = 0f;\r\n\r\n    \/\/ Auxiliar variables to know where to draw the picture to center it on the screen\r\n    private float origin_x, origin_y;\r\n    ...\r\n    \r\n    @Override\r\n    public void render () {\r\n        ...\r\n        \/\/ Elapsed time\r\n        elapsed_time += Gdx.graphics.getDeltaTime();\r\n        \r\n        \/\/ Getting the frame we must draw at this moment\r\n        currentFrame = runningAnimation.getKeyFrame(elapsed_time);\r\n\r\n        \/\/ Drawing on the screen\r\n        batch.begin();\r\n        batch.draw(currentFrame, origin_x, origin_y);\r\n        batch.end();\r\n        ...\r\n    }\r\n    ...\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<h3>Complete example<\/h3>\n<p>Combining all of the above, the class looks like this:<\/p>\n<pre lang=\"Java\" line=\"14\">\/**\r\n * Frame-by-frame animation example with LibGDX:\r\n * \r\n * http:\/\/www.pixnbgames.com\/blog\/libgdx\/frame-by-frame-animations-in-libgdx\/\r\n * \r\n * @author angel\r\n *\/\r\npublic class GdxAnimationExample extends ApplicationAdapter {\r\n    \r\n    \/\/ Time while each frame keeps on screen\r\n    private static float FRAME_DURATION = .05f;\r\n    \r\n    \/\/ To draw on screen\r\n    private SpriteBatch batch;\r\n    \r\n    \/\/ Atlas with the definition of the frames \"charset.atlas\"\r\n    private TextureAtlas charset;\r\n    \r\n    \/\/ Frame that must be rendered at each time\r\n    private TextureRegion currentFrame;\r\n    \r\n    \/\/ Running animation\r\n    private Animation runningAnimation;\r\n    \r\n    \/\/ Elapsed time\r\n    private float elapsed_time = 0f;\r\n    \r\n    \/\/ Auxiliar variables to know where to draw the picture to center it on the screen\r\n    private float origin_x, origin_y;\r\n    \r\n    \r\n    @Override\r\n        public void create () {\r\n        batch = new SpriteBatch();\r\n        \r\n        \/\/ Frames loading from \"charset.atlas\"\r\n        charset = new TextureAtlas( Gdx.files.internal(\"charset.atlas\") );\r\n        \r\n        \/\/ Frames that compose the animation \"running\"\r\n        Array<AtlasRegion> runningFrames = charset.findRegions(\"running\");\r\n        \r\n        \/\/ Building the animatino\r\n        runningAnimation = new Animation(FRAME_DURATION, runningFrames, PlayMode.LOOP);\r\n        \r\n        \/\/ Calculates the x and y position to center the image\r\n        TextureRegion firstTexture = runningFrames.first();\r\n        origin_x = (Gdx.graphics.getWidth()  - firstTexture.getRegionWidth())  \/ 2;\r\n        origin_y = (Gdx.graphics.getHeight() - firstTexture.getRegionHeight()) \/ 2;\r\n    }\r\n    \r\n    \r\n    @Override\r\n    public void render () {\r\n        \/\/ Clear the screen\r\n        Gdx.gl.glClearColor(1.0f, .8f, .667f, 1);\r\n        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);\r\n        \r\n        \/\/ Elapsed time\r\n        elapsed_time += Gdx.graphics.getDeltaTime();\r\n        \r\n        \/\/ Getting the frame which must be rendered\r\n        currentFrame = runningAnimation.getKeyFrame(elapsed_time);\r\n        \r\n        \/\/ Drawing the frame\r\n        batch.begin();\r\n        batch.draw(currentFrame, origin_x, origin_y);\r\n        batch.end();\r\n    }\r\n    \r\n    \r\n    @Override\r\n    public void dispose() {\r\n        \/\/ Resource releasing\r\n        charset.dispose();\r\n        super.dispose();\r\n    }\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<h2>Source code<\/h2>\n<p>You can get the sample project from <a href=\"https:\/\/github.com\/angelnavarro\/Gdx-Animation-Example\" target=\"_blank\">my GitHub repository<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify;\">Regards,<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Intoduction When we need to animate our game objects, one of the methods we have is the frame by frame animations. It&#8217;s the classic animation method, and consists on drawing a serie of images that, when they are showed in <a class=\"more-link\" href=\"https:\/\/www.pixnbgames.com\/blog\/libgdx\/frame-by-frame-animations-in-libgdx\/\">Seguir leyendo <span class=\"screen-reader-text\">  Frame by frame animations in LibGDX<\/span><span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":424,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[14],"tags":[42,10,15],"language":[4],"_links":{"self":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts\/451"}],"collection":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/comments?post=451"}],"version-history":[{"count":11,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts\/451\/revisions"}],"predecessor-version":[{"id":954,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/posts\/451\/revisions\/954"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/media\/424"}],"wp:attachment":[{"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/media?parent=451"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/categories?post=451"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/tags?post=451"},{"taxonomy":"language","embeddable":true,"href":"https:\/\/www.pixnbgames.com\/blog\/wp-json\/wp\/v2\/language?post=451"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}