2
\$\begingroup\$

I am trying to create a card layout for my trading card game. Right now I use this code:

public class ClientCard extends Table {

    ClientCard(int cost, int attack, int health, String title, String description) {
        Texture texture = new Texture(Gdx.files.internal("data/"+title+".jpg"));
        Image image = new Image(texture);
        this.add(image).width(Gdx.graphics.getWidth() / 10).height(Gdx.graphics.getHeight() / 7).colspan(3);
        this.row();
        Skin skin = new Skin(Gdx.files.internal("skin/glassy-ui.json"));
        Label cardName = new Label(title, skin);
        Label cardDescription = new Label(description, skin);
        Label cardCost = new Label(cost + "", skin);
        Label cardAttack = new Label("", skin);
        Label cardLife = new Label(health + "", skin);
        this.add(cardName).colspan(3).padBottom(5);
        this.row();
        this.add(cardDescription).colspan(3).padBottom(5);
        this.row();
        this.add(cardCost);
        this.add(cardLife);
        this.add(cardAttack);
    }
}

It works, it shows the card data, but it looks pretty bad and it's not very compact, also I can't set the outer border for the Table (table.debug is not good). What I want is something like this:

Card

I want to use scene2d so it's easier to fill the card with the data I want (life, attack etc). Any idea how I could realize this? Thanks!

\$\endgroup\$
  • \$\begingroup\$ Do you want an answer for generic layouts or for this (or another) specific layout? If you want one for this specific layout I can provide a more specific answer. \$\endgroup\$ – Charanor Mar 23 '17 at 15:54
  • \$\begingroup\$ For this specific layout would be great. \$\endgroup\$ – Andy Mar 23 '17 at 16:18
2
\$\begingroup\$

How does this look? (Green and red lines are only there for debugging)

result

What I did to achieve this was to first separate the card into three columns and five rows; then I had the Cost, Life, Attack, and S field occupy the small 1st and 3rd column and the Image, Title, and Description occupy the large 2nd column. I then used a Stack (docs) to stack the table of contents on top of the colorful background image.

The general structure looks something like this in code;

table.add(cost); //col1
table.add(); //Blank! Used only to create col2.
table.add(s); //col3
table.row(); //New row

table.add(); //col1
table.add(image); //Image only occupies col2!
table.add(); //col3
table.row(); // New row

table.add();
table.add(title);
table.add();
table.row();

table.add();
table.add(description);
table.add();
table.row();

table.add(life);
table.add(class);
table.add(attack);

stage.addActor(new Stack(background, table));

But this of course won't size the cells to the correct size. The exact size of the cells will depend on what your layout looks like but for this layout I decided that all red fields will have a width and height of 75. With that in mind the exact code used looked like this:

/* Adds the "Cost" label and centers its text. */
table.add("Cost").width(75).height(75).getActor().setAlignment(Align.center);
/* Important! Adds a column between "Cost" and "S". Used to
 * align "Image", "Title", "Description", and "Class". */
table.add();
/* Same as "Cost". */
table.add("S").width(75).height(75).getActor().setAlignment(Align.center);
table.row();

/* Add "Image" to middle column with a height of 50% of the
 * background's height minus 75 (the top columns height). */
table.add();
table.add("Image").growX().height(Value.percentHeight(.5f).get(background) - 75)
                  .getActor().setAlignment(Align.center);
table.add();
table.row();

/* Add "Title".*/
table.add();
table.add("Title").grow().getActor().setAlignment(Align.center);
table.add();
table.row();

/* Add "Description". */
table.add();
table.add("Description").grow().getActor().setAlignment(Align.center);
table.add();
table.row();

/* Add "Life", "Class", and "Attack". Same deal as "Cost" and
 * "S" */
table.add("Life").width(75).height(75).getActor().setAlignment(Align.center);
table.add("Class").growX().fillY().getActor().setAlignment(Align.center);
table.add("Attack").width(75).height(75).getActor().setAlignment(Align.center);

/* Used to show the table above the background image. You
 * should probably use Table#setBackground(drawable)
 * instead of using a stack! */
final Stack stack = new Stack(background, table);
stack.setSize(background.getWidth(), background.getHeight());
stage.addActor(stack);

/*Shows the green and red outlines. ONLY FOR DEBUGGING!*/
stage.setDebugAll(true);

Some of the grow(), expand() and fill() calls might be unnecessary - you'd have to experiment for yourself. If you have any questions just leave a comment and I'll try to answer them :)

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thanks, the layout seems to be fine. Any idea how can i set the background and border of the table, and the background for specific cells? \$\endgroup\$ – Andy Mar 24 '17 at 13:09
  • \$\begingroup\$ Unless you absolutely need to have images for every single cell I would highly recommend having whole card templates and use this as your background. Look at these hearthstone templates to see what I mean. This template can also include the border. You can set the background of a table with Table#setBackground(drawable). \$\endgroup\$ – Charanor Mar 24 '17 at 13:59
  • \$\begingroup\$ So I should use a single image as the template for my card and set it as the table background and then write the text and display the card artwork on top of it? \$\endgroup\$ – Andy Mar 24 '17 at 14:16
  • \$\begingroup\$ Exactly, this is what I would suggest anyways as it's simple and it seems to work very well (once again; Hearthstone). Basically just replace the current colorful background with your finished background :) \$\endgroup\$ – Charanor Mar 24 '17 at 15:08
  • \$\begingroup\$ That's something you'd have to decide for yourself but I'd say in that case you should only combine the card template and card artwork - not title and description since you might want to change those at a later date (e.g. you realize that "When attacked: deal 3 damage" is too strong and wish to change it to 1 damage instead. Now you'd have to edit the image instead of just changing the text). \$\endgroup\$ – Charanor Mar 24 '17 at 16:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.