LibGDX - 让演员水平填充 parent

LibGDX - make actors fill the parent horizontally

我不知道如何用 LibGDX 制作 jrpg-like 菜单。 我有我需要的所有元素,一张英雄图片,一个带有英雄统计数据的 verticalGroup 和第三个 verticalGroup,它目前只包含一个测试按钮。

问题是元素真的很小,我想让它们均匀分布在整个宽度上。

game screenshot

package com.mygdx.game.UI;

import com.badlogic.gdx.scenes.scene2d.ui.Window;
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
import com.badlogic.gdx.utils.Align;
import com.mygdx.game.Entities.Entity;
import com.mygdx.game.Map.Map;

import Utility.Utility;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.ui.HorizontalGroup;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup;

public class BottomMenu extends Window {
    private static final String TAG = BottomMenu.class.getSimpleName();

    private static String title = "";
    private String unknownHeroImageLocation = "sprites/gui/portraits/unknown.png";

    private Image heroImage;

    //identifier labels
    private Label hpLabel;
    private Label mpLabel;
    private Label xpLabel;
    private Label levelLabel;
    private Label iniLabel;

    //value labels
    private Label hp;
    private Label mp;
    private Label xp;
    private Label levelVal;
    private Label iniVal;
    private Label heroNameLabel;

    private Entity linkedEntity;

    private static final float BOTTOMMENUHEIGHTTILES = 6;
    private static final float BOTTOMMENUWIDGETS = 3;


    //Attributes
    private int heroLevel;
    private int heroHP;
    private int heroMP;
    private int heroXP;
    private int heroINI;


    private HorizontalGroup bottomMenuTable;

    public BottomMenu(Entity[] entities){
        super(title, Utility.STATUSUI_SKIN);

        linkUnitsToMenu(entities);
        initElementsForUI();
        configureElements();
        addElementsToWindow();
    }

    private void linkUnitsToMenu(Entity[] entities) {
        for(Entity entity : entities) {
            entity.setbottomMenu(this);
        }
    }

    private void initElementsForUI() {
        this.debug();
        //hero name
        heroNameLabel = new Label("", Utility.STATUSUI_SKIN, "inventory-item-count");
        heroNameLabel.setColor(Color.CYAN);
        heroNameLabel.setScale(20.0f);

        changeHeroImage(unknownHeroImageLocation);

        //groups
        bottomMenuTable = new HorizontalGroup();
        //bottomMenuTable.align(Align.center);
        bottomMenuTable.setFillParent(true);
        this.setTransform(true);
        this.setPosition(0, 0);

        //labels
        hpLabel = new Label(" hp:", Utility.STATUSUI_SKIN);
        hp = new Label("", Utility.STATUSUI_SKIN);
        mpLabel = new Label(" mp:", Utility.STATUSUI_SKIN);
        mp = new Label("", Utility.STATUSUI_SKIN);
        xpLabel = new Label(" xp:", Utility.STATUSUI_SKIN);
        xp = new Label("", Utility.STATUSUI_SKIN);
        levelLabel = new Label(" lv:", Utility.STATUSUI_SKIN);
        levelVal = new Label("", Utility.STATUSUI_SKIN);
        iniLabel = new Label(" ini:", Utility.STATUSUI_SKIN);
        iniVal = new Label("", Utility.STATUSUI_SKIN);
    }

    private void changeHeroImage(String heroImageLink) {
        Utility.loadTextureAsset(heroImageLink);
        TextureRegion tr = new TextureRegion(Utility.getTextureAsset(heroImageLink));
        TextureRegionDrawable trd = new TextureRegionDrawable(tr);
        if(heroImage != null) {
            trd.setMinHeight(this.getHeight());
            trd.setMinWidth(this.getWidth() / BOTTOMMENUWIDGETS);
            heroImage.setDrawable(trd);
        }else {
            trd.setMinHeight(this.getHeight());
            trd.setMinWidth(this.getWidth() / BOTTOMMENUWIDGETS);
            heroImage = new Image(trd);
        }
    }

    private void configureElements() {
        defaults().expand().fill();
    }

    private void addElementsToWindow() {
        this.add(bottomMenuTable);

        bottomMenuTable.addActor(heroImage);
        heroImage.debug();

        Table statsGroup = new Table();

        statsGroup.setHeight(this.getHeight());
        statsGroup.setWidth(this.getWidth() / BOTTOMMENUWIDGETS);

        statsGroup.add(heroNameLabel);
        statsGroup.row();

        statsGroup.add(hpLabel);
        statsGroup.add(hp);
        statsGroup.row();

        statsGroup.add(mpLabel);
        statsGroup.add(mp);
        statsGroup.row();

        bottomMenuTable.addActor(statsGroup);
        statsGroup.debug();

        VerticalGroup smallMenu = new VerticalGroup();

        smallMenu.setHeight(this.getHeight());
        smallMenu.setWidth(this.getWidth() / BOTTOMMENUWIDGETS);

        smallMenu.addActor(new TextButton("test", Utility.STATUSUI_SKIN));
        bottomMenuTable.addActor(smallMenu);
        smallMenu.debug();
    }

    public void setHero(Entity entity) {
        if(entity != null) {
            if(entity.getName() != heroNameLabel.getText().toString()) {
                this.linkedEntity = entity;
                initiateHeroStats();
                populateElementsForUI(entity);
            }
        }else {
            resetStats();
        }
    }

    private void initiateHeroStats() {
        heroLevel = this.linkedEntity.getLevel();
        heroHP = this.linkedEntity.getHp();
        heroMP = this.linkedEntity.getMp();
        heroXP = this.linkedEntity.getXp();
        heroINI = this.linkedEntity.getIni();
    }

    private void populateElementsForUI(Entity entity) {
        heroNameLabel.setText(entity.getName());
        changeHeroImage(entity.getPortraitPath());
        updateLabels();
    }

    private void resetStats() {
        heroNameLabel.setText("");
        hp.setText("");
        mp.setText("");
        xp.setText("");
        levelVal.setText("");
        iniVal.setText("");
        changeHeroImage(unknownHeroImageLocation);
    }

    public void update() {
        Gdx.app.debug(TAG, "updating bottom menu UI");
        updateStats();
        updateLabels();
        updateSize();
    }

    private void updateLabels() {
        hp.setText(String.valueOf(heroHP));
        mp.setText(String.valueOf(heroMP));
        xp.setText(String.valueOf(heroXP));
        levelVal.setText(String.valueOf(heroLevel));
        iniVal.setText(String.valueOf(heroINI));
    }

    private void updateStats() {
        if(linkedEntity != null) {
            heroLevel = linkedEntity.getLevel();
            heroHP = linkedEntity.getHp();
            heroMP = linkedEntity.getMp();
            heroXP = linkedEntity.getXp();

            if(linkedEntity.getEntityactor().getIsHovering()) {
                this.setVisible(true);
            }
        }
    }

    private void updateSize() {
        int scaledWidth = Gdx.graphics.getWidth();
        int scaledHeight = (int) (BOTTOMMENUHEIGHTTILES * Map.TILE_HEIGHT_PIXEL);
        this.setSize(scaledWidth,scaledHeight);
        bottomMenuTable.setSize(scaledWidth,scaledHeight);
    }
}
  • 将所有 Vertical/HorizontalGroups 更改为 Table。
  • 检查 Table 单元格上的 fillX/expandX 方法。