Search code examples
libgdxtexturesspritespritebatch

libgdx - Render two textures side by side using SpriteBatch and use one camera


I want to render two textures side by side. And then consider such combination of these two textures as one sprite to use a single camera. I am able to render two textures side by side using SpriteBatch. How do I make the combination of these two textures into a single sprite and use camera to get different views?

Currently after I drew two textures with SpriteBatch, I'm trying to draw such SpriteBatch with a sprite. But I'm getting nullpointer when calling sprite.draw().

My ultimate goal is to render two images side by side to use as a background, and be able to use a camera on my background. Any ideas? THX

My current code:

public void create () {
    batch = new SpriteBatch();
    //create two texture for 1.jpg and 2.jpg
    //use batch to draw them separately at different position
    img_1 = new Texture("1.jpg"); 
    img_2 = new Texture("2.jpg"); 

    mWorld = new Sprite();
    mWorld.setPosition(0, 0);
    mWorld.setSize(WORLD_WIDTH,WORLD_HEIGHT);
    float aspectRatio = (float)Gdx.graphics.getHeight() / (float)Gdx.graphics.getWidth();
    camera = new OrthographicCamera(VIEWPORT_WIDTH, VIEWPORT_WIDTH * aspectRatio);
    camera.position.set(camera.viewportWidth / 2f, camera.viewportHeight / 2f, 0);
    camera.update();
}

@Override
public void render () {
    batch.setProjectionMatrix(camera.combined);
    batch.begin();
    batch.draw(this.img_1, 0, 0, WORLD_WIDTH/2, WORLD_HEIGHT);
    batch.draw(this.img_2, WORLD_WIDTH/2, 0, WORLD_WIDTH/2, WORLD_HEIGHT);

    //getting java nullpointer exception here
    mWorld.draw(batch);
    batch.end();
}

Solution

  • Sprite is simply a wrapper (to add more functionality) for a single Texture (or TextureRegion).

    You just call "new Sprite();" which creates a sprite with no texture (so nothing to draw, no image information, etc), thus you get a null pointer exception when you try to draw the sprite.

    Since you want to combine two textures, why not create a single texture (image) with an external tool (like pain.net or gimp,..)?

    If you want to draw two textures as a single object, you need to create your own class, for example:

    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.Texture;
    import com.badlogic.gdx.graphics.g2d.Batch;
    import com.badlogic.gdx.graphics.g2d.SpriteBatch;
    
    public class TestGame extends ApplicationAdapter
    {
    
        public class TwoTextures
        {
            private final Texture   tex1, tex2;
            private final float     pos1X, pos1Y, pos2X;
    
            public TwoTextures(Texture tex1, Texture tex2, float posX, float posY)
            {
                this.tex1 = tex1;
                this.tex2 = tex2;
                this.pos1X = posX;
                this.pos1Y = posY;
    
                this.pos2X = posX + tex1.getWidth();
            }
    
            public void draw(Batch batch)
            {
                batch.draw(tex1, pos1X, pos1Y);
                batch.draw(tex2, pos2X, pos1Y);
            }
    
            public void dispose()
            {
                tex1.dispose();
                tex2.dispose();
            }
        }
    
        OrthographicCamera  camera;
    
        Batch               batch;
    
        TwoTextures         background;
    
        @Override
        public void create()
        {
            batch = new SpriteBatch();
            camera = new OrthographicCamera();
    
            background = new TwoTextures(
                    new Texture("1.jpg"),
                    new Texture("2.jpg"),
                    0,
                    0);
        }
    
        @Override
        public void render()
        {
            Gdx.gl.glClearColor(1, 0, 0, 1);
            Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    
            batch.begin();
            {
                background.draw(batch);
            }
            batch.end();
        }
    
        @Override
        public void dispose()
        {
            batch.dispose();
            background.dispose();
        }
    }