Android Question Animation using LIBGDX and lgtextureatlas

MarcTG

Active Member
Licensed User
Longtime User
Hello

I am trying to create an animated live wallpaper using the Libgdx library. I found an example of how to animate a simple animation using a texture atlas written in java but I can't seem to properly translate it to B4A:

http://www.gamefromscratch.com/post/2013/12/09/LibGDX-Tutorial-3B-Simple-Animation.aspx

I do realize that this java tutorial starts by stating that this not the ideal method for creating an animation. I tried using lganimation (modifying the animation "caveman" example), but I can't pack my animation in one 2,048 x 2,048 sheet... if I pack my animation in a larger sheet, the animation works on the emulator but not on my phone or tablet. That is why I am trying to use an atlas with multiple sheets instead.

Please feel free to make any other suggestions on how to animate multiple images efficiently for a live wallpaper using Libgdx or any other library, I am very new to B4A and would appreciate any kind of help.

Thanks!
 

MarcTG

Active Member
Licensed User
Longtime User
Thank you andymc, I really appreciate you sharing this. Your source code was very helpful not just as an animation example.

So if I understand this correctly, instead of using an animation you are animating each frame using draw. This seems very straight forward and easy to implement, but is it more efficient than using an atlas + animation?
 
Upvote 0

MarcTG

Active Member
Licensed User
Longtime User
Attached is the wallpaper that I am trying to build (this is a random animation), it crashes after it starts, I am not sure why... Plz help :-(
 

Attachments

  • Livewallpaper.zip
    202.1 KB · Views: 282
Upvote 0

Informatix

Expert
Licensed User
Longtime User
Attached is the wallpaper that I am trying to build (this is a random animation), it crashes after it starts, I am not sure why... Plz help :-(
It crashes because of these lines in Process_Globals:
B4X:
Dim minscreen As Int = Min(LW.Graphics.Height, LW.Graphics.width)
Dim SH As Int = LW.Graphics.Height
Dim SW As Int = LW.Graphics.width
The LW object is not initialized yet, so you cannot use it (and the Graphics class will be available only when the OpenGL surface is created, thus not before LG_Create). MinScreen, SH and SW should be set in the LG_Resize event.
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
Thank you andymc, I really appreciate you sharing this. Your source code was very helpful not just as an animation example.

So if I understand this correctly, instead of using an animation you are animating each frame using draw. This seems very straight forward and easy to implement, but is it more efficient than using an atlas + animation?
Using the Animation class is just a convenient way of animating things. It does not offer better performance.
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
In my games I use textureregions to do my animation. You can download my source code here and take a look:

https://dl.dropboxusercontent.com/u/8673694/my games/Invaders-source.zip
As you say in the comments at the end, there are memory leaks because of the number of resources not disposed of. To avoid bothering with the numerous dispose() to call and to not miss one, you can use the AssetManager class. You load your resources when needed with MyAssetManager.Load and MyAssetManager.FinishLoading (to force their loading right now, and not wait for their loading in the background). To use a loaded resource, you call MyAssetManager.Get("myresource.ext") and, when the game ends, you clean up the memory with MyAssetManager.dispose.
 
Upvote 0

MarcTG

Active Member
Licensed User
Longtime User
The LW object is not initialized yet, so you cannot use it (and the Graphics class will be available only when the OpenGL surface is created, thus not before LG_Create). MinScreen, SH and SW should be set in the LG_Resize event.

Thank you Fred :) I fixed this along with another problem I had involving deltatime (I read a previous post you had on that).

I know that many people before me have thanked for creating the libgdx library. As far as I go, your libraries, documentation, explanation, and support of everyone that has a question is the reason why I tried and bought this software. I think this community is lucky to have someone as talented and kind as you :).
 
Upvote 0

Brizky

Member
Licensed User
Longtime User
Hey, folks.

I'm wondering if someone could help me.

I've got a small game in the works where I'm trying to have all images and animation sequences in a Texture Atlas.
Using the Caveman animation example I modified the code to pull my animation frames from the Atlas. And I tried out the GDX Texyure Packer with a spritesheet IF found on line. In short, I have two issues.

1.) The spritesheet had 6 rows of sprite animations, 5 to a row. I modified it to be 16 frames with 4 columns and 4 rows. But I use the GetRegionArray() function but it seems that it's designed to return a specific array (of a two-dimensional array) based on index. But I wanted to use all of the frames and not just a single array of frames for the animation. I was hoping that the resulting array of lgTextureRegion would have some kind of method to add more frames but it seems to only give the Length property.

2.)The second, bigger issue seems to be that when I run my animation (which only uses 4 frames because of the issue above), the animation seems to flicker at the end. When I log the Length property of my lgTexture array, B4A tells me that I have 7 elements instead of the 4 I expect. So after trying to debug for a while, I decided to reduce the spritesheet to just 4 images and then pack it. Here's the strange thing. It seems the TExture Packer adds extra space on the end of my 4 images as if it's trying to fill up the width of the page. And it LOOKS like there's space for 3 more sprite frames judging by the border displayed around my image in Texture Packer. Now, looking at the max width for the page, it's set to 1024. Each animation frame is 117 high by 143 wide. So only 7 full frames would be able to fit across if I had 7. So I wonder if TExture Packer is forcing me to have 7 frames across because of the Max Page Width?
I've attached the png file that I use as input for the Atlas and a screenshot of what TexturePacker looks like when I add that pic. Notice the border is longer than it needs to be. So I'm thinking the flicker at the end of my animation are these blank frames.

How do I show this software who's boss?

Thanks,
Br&on

TexturePacker2.jpg

rider3.png
 

Attachments

  • TexturePacker2.jpg
    TexturePacker2.jpg
    293.3 KB · Views: 295
Upvote 0

MarcTG

Active Member
Licensed User
Longtime User
The flicker is due to the extra empty frames that you have in your image. The caveman example does not use a texture atlas, it just grabs equal frames from a spritesheet. Fred has another example called Textureatlas for texture atlas...
if you want to use this rather than an atlas i suggest you fix your spritesheet so that you don't have any empty frames. I don't use this texture packer software, but you probably have to learn more about how to use it and what you are getting out of it... For instance it looks like you have edge padding checked, and that's probably what's adding the extra space at the ends. Also, you have force POT checked, this will force the software to generate a texture that is a power of two, meaning the texture will be 2^n x 2^n regardless of the stuff your are adding.

The caveman method is simple to use in code, but you have to make sure that your spritesheet is flawless.

As far as the issue of the two dimensional array, you can transform it to a one dimensional array and extract any frame that you want from it. I use something like this:

B4X:
Dim animregion As lgTextureRegion  
animregion.InitializeWithTexture(texture) 
Dim animsplit(,) As lgTextureRegion=animregion.Split(xsize,ysize)

Dim animframes (8) As lgTextureRegion '8 is the size of the one dimensional array, or number of frames
Dim index As Int = 0

  For i=0 To 2-1   '2 is the number of columns in the sprite sheet (in yours its 1)
     For  j = 0 To 4-1 '4 is the number of rows in the sprite sheet (in yours its 4)
     animframes(index)=animsplit(i,j) '2D to 1D
     index=index+1 
     Next
   Next

Hope this helps
 
Upvote 0

Brizky

Member
Licensed User
Longtime User
Thanks for the response, MarcTG. And, yeah, I thought the flicker had to do with the extra space. I just didn't know how that extra space was getting in there. And the padding issue does make sense. I'm assuming while I was messing around with TexturePacker to see how it worked, I left some things checked that I shouldn't have. I was going through the different options and seeing what the result was on the screen. Didn't see any changes so I didn't think it did anything.

And the power of 2 makes sense now that you say that. Dind't know what that POT option meant. Even after reading the different property descriptions for TExture Packer I was still a bit confused. But you cleared that up. I'm just glad it wasn't the code because I was eyeballing the heck out of it for too long.

Thanks again,

I'm going to try this (and the code above) real soon.
 
Upvote 0

Brizky

Member
Licensed User
Longtime User
The flicker is due to the extra empty frames that you have in your image. The caveman example does not use a texture atlas, it just grabs equal frames from a spritesheet. Fred has another example called Textureatlas for texture atlas...
if you want to use this rather than an atlas i suggest you fix your spritesheet so that you don't have any empty frames. I don't use this texture packer software, but you probably have to learn more about how to use it and what you are getting out of it... For instance it looks like you have edge padding checked, and that's probably what's adding the extra space at the ends. Also, you have force POT checked, this will force the software to generate a texture that is a power of two, meaning the texture will be 2^n x 2^n regardless of the stuff your are adding.

The caveman method is simple to use in code, but you have to make sure that your spritesheet is flawless.

As far as the issue of the two dimensional array, you can transform it to a one dimensional array and extract any frame that you want from it. I use something like this:

B4X:
Dim animregion As lgTextureRegion 
animregion.InitializeWithTexture(texture)
Dim animsplit(,) As lgTextureRegion=animregion.Split(xsize,ysize)

Dim animframes (8) As lgTextureRegion '8 is the size of the one dimensional array, or number of frames
Dim index As Int = 0

  For i=0 To 2-1   '2 is the number of columns in the sprite sheet (in yours its 1)
     For  j = 0 To 4-1 '4 is the number of rows in the sprite sheet (in yours its 4)
     animframes(index)=animsplit(i,j) '2D to 1D
     index=index+1
     Next
   Next

Hope this helps

Yup, the Texture Packer settings were definitely the issue. Thanks for the assist!
 
Upvote 0
Top