How to have multiple sprite in one atlas for libgdx? - android

I am using libGdx(Android) to create a simple animation
I used TexturePacker to create a sprite of multiple images ,I was using about 50 images , texture packer put them in more than one sprite sheet( 3 sprites) and exports a .atlas file with them , which contains all information about images:
TextureAtlas texture = new TextureAtlas(Gdx.files.internal("image.atlas");
Animation anime = new Animation(1/30f, texture.getRegions());
and this is render method
#Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);
batch.begin();
elapsedTime += Gdx.graphics.getDeltaTime();
batch.draw((TextureRegion)anime.getKeyFrame(elapsedTime, true), 0, 0,w,h);
batch.end();
}
when I tested my code it works, but only the first sprite is appeared and loop, the other 2 sprites aren't !

Related

Reduce time delay on Resume

I have a simple libgdx code for game which contains 1 texture and a particle effect with 4 emitters.
Whenever I resume to the game screen or lock-unlock the phone, I get a delay of about 3 seconds.
How do I reduce this delay?
One thing I have tried is that by reducing the texture image size.
Before i had a texture image of 300kb and used to get a delay of 5 seconds, now i hve reduced it to 60kb
and now I get a delay of 3 seconds.
Is there any way programaticaly that I can reduce the delay. I dont want to show any spalsh screen
Code:
#Override
public void show() {
SpriteBatch batch = new SpriteBatch();
Texture tex = new Texture(Gdx.files.internal("data/bg1.jpg"));
Sprite sprite = new Sprite(tex);
ParticleEffect pe = new ParticleEffect();
pe.load(Gdx.files.internal("data/pe1.p"), Gdx.files.internal("data"));
pe.start();
}
#Override
public void render(float delta) {
gl.glClearColor(0f, 0f, 0f, 1f);
gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
gl.glViewport(0, 0, (int) Width, (int) Height);
camera.update();
batch.setProjectionMatrix(camera.combined);
batch.begin();
sprite.draw(batch);
pe.draw(batch, delta);
batch.end();
}
Why don't you just try making the local variables in show() field variables and initializing them in the constructor rather than in the show method. I would still recommend measuring which part is taking the most time as the one comment states.

LibGdx don't draw properly a circle in float space

My camera is set to a normalized space (1 unit in height and 1.5 unit in width). But it seems the circle algorithm of the ShapeRenderer works only in integer space. Is there a workaround ?
public void create() {
camera = new OrthographicCamera();
camera.setToOrtho(false, 1.5f, 1f);
shapes = new ShapeRenderer();
}
public void drawScene() {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
shapes.setProjectionMatrix(camera.combined);
shapes.begin(ShapeType.Circle);
shapes.setColor(1, 0, 0, 1);
shapes.circle(0.75f, 0.5f,0.5f);
shapes.end();
}
ShapeRenderer uses 6 times the cube root of the radius to estimate how many segments it needs to draw a circle.
In your case that you end up with 4 segments (6 * 0.793 is roughly 4.76). Which is what you see.
ShapeRenderer assumes units are screen pixels according to the documentation, so these are reasonable estimates.

My AndEngine onLoadResources() does not seem to be efficient

I'm using AndEngine to create a live wallpaper. However, in my onLoadResources() method I am currently loading 3 different textures:
#Override
public void onLoadResources() {
prefs = PhysicsWallpaperActivity.this.getSharedPreferences(SHARED_PREFS_NAME, 0);
prefs.registerOnSharedPreferenceChangeListener(this);
this.mAutoParallaxBackgroundTexture = new BitmapTextureAtlas(2048, 2048, TextureOptions.DEFAULT);
this.mAutoParallaxImage1Texture = new BitmapTextureAtlas(2048, 2048, TextureOptions.DEFAULT);
this.mAutoParallaxImage2Texture = new BitmapTextureAtlas(2048, 2048, TextureOptions.DEFAULT);
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
this.mParallaxLayerBackground = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mAutoParallaxBackgroundTexture, this, "background.jpg", 0, 0);
this.mParallaxLayerImage1 = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mAutoParallaxImage1Texture, this, "image1.jpg", 0, 0);
this.mParallaxLayerImage2 = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mAutoParallaxImage2Texture, this, "image2.png", 0, 800);
this.mEngine.getTextureManager().loadTexture(this.mAutoParallaxBackgroundTexture);
this.mEngine.getTextureManager().loadTexture(this.mAutoParallaxImage1Texture);
this.mEngine.getTextureManager().loadTexture(this.mAutoParallaxImag2Texture);
}
I feel like this is not the most efficient way to do this. But if I have all my BitmapTextureAtlasTextureRegionFactorys 'images' pointing to just a single BitmapTextureAtlas, and those 'images' are at the same coordinates, the images will load together on top of each other even if I only call 1 of them.
An example of the problem is here:
#Override
public void onLoadResources() {
prefs = PhysicsWallpaperActivity.this.getSharedPreferences(SHARED_PREFS_NAME, 0);
prefs.registerOnSharedPreferenceChangeListener(this);
this.mAutoParallaxBackgroundTexture = new BitmapTextureAtlas(2048, 2048, TextureOptions.DEFAULT);
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
this.mParallaxLayerBackground = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mAutoParallaxBackgroundTexture, this, "background.jpg", 0, 0);
this.mParallaxLayerImage1 = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mAutoParallaxBackgroundTexture, this, "image1.jpg", 0, 0;
this.mParallaxLayerImage2 = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mAutoParallaxBackgroundTexture, this, "image2.png", 0, 800);
this.mEngine.getTextureManager().loadTexture(this.mAutoParallaxBackgroundTexture);
}
^ I would have liked to use the code like this because it seems more efficient, but 'image1' and 'image2' automatically load on top of each other even if I only call 1 of them.
Am I doing this the right way? Or is there a more efficient way?
Your textures can contain more than one resource. Think of it like a sprite sheet. or like gluing photos to a big white sheet of paper. you do not need a new texture for each texture region. For example:
Say you have a star image, that is 250x250 pixels and a spaceship image that is 100x100 pixels. You could put both of these on a texture that measure 512x256.
You create a texture region for the star(250x250) at 0, 0.
Then create a second texture region for the spaceship at 251, 0.
In that scenario there is still some leftover area for other images blow the spaceship, if they are small enough to fit. The Image below shows how your texture would look if you could see it in memory.
Hope this helps.
Your Textures are huge! Are you very sure you need them that big?

How do I create an orthographic camera that correctly scales my sprites/textures with libgdx?

I'm creating a game with libgdx that I want to run at a higher resolution on the desktop, but I want it to scale everything down correctly when I run it on android at smaller resolutions. I've read that the best way to do this is to not use a pixel perfect camera, and instead to use world coordinates, but I'm not sure how to correctly do that.
This is the code I have right now:
#Override
public void create() {
characterTexture = new Texture(Gdx.files.internal("character.png"));
characterTextureRegion = new TextureRegion(characterTexture, 0, 0, 100, 150);
batch = new SpriteBatch();
Gdx.gl10.glClearColor(0.4f, 0.6f, 0.9f, 1);
float aspectRatio = (float)Gdx.graphics.getWidth() / (float)Gdx.graphics.getHeight();
camera= new OrthographicCamera(aspectRatio, 1.0f);
}
#Override
public void render() {
GL10 gl = Gdx.graphics.getGL10();
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
camera.update();
camera.apply(gl);
batch.setProjectionMatrix(camera.combined);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
draw();
}
private void draw() {
//batch.getProjectionMatrix().set(camera.combined);
batch.begin();
batch.draw(characterTextureRegion, 0, 0, // the bottom left corner of the box, unrotated
1f, 1f, // the rotation center relative to the bottom left corner of the box
0.390625f, 0.5859375f, // the width and height of the box
1, 1, // the scale on the x- and y-axis
0); // the rotation angle
batch.end();
}
The texture I'm use is 256x256 with the actual image in it being 100x150.
This is the result I get when I run the game: http://i.imgur.com/HV9Bi.png
The sprite that gets rendered is massive, considering this is the original image: http://i.imgur.com/q1cZT.png
What's the best way to go about making it so that the sprites get rendered at their original size while still keeping the ability to have the game scale correctly when played in different resolutions?
I've only found two solutions, both of which I don't like.
The image showed up how it was supposed to if I used pixel coordinates for the camera, but then that didn't scale at all when I put it on my phone with a different resolution.
I can scale the texture region down when I draw it, but it seems like there is a better way because it is extremely tedious trying to figure out the correct number to scale it by.
Have you ever used the Libgdx setup tool? When you create a project with it, it has a sample image that is displayed. It seems to keep it's ratio correct no matter what size you change the screen to.
public class RotationTest implements ApplicationListener {
private OrthographicCamera camera;
private SpriteBatch batch;
private Texture texture;
private Sprite sprite;
Stage stage;
public boolean leonAiming = true;
#Override
public void create() {
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
camera = new OrthographicCamera(1, h/w);
batch = new SpriteBatch();
texture = new Texture(Gdx.files.internal("data/libgdx.png"));
texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
TextureRegion region = new TextureRegion(texture, 0, 0, 512, 275);
sprite = new Sprite(region);
sprite.setSize(0.9f, 0.9f * sprite.getHeight() / sprite.getWidth());
sprite.setOrigin(sprite.getWidth()/2, sprite.getHeight()/2);
sprite.setPosition(-sprite.getWidth()/2, -sprite.getHeight()/2); }....
#Override
public void render() {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
batch.begin();
sprite.draw(batch);
batch.end();
First of all you need to fix boundaries to the world (I mean to your game ). In that world only you actors(game characters) should play. If you are crossing boundaries, manage it with camera like showing up, down, left and right.

How to load animation frames as textures in OpenGL ES?

I'm new to OpenGL ES and developing a simple 2D game. However, I'm confused as to how I can go about loading multiple animation frames as textures (for the player character). I've tried to load a different image every time the character is rendered, but that's too slow.
Here is my texture loading code thus far:
public void loadGLTexture(GL10 gl, Context context) {
InputStream[] is=new InputStream[3];
is[0]= context.getResources().openRawResource(R.drawable.r1);
is[1]= context.getResources().openRawResource(R.drawable.r2);
is[2]= context.getResources().openRawResource(R.drawable.r3);
try {
bitmap[0]= BitmapFactory.decodeStream(is[0]);
bitmap[1]= BitmapFactory.decodeStream(is[1]);
bitmap[2]= BitmapFactory.decodeStream(is[2]);
} finally {
try {
is[0].close();
is[1].close();
is[2].close();
is = null;
} catch (IOException e) {
}
}
gl.glGenTextures(3, textures,0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap[0], 0);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap[1], 0);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap[2], 0);
bitmap[0].recycle();
bitmap[1].recycle();
bitmap[2].recycle();
}
How can I make all three images accessible through an array?
You need to call glBindTexture before every texImage2D. Currently you are loading all three images into textures[0].
Don't try to load all textures at once. Change your function to load only one texture and just call it three times. You should be able to do:
textures[0]=loadGLTexture(GL10,context,R.drawable.r1);
textures[1]=loadGLTexture(GL10,context,R.drawable.r2);
textures[2]=loadGLTexture(GL10,context,R.drawable.r3);
You can place all the frames of animation on a single texture and use texture coordinates to select which one to use

Categories

Resources