Scene2d Positioning Components on Stack - libgdx

This is current state: image
But there are 2 more things I want to do:
moving the stack to the top left of the screen
In the image, I divided the parchment into two parts, I want to put 2 labels on the upper part and 2-3 text buttons on the lower part.
related codes:
Table table = new Table();
table.center();
table.setFillParent(true);
Stack stack = new Stack();
titleLabel.setFontScale(0.5f);
label1.setFontScale(0.5f);
textButton.getLabel().setFontScale(0.5f);
textButton2.getLabel().setFontScale(0.5f);
parchment.setScaling(Scaling.fill);
stack.add(parchment);
Table overlay = new Table();
overlay.add(titleLabel).expand();
overlay.row();
overlay.add(label1).expand();
overlay.row();
overlay.add(textButton).expand();
overlay.row();
overlay.add(textButton2).expand();
stack.add(overlay);
table.add(stack).top().left();
stage.addActor(table);

The first thing to do in situations like this is to set debug on any tables you have - you will then be able to see the boundary lines showing how big the table is and how big the cells in the tables are. Simply do this:
table.setDebug(true);
moving the stack to the top left of the screen
With debug set, I can see that your stack isn't filling the whole table or the whole screen. Stacks only grow to fit their contents, they will not fill the their container automatically, so to fill the screen add "expand()" to the Stack's cell in the Table like this:
table.add(stack).expand().top().left();
In the image, I divided the parchment into two parts, I want to put 2 labels on the upper part and 2-3 text buttons on the lower part.
You can do this in one of two ways. You could make a table for each group which would be a good approach if there are lots of items in each group. Or if there are only a few items you can add "expand()" to force the items in the middle to push the other items up/down, like this:
Table table = new Table();
// table.setDebug(true);
table.setFillParent(true);
Stack stack = new Stack();
titleLabel.setFontScale(0.5f);
label1.setFontScale(0.5f);
textButton.getLabel().setFontScale(0.5f);
textButton2.getLabel().setFontScale(0.5f);
parchment.setScaling(Scaling.fill);
stack.add(parchment);
Table overlay = new Table();
// overlay.setDebug(true);
overlay.add(titleLabel).top();
overlay.row();
overlay.add(label1).expand().top();
overlay.row();
overlay.add(textButton).expand().bottom();
overlay.row();
overlay.add(textButton2).bottom();
stack.add(overlay);
table.add(stack).expand().top().left();
stage.addActor(table);

Related

Libgdx Table Layout Logical table not Positioning Correctly

I wants to store a scrollpane in a table. However, the positioning of the images are not as expected.
I have look through this, but has no clue on solving my problem.
The blue box (logical table) of the scrollpane and scrolldetails table is not at the right position. Please help.
My codes goes as below:
scrollDetails = new Table();
scrollDetails.setBackground(skin.getDrawable("gameSelectionBox1"));
scrollDetails.setDebug(true);
Button b = new Button(skin,"arithmetic");
scrollDetails.add(b);
scrollDetails.pack();
sp = new ScrollPane(scrollDetails);
sp.setOverscroll(false,true);
sp.pack();
sp.setDebug(true);
table = new Table();
table.setFillParent(true);
table.bottom().padBottom(100).add(sp).align(Align.center);
table.setDebug(true);
table.pack();
//tried but has no effect
//t.setPosition(0,100);
//sp.setPosition(0,550);
//tt.setPosition(0,100);
stage.addActor(tt);
setFillParent() does not work correctly inside a ScrollPane. Remove the line and it will work as intended.

Libgdx Can you set the bounds of a ScrollPane?

So recently i discovered Scrollpanes and have been trying implement one properly.
After a bit of searching i found this section of code
public void create() {
batch = new SpriteBatch();
skin = new Skin(Gdx.files.internal("data/uiskin.json"));
stage = new Stage();
gamelog = new Label("Start", skin);
gamelog.setAlignment(Align.center);
gamelog.setWrap(true);
Table scrollTable = new Table();
scrollTable.add(gamelog);
scrollTable.row();
scroller = new ScrollPane(scrollTable);
Table table = new Table();
table.setFillParent(true);
table.add(scroller).fill().expand();
Now for the most part this code works well. a scrollpane is actually created and i can dynamically add text to it. my issue however is the size of the scrollpane takes up the whole screen, and initial text is centered in the middle of the scrollpane(so in the middle of the screen) and only starts to scroll once enough text has been added to take up the whole height of the screen.
Rather than expanding on its own what i actually want is for the scrollpane to take up just a small section at the bottom of the screen.
I have tried setting the bounds of the tables and of the scrollpane but the closest i have come is merely moving the scrollpane downwards(meaning the last text added is off screen and not in view. Its s if it completely ignores any width or height set and just expands on its own.
I figure i could get the desired effect by simply using a set of labels at the bottom of the screen and change their text dynamically but then the scroll feature would be lost. so before i do this i was hoping someone could shed some light on wether or not it is possible to resize and set a scrollpanes bounds?
Table uses cells to size its components. When you add a component to a table it returns the table's cell which holds that component. You can then use the cell to set the size of the component.
In your original code try this:
table.add(scroller).size(460, 200);
And if you want to change the scrollpane size after adding it to the table, you can get the cell from the table and then set its size like this:
table.add(scroller);
...
table.getCell(scroller).size(460, 200);
And here is the API for Cell:
https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/Cell.html
I stumbled across a solution with trial and error.
the following code works for me and allows the scrollpane to be resized and positioned. The main culprit seems to be the use of table.setFillParent(true); and the order in which you try to set the parent tables bounds.
batch = new SpriteBatch();
skin = new Skin(Gdx.files.internal("data/uiskin.json"));
stage = new Stage();
gamelog = new Label("Start", skin);
gamelog.setAlignment(Align.center);
gamelog.setWrap(true);
Table scrollTable = new Table();
scrollTable.add(gamelog);
scrollTable.row();
scroller = new ScrollPane(scrollTable);
Table table = new Table();
table.setBounds(10, 10, 460, 200);
table.add(scroller).fill().expand();
scrollTable.debug();
scroller.debug();
table.debug();
stage.addActor(table);

LibGDX: Scene 2D Table, Is it possible to overlap two actors like an image and a label?

The image below explains what I want to do.
The top diagram represents how I have the arrangement now.
The bottom diagram represents how I want the arrangement. Here is a diagram:
I wish for a label actor to be on top of an image actor.
Can this be done?
Thanks to #noone for guiding me to the stack. Please note my code is apart of a scroll pane. Also note the last item to be added to the stack will be on top. So that's why I add image and then the label.
Image image = new Image(texture);
Label buildingName = new Label(entry.getValue.name, skin, "building");
buildingName.setAlignment(Align.top);
Stack stack = new Stack();
stack.add(image);
stack.add(buildingName);
stack.addListener(buildItemUIListener); //used for click listener
stack.setName(entry.getKey()); //Used for the click listener
table.add(stack);

How to align table in scrollPane top?

I' am making achievements screen in my libgdx game. I want to align my table in scrollPane to top, now it is centred vertically and horizontally and I don't know why. Using .top() method when I've tried to create new row didn't worked.
stage = new Stage();
Gdx.input.setInputProcessor(stage);
outerTable = new Table();
innerTable = new Table();
innerTable.setFillParent(true);
for(int i=0;i<score_bound; i++){
if(i<score_state){
innerTable.row().width(achie_width).height(achie_height).top();
innerTable.add(new Image(ltm.assets.score_textures[i]));
}else{
innerTable.row().width(achie_width).height(achie_height).top();
innerTable.stack(new Image(ltm.assets.score_textures[i]),new Image(ltm.assets.kurtyna));
}
}
for(int i=0;i<letin_bound; i++){
if(i<letin_state){
innerTable.row().width(achie_width).height(achie_height).top();
innerTable.add(new Image(ltm.assets.letin_textures[i]));
}else{
innerTable.row().width(achie_width).height(achie_height).top();
innerTable.stack(new Image(ltm.assets.letin_textures[i]),new Image(ltm.assets.kurtyna));
}
}
scrollPane = new ScrollPane(innerTable);
outerTable.setPosition(0, 0);
outerTable.setSize(Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
outerTable.debug();
outerTable.add(scrollPane).fill().expand();
stage.addActor(outerTable);
I run into the same issue today and came across here, so I might as well post an answer here in case somebody is still looking for an answer.
#peterSweter said top() does not work, what #Rara suggested is the same as calling top.
The only way to achieve something that looks like an align to the top - which only is relevant if the innerTable is smaller - is to increase the size by adding empty elements around it, so the table you pass to the ScrollPane has at least the same size as the scrollPane.
I just wrapped yet another Table around my innerTable reference.
(658 is the fixed height I use for my ScrollPane)
Table spacingTable = new Table();
spacingTable.setHeight(Math.max(innerTable.getHeight(), 658));
spacingTable.add(innerTable);
if (innerTable.getHeight() < 658) {
spacingTable.row();
spacingTable.add().expandY();
}
ScrollPane scroll = new ScrollPane(spacingTable, skin);
In order to achieve what you want, you can wrap your table inside another table and use that table for ScrollPane. Note that when adding your table to container table, you'll need to add some growable, empty cell at the bottom and right side in order to "push" it to top-left (although I believe you can also simply use containerTable.add(myTable).top().left() - but haven't tested it really).
This of course is a much better solution than second's solution, which uses hardcoded height. The thing is, you will usually want to add scroll pane as growable (.grow()), so fixed height/width is useless.

as3: Making an animation

I am playing with animation in AS3 and flex4, and I've come into a problem. My application is a game board (like a chess board), where each field is a border container added to some position.
Also I am adding a child element (shape), to this container on mouse click. What I want to achieve is to be able to move shapes smoothly from one field to another. But it appears that the shape goes behind the neighbor field this way http://screencast.com/t/iZ3DCdobs.
I believe this happens because shape is a child of specific border container, and to make it visible over every other container, I would need to use layers somehow....
I would be happy if anybody could suggest a solution
Yes you're right on that. You should add the movable objects to a different layer.
As there are no typical layers in AS, you could try to drop the fields in one sprite and any other objects to a different an than place them on each other, so that when you will move a object it won't go behind other objects.
If you place both sprites in the same position you will still have accurate x,y positions between movable objects and fields.
You have two options:
First one is to have different layers for your DisplayObjects: as an example, the bottom layer would hold all the boards, and the upper layer would hold all the pieces.
Second option is to manipulate the index of the objects with swapChildren(), swapChildrenAt(), and setChildIndex(). So to bring a MovieClip to the topmost front, you would do MovieClip(parent).setChildIndex(this, 0);
If the situation is that always the shape object gets hidden behind the next ( right side ) grid container, the I suggest you create your grid in reverse.
Suppose you are creating a chess grid. that is a 8x8 grid. Normally you would create your grid using 2 for loops, looping from 0 to 8 with say the x and y points starting at 0,0 for the first grid and going on till the end. What I suggest you to do is to create from 8,8 to 0,0.
Display objects in flash are stacked on top of each other based on their child index.
For example: If you create two objects. Rectangle and Circle as follows
var rect:Rectangle = new Rectangle();
this.addChild(rect);
var circ:Circle = new Circle();
this.addChild(circ);
The circle will always be on top of the rectangle in this scenario because the circle was added after the rectangle to the display list.
So if you reverse the order of creation of your grid, the right grid cell will be added to the display list first and so the grid cells to the left will always be on top of the right ones. Hence, the problem that you are facing will not occur.