[Solved] Actors drawing white box when stacked together

Anything libgdx related goes here!

[Solved] Actors drawing white box when stacked together

Postby Zebolt » Thu Jun 14, 2018 8:26 am

Good morning everyone,

I'm trying to use Scene2d to render tiledmap, hero and NPCs in a RPG game. I thought of it this way : create a class extending Stage, called MapStage. This stage uses a libgdx Stack to layout the different actors. Here are my actors, in the order in which they are stacked :

1rst actor, bottom of the stack : a Map, extending Actor
2nd actor, top of the stack : a Hero, extending Actor

I just want to achieve that before getting into details (the different layers of the map etc). If I only add the Map to the stack and the stack to the stage, everything's OK
https://ibb.co/gEsfCy

If I only add the Hero to the stack and the stack to the stage, everything's OK
https://ibb.co/kdZ5ed

But if add the Map, then the Hero to the stack and then the stack to the stage, I get this weird white rectangle box :
https://ibb.co/gb4csy

And if I do the same, but I change the rendering location by one pixel in the Hero draw method, i get this:
https://ibb.co/gEsfCy

I bet this is a camera/viewport matter that I don't understand yet... I tried checking the documentation and search this forum and google with the keywords "white box", "white rectangle box", "stage draw issue", "stacking actors".

Here's my code :

ApplicationAdapter
Code: Select all
public class BeforeDawn extends ApplicationAdapter {
   public static final int V_WIDTH = 800;
   public static final int V_HEIGHT = 480;
   MapStage mapStage;
   @Override
   public void create () {
      mapStage = new MapStage("maison1.tmx");
   }
   
   @Override
   public void render () {
      Gdx.gl.glClearColor(1,0,0,1);
      Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
      
      mapStage.draw();
   }
   
   @Override
   public void dispose () {
   }
   
   @Override
   public void resize(int width, int height) {
   }
   
   @Override
   public void pause() {
   
   }
   
   @Override
   public void resume() {
   
   }
}


MapStage
Code: Select all
public class MapStage extends Stage implements Disposable {
   
    private boolean visible = true;
   
    private Hero hero;
    private Map map;
   
   
    public MapStage(String filename){
        Stack stack = new Stack();
        stack.setFillParent(true);
        getViewport().update(Game.V_WIDTH, Game.V_HEIGHT);
   
        hero = new Hero();
        map = new Map(filename);
       
        stack.add(map);
        stack.add(hero);
       
        addActor(stack);
    }
   
    public void draw(){
        act(Gdx.graphics.getDeltaTime());
        if(visible){
            super.draw();
        }
    }
   
    public void setVisible(boolean visible){
        this.visible = visible;
    }
   
    public void dispose(){
   
    }
}


Map
Code: Select all
public class Map extends Actor implements Disposable {
   
    private TmxMapLoader mapLoader;
    private TiledMap map;
    private OrthogonalTiledMapRenderer renderer;
   
    public Map(String filename){
        String buff = new String("maps/" + filename);
        mapLoader = new TmxMapLoader();
        map = mapLoader.load(buff);
        renderer = new OrthogonalTiledMapRenderer(map);
    }
   
    public void draw(Batch batch, float alpha){
        renderer.setView((OrthographicCamera)getStage().getCamera());
        renderer.render();
    }
   
    public void dispose(){
        renderer.dispose();
    }
}


Hero
Code: Select all
public class Hero extends Actor {
    private static final float F_DURATION = 1/5f;
    private TextureAtlas atlas;
    private Direction direction; //simple enumeration of UP, LEFT, DOWN...
    private Animation leftAnim, downAnim, upAnim, rightAnim;
    private float elapsedTime = 0f;
   
    public Hero(){
        this.atlas = new TextureAtlas("charsets/charset.atlas");
        direction = Direction.DOWN;
       
        TextureRegion[] leftFrames = new TextureRegion[4];
        TextureRegion[] downFrames = new TextureRegion[4];
        TextureRegion[] upFrames = new TextureRegion[4];
        TextureRegion[] rightFrames = new TextureRegion[4];
       
        for(int i = 0; i<4; i++){
            leftFrames[i] = atlas.findRegion(String.format("%04d", i+5));
            downFrames[i] = atlas.findRegion(String.format("%04d", i+1));
            upFrames[i] = atlas.findRegion(String.format("%04d", i+13));
            rightFrames[i] = atlas.findRegion(String.format("%04d", i+9));
        }
       
        leftAnim = new Animation(F_DURATION, leftFrames);
        downAnim = new Animation(F_DURATION, downFrames);
        upAnim = new Animation(F_DURATION, upFrames);
        rightAnim = new Animation(F_DURATION, rightFrames);
    }
   
     
    public void draw(Batch batch, float alpha){
        elapsedTime += Gdx.graphics.getDeltaTime();
        if(direction == Direction.LEFT) {
            batch.draw((TextureRegion)leftAnim.getKeyFrame(elapsedTime, true), 0, 0);
            return;
        }
        if(direction == Direction.UP) {
            batch.draw((TextureRegion)upAnim.getKeyFrame(elapsedTime, true), 0, 0);
            return;
        }
        if(direction == Direction.DOWN) {
            batch.draw((TextureRegion)downAnim.getKeyFrame(elapsedTime, true), 0, 0);
            return;
        }
        if(direction == Direction.RIGHT) {
            batch.draw((TextureRegion)rightAnim.getKeyFrame(elapsedTime, true), 0, 0);
            return;
        }
       
       
    }
   
    public void handleInput(){
        Direction buff = Direction.NIL;
        if (Gdx.input.isButtonPressed(Input.Keys.LEFT))
            buff = Direction.LEFT;
        if (Gdx.input.isButtonPressed(Input.Keys.DOWN))
            buff = Direction.DOWN;
        if (Gdx.input.isButtonPressed(Input.Keys.UP))
            buff = Direction.UP;
        if (Gdx.input.isButtonPressed(Input.Keys.LEFT))
            buff = Direction.RIGHT;
       
       
        if(buff != direction)
            elapsedTime = 0f;
       
        direction = buff;
       
    }
}


I'm really stuck on this one. Thanks in advance for your precious help
Best regards
Last edited by Zebolt on Thu Jun 14, 2018 12:24 pm, edited 1 time in total.
Zebolt
 
Posts: 14
Joined: Tue Jun 05, 2018 7:57 am

Re: Actors drawing white box when stacked together

Postby evilentity » Thu Jun 14, 2018 10:35 am

That white part is probably a pixel you are so fond of. If you draw something without specifying size its wrong 99 times out of 100
Looking for a freelancer? PM me!
evilentity
 
Posts: 4502
Joined: Wed Aug 24, 2011 11:37 am

Re: Actors drawing white box when stacked together

Postby Zebolt » Thu Jun 14, 2018 10:57 am

Thanks for your quick answer!
You're right, if I draw my TextureRegion at (-1, -1), the whole screen is white.

I tried setSize on my Hero class and batch.setProjectionMatrix(getStage().getCamera().combined) in its draw method, nothing has changed... Or do you mean I have to specify the size of the TextureRegion I'm drawing ?

##### Solved #####

Ok so this will teach me a lesson about reading documentations with Ctrl+F.

Libgdx wiki, Scene2d
If an actor needs to perform drawing differently, such as with a ShapeRenderer, the Batch should be ended and then begun again at the end of the method.

I applied this to the draw method of my Map actor, and everything's fine again.
Zebolt
 
Posts: 14
Joined: Tue Jun 05, 2018 7:57 am


Return to Libgdx

Who is online

Users browsing this forum: Exabot [Bot], Google [Bot], hoangtunho2611, shatterblast and 1 guest