Will Tuttle
Will Tuttle

Reputation: 450

Libgdx- Positioning actor in table row

I have an an Actor called tile that I'd like to add to a table to make something like a checker board. I can get the tile to draw, however the batch.draw always asks for a position. If I set the position then the tile won't be drawn at the end of the row like I want. For example,

             batch.draw(texture, 0, 0);

Would draw:

enter image description here

As you can see, I have a table with buttons and they line up on the row correctly, since they aren't drawn by position. Is there a way I can get my tile to draw the same way?

Here's my code:

Tile.java

public class Tile extends Actor {

boolean filled;
int row;
int column;
Texture texture;

public Tile(int row, int column){
    this.row = row;
    this.column = column;
    texture = new Texture(Gdx.files.internal("assets/game/tile.png"));

    this.addListener(new InputListener() {
        public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
            System.out.println("down");
            return true;
        }

        public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
            System.out.println("up");
        }
    });
}


@Override
 public void draw (SpriteBatch batch, float parentAlpha) {
        //batch.setColor(0.5f, 0.5f, 0.5f,  1);
         batch.draw(texture, 0, 0);
}

public int getRow(){
    return row;
}

public int getColumn(){
    return column;
}

}

MainScreen.java

public class MainScreen implements Screen {

MyGame myGame;
private final Stage stage;
private final SpriteBatch spriteBatch;
Table table;
private TextureAtlas buttonsUi;
Boolean nextScreen= false;


public MainScreen(MyGame myGame) {
    spriteBatch = new SpriteBatch();
    stage = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false, spriteBatch);
    this.myGame = myGame;

     Gdx.input.setInputProcessor(stage);


    //Create the text label 
    Skin pennySkin = new Skin(Gdx.files.internal("uiskin.json"));
    Label pennyLabel = new Label("PennyPop", pennySkin);

    //Create the sfx and api button button
    ImageButton sfxButton = createSfxButton();
    ImageButton apiButton = createApiButton();
    ImageButton gameButton = createGameButton();


     table = new Table();
     table.add(sfxButton);
     table.add(apiButton).padLeft(10);
     table.add(gameButton).padLeft(10);
     table.add(new Tile(0,0)).padLeft(10); //Tile added here to the row
     table.debug();


     //VericalGroup the buttons and the label
     VerticalGroup vGroup = new VerticalGroup();
     vGroup.addActor(pennyLabel);
     vGroup.addActor(table);

     //Put in another group to align correctly with api widget
    Table rootTable = new Table();
    rootTable.setName("root table");
    rootTable.setFillParent(true);
    rootTable.add(vGroup);
    rootTable.debug();




   //  stage.addActor(pennyLabel);
     stage.addActor(rootTable);
}

@Override
public void dispose() {
    spriteBatch.dispose();
    stage.dispose();
}

@Override
public void render(float delta) {

     Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

    stage.act(delta);
    stage.draw();
    Table.drawDebug(stage);

    if(nextScreen){
        myGame.setScreen(new GameScreen(myGame));
        dispose();
    }
}

@Override
public void resize(int width, int height) {
    stage.setViewport(width, height, false);
}

@Override
public void hide() {
    Gdx.input.setInputProcessor(null);
}

@Override
public void show() {
    Gdx.input.setInputProcessor(stage);
}

@Override
public void pause() {
    // Irrelevant on desktop, ignore this
}

@Override
public void resume() {
    // Irrelevant on desktop, ignore this
}

Upvotes: 2

Views: 2924

Answers (1)

Tenfour04
Tenfour04

Reputation: 93779

Your Tile Actor must set its own size so the Table knows how to place it. Since it's a subclass of Actor, it already has the size fields available for you to fill in (don't create your own height and width variables, which would hide the correct ones).

texture = new Texture(Gdx.files.internal("assets/game/tile.png"));
width = texture.getWidth();
height = texture.getHeight();

Then to draw it, use the x and y fields (also part of the Actor superclass). The Table will set the x and y values for you, so this is all you need to do.

@Override
public void draw (SpriteBatch batch, float parentAlpha) {
    batch.setColor(1, 1, 1, parentAlpha);
    batch.draw(texture, x, y);
}

Note that you must always set color, even if it's white, because its always possible that the batch's color has been left as something non-white by some other thing it has just drawn.

Upvotes: 3

Related Questions