简体   繁体   中英

Position Child Actor relative to Stage and NOT Parent

I have HorizontalGroup with actors added to it. When I tap an actor, I want it to pop up in the center of the screen with (pseudocode)

Gdx.graphics.getWidth()/2 - myActor.getWidth()/2;
Gdx.graphics.getHeight()/2 - myActor.getHeight()/2;

The problem is that the actor is getting position relative to the parent and not the stage/screen.

How could I go about solving this?

There are quite a few possibilities to solve your question.

  1. Transform the screen coordinates to stage coordinates (skip if they are the same) then transform the stage coordinates to the group coordinates, then set the actor to the transformed position

     vector = stage.screenToStageCoordinates(vector); vector = group.stageToLocalCoordinates(vector); actor.setPosition(vector.x, vector.y); 
  2. Add a Stack to your stage, add already existing group to it, then if you tap on the actor add it to the stack (this automatically removes it from its old parent)

     Stack stack = new Stack(); stage.addActor(stack); stack.add(yourGroup); // then on tap stack.add(actor); 
  3. Disable the group layout, so if you manipulate the actor, the group layout is not calculated again, plus disable child transformation to parent coordinates:

     group.setLayoutEnabled(false); group.setTransform(false); 

    You might enable the layout/transformation again, later.

  4. Similar to 2., but add the actor the stage and set the position to the center

     // then on tap stage.addActor(actor); actor.setPosition( (stage.getWidth() - actor.getWidth()) / 2f, (stage.getHeight() - actor.getHeight()) / 2f); 

Depending on your setup some solutions might not work as expected.


Here an example of 4.:

public class TestGame extends ApplicationAdapter
{
    private Skin    skin;
    private Stage   stage;
    private Texture t;

    @Override
    public void create()
    {
        skin = new Skin(Gdx.files.internal("uiskin.json"));

        t = new Texture(Gdx.files.internal("badlogic.jpg"));

        // So we see everything
        stage = new Stage(new ExtendViewport(4000, 400));

        HorizontalGroup hGroup = new HorizontalGroup();
        hGroup.setFillParent(true);

        // So that the hGroup is on top
        Table filler = new Table(skin);
        filler.setFillParent(true);
        filler.add(hGroup).fill().center();

        stage.addActor(filler);

        for (int i = 0; i < 10; i++)
        {
            final ImageButton b = new ImageButton(
                    new TextureRegionDrawable(new TextureRegion(t)));
            b.addListener(new ClickListener()
            {

                @Override
                public void clicked(InputEvent event, float x, float y)
                {
                    if (b.getParent().equals(hGroup))
                    {
                        stage.addActor(b);
                        b.setPosition(
                                (stage.getWidth() - b.getWidth()) / 2f,
                                (stage.getHeight() - b.getHeight()) / 2f);
                    } else
                    {
                        hGroup.addActor(b);
                    }
                }
            });
            hGroup.addActor(b);
        }

        Gdx.input.setInputProcessor(stage);
    }

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

    @Override
    public void render()
    {
        Gdx.gl.glClearColor(0f, 0f, 0f, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        stage.act();
        stage.draw();
    }

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM