Drawing Overlapping Images in Libgdx with a Table - java

Basically, I'm trying to draw an empty health bar as an image, and then the actual health bar on top of it as another image so that I can just shorten the actual health bar when I need to update it. This is what I have so far:
TextureAtlas HUDatlas = new TextureAtlas(Gdx.files.internal("data/ui/HUDPack/textures.pack"));
emptyPlayerHealthBar = new Image(HUDatlas.findRegion("empty-health-bar"));
playerHealthBar = new Image(HUDatlas.findRegion("health-bar"));
//Creating the table
table = new Table(skin);
table.debug();
table.setBounds(0, 0, Gdx.graphics.getWidth(), 50);
table.left();
table.top();
table.add(playerHealthBar);
table.add(emptyPlayerHealthBar);
stage.addActor(table);
But this draws them side-by-side. How do I draw it so that the images are overlapping (empty-health-bar on the bottom and health-bar on top)?

I used this code to place a diamond over a box:
Image boxImage = new Image(Assets.instance.gifts.box);
Image diamondImage = new Image(Assets.instance.gifts.diamond);
Stack diamondBox = new Stack();
diamondBox.addActor(boxImage);
diamondBox.addActor(diamondImage);
tbl.add(diamondBox).width(20).height(20);
tbl.row();

You should probably use Scene2D's WidgetGroup (or, if you're not using layout managers, e.g. Table, Group) for that, e.g.
TextureAtlas HUDatlas = new TextureAtlas(Gdx.files.internal("data/ui/HUDPack/textures.pack"));
emptyPlayerHealthBar = new Image(HUDatlas.findRegion("empty-health-bar"));
playerHealthBar = new Image(HUDatlas.findRegion("health-bar"));
// creating the group
WidgetGroup group = new WidgetGroup();
group.addActor(playerHealthBar);
group.addActor(emptyPlayerHealthBar);
// creating the table
table = new Table(skin);
table.setBounds(0, 0, Gdx.graphics.getWidth(), 50);
table.debug().left().top().add(group);
stage.addActor(table);
Note that you can offset those bars simply by using .setPosition() on them, as usual with libGDX's 2.5D objects. Also, you can make your libGDX code more concise by using method chaining, although that's mostly a matter of style.

Related

Libgdx table setBackground does nothing

I made .pack file and load it to skin. I can set it as drawable for Image class and it works fine. But Table.setBackground do nothing.
Drawable background = skin.getDrawable("tooltip_background");
tooltipGroup.setBackground(background);
Why this code not work?
Full code:
tooltipGroup = new Table(skin);
tooltipGroup.setWidth(w/6);
Label.LabelStyle headerStyle = new Label.LabelStyle(headerFont, Color.GREEN);
Label headerLabel = new Label(effect.getName(), headerStyle);
headerLabel.setWidth(w/6);
headerLabel.setX(20);
headerLabel.setWrap(true);
headerLabel.setAlignment(Align.topLeft);
tooltipGroup.addActor(headerLabel);
Label.LabelStyle style = new Label.LabelStyle(font, Color.WHITE);
Label descriptionLabel = new Label(effect.getDescription(), style);
descriptionLabel.setWidth(w/6);
descriptionLabel.setWrap(true);
descriptionLabel.setAlignment(Align.topLeft);
descriptionLabel.setPosition(20, -descriptionLabel.getHeight());
tooltipGroup.addActor(descriptionLabel);
tooltipGroup.setPosition(mouseX, h - mouseY);
Drawable background = skin.getDrawable("tooltip_background");
tooltipGroup.setBackground(background);
stage.addActor(tooltipGroup);
Don't use addActor on the Table. In order to add Actors to the table, use the add method, and specify custom parameters like fill or width / height of the actors in chaining methods. Like this, you can control how you add the actors to the table, since the table does auto layouting.
Table rootTable = new Table();
rootTable.setFillParent(true);
TextField fieldFirst = new TextField("First", skin);
TextField fieldSecond = new TextField("Second", skin);
rootTable.add("First:");
rootTable.add(fieldFirst).width(100).row();
rootTable.add("Second:");
rootTable.add(fieldSecond).width(100);
stage.addActor(rootTable);
As you can see, this allows you to specify the width, in the table, with the expand(), and fill() methods, you can even have an element fill all the available space within one row. Once you use this auto layouting of your table, the table should have the appropriate size, and your background should show. More on how to use the libGdx table layouting can be found here.

Jgraphx styles applied to circleLayout

I'm using JGraphX to draw a graph,using mxCircleLayout as basic representation, but I want to change some behavior. For example I want the EDGESTYLE_TOPTOBOTTOM, so before build mxGraphComponent I define a new edge style:
'
JGraphXAdapter graphAdapter = new JGraphXAdapter(this.stradario.getStradario());
graphAdapter.getModel().beginUpdate();
try {
Map<String, Object> edgeStyle = new HashMap<String, Object>();
edgeStyle = graphAdapter.getStylesheet().getDefaultEdgeStyle();
edgeStyle.put(mxConstants.STYLE_EDGE, mxConstants.EDGESTYLE_TOPTOBOTTOM);
mxStylesheet stylesheet = new mxStylesheet();
stylesheet.setDefaultEdgeStyle(edgeStyle);
graphAdapter.setStylesheet(stylesheet);
} finally {
graphAdapter.getModel().endUpdate();
}
mxCircleLayout layout = new mxCircleLayout(graphAdapter);
layout.execute(graphAdapter.getDefaultParent());
mxGraphComponent graphComponent = new mxGraphComponent(graphAdapter);
graphComponent.getViewport().setBackground(Color.white);
'
The graph was drawn as a circle layout, but edges are not in TOPTOBOTTOM style.
First draw
Then, if I draw a new edge, or I change an existing one, the edge is drawn with TOPTOBOTTON style.
Modified edge take the TOPTOBOTTOMSTYLE
I don't understand why the initial drawn is without TOPTOBOTTOM style and the modified edge was done with the new style.
The layout disables edge styles by default. Set the disableEdgeStyle member to false.
mxCircleLayout layout = new mxCircleLayout(graphAdapter);
layout.setDisableEdgeStyle(false);
layout.execute(graphAdapter.getDefaultParent());

LibGDX loading scene2D widgets very slow for first time, need suggestions

I started using scene2D in my LibGDX game to make a more professional looking login/register menu. The only problem is that switching to those menus is very long for menu navigation (3-5 sec).
I want to know if there is a better way to load them before hand, like during the game's initial loading screen. The thing is that once one of the menus is loaded, it loads very quick the second time.
I know for sure that its the create method of my screens that takes this long. Here is all that it is loading:
public void create(){
stage = new Stage(new StretchViewport(1920, 1080));
Gdx.input.setInputProcessor(stage);
loginBox = new Image(Textures.Gui.BOX);
loginBox.setSize(650, 1000);
loginBox.setPosition(635, 40);
stage.addActor(loginBox);
loginLBL = new Label("Login", Archipelo.SKIN, "basic-large-font", Color.LIGHT_GRAY);
loginLBL.setPosition(880, 955);
stage.addActor(loginLBL);
selectionHighlight = new Image(Textures.Gui.SELECTION_HIGHLIGHT);
selectionHighlight.setSize(540, 140);
stage.addActor(selectionHighlight);
usernameTF = new TextField("", Archipelo.SKIN);
usernameTF.setMaxLength(24);
usernameTF.setPosition(usernameTFx, usernameTFy);
usernameTF.setSize(400, 60);
stage.addActor(usernameTF);
passwordTF = new TextField("", Archipelo.SKIN);
passwordTF.setPasswordMode(true);
passwordTF.setPasswordCharacter('•');
passwordTF.setPosition(passwordTFx, passwordTFy);
passwordTF.setSize(400, 60);
stage.addActor(passwordTF);
usernameLBL = new Label("Username", Archipelo.SKIN, "basic-medium-font", new Color(1, 1, 1, 0.5f));
usernameLBL.setPosition(usernameTFx + 10, usernameTFy + 5);
stage.addActor(usernameLBL);
passwordLBL = new Label("Password", Archipelo.SKIN, "basic-medium-font", new Color(1, 1, 1, 0.5f));
passwordLBL.setPosition(passwordTFx + 10, passwordTFy + 5);
stage.addActor(passwordLBL);
remember = new CheckBox(" Remember Login?", Archipelo.SKIN);
remember.setPosition(rememberX, rememberY);
remember.getCells().get(0).size(30, 30);
stage.addActor(remember);
errorLBL = new Label("", Archipelo.SKIN, "basic-small-font", Color.RED);
errorLBL.setPosition(750, 650);
errorLBL.setWrap(true);
errorLBL.setBounds(750, 500, 400, 250);
stage.addActor(errorLBL);
continueLBL = new Label("Continue", Archipelo.SKIN, "basic-big-font", Color.WHITE);
continueLBL.setPosition(875, 100);
stage.addActor(continueLBL);
}
Also, I load the uiskin files before in the game's initial loading screen. Archipelo.SKIN is a static variable that refers to that uiskin. I also wanted to mention that my screen class is custom made and that whenever create() is called it is because a new screen instance is being created.
The thing that I don't get is why it takes so long to create the screen the first time and then every other time, it still goes through the same process except its much faster. Is there a way to make it faster the first time?
Thanks in advance. If you need more info by all means ask.
To summarize the comments...
The OP had a convenience class for texture references, that listed the textures like this:
public class Gui {
public static final Texture BOX = new Texture("box.png");
public static final Texture SELECTION_HIGHLIGHT= new Texture("selectionHighlight.png");
//...
}
Since they are declared static, they are members of the class, not an instance of a class. Static members of a class are all initialized at once, but only the first time the class or an instance of the class is accessed. This setup results in all the Gui textures getting loaded all at once at some inopportune, unplanned time.
The Texture's constructor Texture(String filename) causes a texture to be loaded from a file, which is time-consuming, so the loading of the Gui class takes a few seconds.
The solution is to not instantiate member texture variables in their declaration. Instantiate them within some method so you can decide exactly when they should be loaded.

Drawing table borders in libgdx 0.9.7

I am drawing a table in using libgdx game framework. Everything is rendered perfectly what I was trying to achieve. All I need now is to display cell borders of the table but I found nothing regarding this so far. I am also inclined to use the debug border lines to fullfill the purpose but also could not change the color of them.
Here is my code.
Table table = new Table();
table.setFillParent(true);
table.left().top();
table.add(new Label("Results", new LabelStyle(font, Color.BLACK))).colspan(2).expandX();
table.row();
table.add(new Label(text_you_score, new LabelStyle(font, Color.BLACK)));
table.add(new Label(text_actual_score, new LabelStyle(font, Color.BLACK)));
return table;
There are many properties available for the table and cell but not the border property.
We can also draw grid lines manually but that won't work perfectly on every device resolution I think. Any help or idea is highly appreciated. Thanks
This is based on libGDX 1.5.3:
A solution to this is to use a NinePatch as the background image for your Table.
NinePatch patch = new NinePatch(new Texture(Gdx.files.internal("background.png")),
3, 3, 3, 3);
NinePatchDrawable background = new NinePatchDrawable(patch);
Table table = new Table();
table.setBackground(background);
Using the number variables, you can modify the border radius. Make sure that this matches the png file.
Register your table for debug mode
table.debug();
Call in render() method
Table.drawDebug(stage);
Example
I achieved the display of the debug lines by converting from using a ShapeRenderer with the table.drawDebug(shapeRenderer shapes) call (which I couldn't get to work) to using a stage and adding the table as an actor.
The example linked in the answer above does show it clearly, but here is a short snippet for reference sake. This is on libGDX 1.5.3.
public class MyGdxGame extends ApplicationAdapter {
Texture img;
Stage stage;
#Override
public void create () {
img = new Texture("badlogic.jpg");
stage = new Stage();
final Skin skin = new Skin();
Label.LabelStyle style = new Label.LabelStyle(new BitmapFont(),Color.WHITE);
TextField.TextFieldStyle textFieldStyle = new TextField.TextFieldStyle();
textFieldStyle.fontColor = Color.WHITE;
textFieldStyle.font = new BitmapFont();
skin.add("default", style);
skin.add("default", textFieldStyle);
// Keep your code clean by creating widgets separate from layout.
Label nameLabel = new Label("Name:", skin);
TextField nameText = new TextField("",skin);
Label addressLabel = new Label("Address:", skin);
TextField addressText = new TextField("",skin);
Table table = new Table();
table.add(nameLabel); // Row 0, column 0.
table.add(nameText).width(100); // Row 0, column 1.
table.row(); // Move to next row.
table.add(addressLabel); // Row 1, column 0.
table.add(addressText).width(100); // Row 1, column 1.
table.setOriginX(0);
table.setOriginY(0);
table.setX(200);
table.setY(200);
table.debug();
stage.addActor(table);
}
#Override
public void render () {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
}
public void resize (int width, int height) {
stage.getViewport().update(width, height, true);
}
public void dispose () {
stage.dispose();
}
}

How to create widget like google maps in GWT?

I need to create widget, similar to google maps one.
In it's simplest form, the map of all planet is divided into image tiles. While user scrolls the widget into different directions, new empty cells appeared and widget requests these tiles from the server and put it into the widget.
How it can be implemented in GWT?
I found no way to set absolute position dynamically in ScrollPanel. I found no way to draw something lefter than left or upper then top in AbsolutePanel. How to combine panels correctly?
Thanks.
UPDATE 1
Here is one of the examples. In this example labels do not show, because the size of containing absolute panel is zero by height (looked in firebug). I can't just set it's size because this won't help for label at -100,-100.
public void onModuleLoad() {
Label label_minus100_minus100 = new Label("(-100,-100)");
Label label_0_0 = new Label("(0,0)");
Label label_100_100 = new Label("(100,100)");
AbsolutePanel absolutePanel = new AbsolutePanel();
absolutePanel.setStyleName("absolutePanel");
absolutePanel.add(label_0_0, 0, 0);
absolutePanel.add(label_minus100_minus100, -100, -100);
absolutePanel.add(label_100_100, 100, 100);
DOM.setStyleAttribute(absolutePanel.getElement(), "overflow", "visible");
ScrollPanel scrollPanel = new ScrollPanel();
scrollPanel.add(absolutePanel);
scrollPanel.setStyleName("scrollPanel");
RootPanel rootPanel = RootPanel.get();
rootPanel.add(scrollPanel);
}

Categories

Resources