Search code examples
objectlibgdx

LibGDX very strange bug - objects are disappeared


When I was creating my first tiled map creator in libGDX, I noticed a very strange bug. I creating grid of objects like this:

private static final int GRID_WIDTH=2400;
private static final int GRID_HEIGHT=2400;
private static final int CELL_SIZE=60;

so you can see there are 2400/60x2400/60 objects or cells. I am creating my map like this:

private void createMap(){
    cells = new Cell[GRID_WIDTH/CELL_SIZE][GRID_HEIGHT/CELL_SIZE];

    for(int i=0;i<GRID_WIDTH/CELL_SIZE;++i){
        for(int j=0;j<GRID_HEIGHT/CELL_SIZE;++j){
            cells[i][j]=new Cell(textures[0],i*CELL_SIZE,j*CELL_SIZE);
        }
    }
}

I also have coordinates for my debug in the screen so I know where they started to disappear. Y coordinate is ok there are from 0 to 2400, but on the X they started to disappear at 1500. When I start to draw there some texture every column will be visible to that texture for example (when I start to write texture at x=2100 every disappeared column will be visible to 2100) and when I will delete that texture every column will disappear again to 1500. So the objects are there but they are not visible. It is so annoying does anyone know about this bug?

As you can see coordinates are at the bottom left this is at the beginning:

enter image description here

and this is when I will add there some texture

enter image description here

[Edited] Code with camera:

        private float x=GRID_WIDTH/2,y=GRID_HEIGHT/2;

        @Override
        public void render(float delta) {
            batch = new SpriteBatch();
            camera=new OrthographicCamera(CAM_WIDTH,CAM_HEIGHT);
            viewPos = new Vector3();

            Gdx.gl.glClearColor(0, 0, 0, 1);
            Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
            viewPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
            camera.unproject(viewPos);

            batch.begin();

            if(Gdx.input.isKeyPressed(Input.Keys.RIGHT) || Gdx.input.isKeyPressed(Input.Keys.D))
                x+=SPEED*Gdx.graphics.getDeltaTime();
            if(Gdx.input.isKeyPressed(Input.Keys.LEFT) || Gdx.input.isKeyPressed(Input.Keys.A))
                x-=SPEED*Gdx.graphics.getDeltaTime();
            if(Gdx.input.isKeyPressed(Input.Keys.UP) || Gdx.input.isKeyPressed(Input.Keys.W))
                y+=SPEED*Gdx.graphics.getDeltaTime();
            if(Gdx.input.isKeyPressed(Input.Keys.DOWN) || Gdx.input.isKeyPressed(Input.Keys.S))
                y-=SPEED*Gdx.graphics.getDeltaTime();
            stage.act(Gdx.graphics.getDeltaTime());
            stage.draw();

            camera.position.set(x,y,0);
            camera.update();
            batch.setProjectionMatrix(camera.combined);
            batch.end();
      }

Solution

  • The camera is correct. The problem is the batch.begin() and batch.end(). As you might know you cannot do batch.begin() and then shaperenderer.begin() directly after each others without closing one of them. Reason for this I am not 100% about. stage works similar. This means we have to close the batch before drawing the stage

    batch.end();
    stage.draw();
    batch.begin();
    // draw your batch stuff here
    

    Also it's terrible to do this

    batch = new SpriteBatch();
    camera=new OrthographicCamera(CAM_WIDTH,CAM_HEIGHT);
    

    inside the render method. Instead, put it into the create() method or some of your own initialize method. The important thing is to not create a new SpriteBatch every frame as the batch isn't collected by the GC. So you have to manually dispose it using batch.dispose() or it will leak so much memory your RAM will be gone in no time.

    I hope this helped you out, good luck.