Libgdx游戏编程之卡牌游戏UI布局

本文详细介绍了如何利用LibGDX库中的Stage、Table、Stack等组件,结合TextureAtlas资源,构建复杂的UI布局。包括头像、等级、金币、钻石、底部菜单等多个元素的展示,并展示了具体代码实现过程。
摘要由CSDN通过智能技术生成

先上效果:

准备素材:

素材准备好,使用GDX Texture Packer打包

 整体布局采用Stack + Table,每层都使用Table来绘制不同的元素

package com.mygdx.game.ui;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Button;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.Stack;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
import com.badlogic.gdx.utils.Disposable;
import com.badlogic.gdx.utils.viewport.FitViewport;

public class GameHUD implements Disposable {
    private static final String TAG = GameHUD.class.getSimpleName();
    private GameUIDemo game;
    private Stage stage;
    private OrthographicCamera camera;
    private FitViewport viewport;
    private TextureAtlas atlas;
    private BitmapFont font;

    public GameHUD(GameUIDemo game){
        this.game = game;

        //加载资源
        atlas = new TextureAtlas(Gdx.files.internal("ui/gameui.atlas"));

        font = new BitmapFont();
        font.setColor(Color.WHITE);

        //创建舞台
        camera = new OrthographicCamera();
        viewport = new FitViewport(GameUIDemo.V_WIDTH, GameUIDemo.V_HEIGHT, camera);
        stage = new Stage(viewport, game.batch);

        //创建多层布局框架
        Stack layout = new Stack();
        layout.setFillParent(true);

        //绘制头像、等级部分外框层
        Table headTable = new Table();
        headTable.setFillParent(true);
        headTable.left().top();
        headTable.add(new Image(atlas.findRegion("bottom_bg"))).colspan(3).left().width(GameUIDemo.V_WIDTH).height(30);
        headTable.row();

        Image headImg = new Image(atlas.findRegion("head"));

        float hw = GameUIDemo.V_WIDTH * 0.20f;
        float headScale = hw / headImg.getWidth();

        headTable.add(headImg).width(hw).height(headImg.getHeight() * headScale).left().top();

        Image headInner = new Image(atlas.findRegion("head_inner"));
        headTable.add(headInner).width(GameUIDemo.V_WIDTH - hw - 10).height(headInner.getHeight() * headScale - 1).padRight(-15f).left().top();

        Image headCorner = new Image(atlas.findRegion("head_corner"));
        headTable.add(headCorner).width(30).height(headCorner.getHeight() * headScale - 1).padLeft(-5f).left().top();
        headTable.row();

        layout.add(headTable);

        //头部名称、金币和钻石等显示框层
        Table textTable = new Table();
        textTable.setFillParent(true);
        textTable.left().top().padTop(30);

        TextureAtlas.AtlasRegion textInnerRegion = atlas.findRegion("text_inner");
        TextureAtlas.AtlasRegion textCornerRegion = atlas.findRegion("text_corner");
        Image textInner = new Image(textInnerRegion);
        Image textCorner = new Image(textCornerRegion);

        float cornerWidth = textCorner.getWidth() * headScale;
        float offsetLeft = headImg.getWidth() * headScale - 10;
        float innerWidth = GameUIDemo.V_WIDTH - offsetLeft - cornerWidth * 3 - 40;
        float innerHeight = textInner.getHeight() * headScale;
        float innerTop = (headInner.getHeight() - textInner.getHeight()) * headScale / 2;
        textTable.add(textInner).width(innerWidth / 3).height(innerHeight).padTop(innerTop - 1).padLeft(offsetLeft);
        textTable.add(textCorner).width(textCorner.getWidth() * headScale).height(innerHeight).padTop(innerTop - 1).left();

        textInner = new Image(textInnerRegion);
        textTable.add(textInner).width(innerWidth / 3).height(innerHeight).padTop(innerTop - 1).padLeft(20);

        textInner = new Image(textInnerRegion);
        textTable.add(textInner).width(innerWidth / 3).height(innerHeight).padTop(innerTop - 1).padLeft(20);

        layout.add(textTable);

        //金币、钻石图标层
        Table infoTable = new Table();
        infoTable.setFillParent(true);
        infoTable.left().top().padTop(30).padLeft(headImg.getWidth() * headScale - 30);

        Image levelImg = new Image(atlas.findRegion("level_bg"));
        infoTable.add(levelImg).width(levelImg.getWidth() * headScale).height(levelImg.getHeight() * headScale).left().top();

        Image goldenImg = new Image(atlas.findRegion("golden"));
        float goldenOffsetLeft = innerWidth / 3 + 20 - goldenImg.getWidth() * headScale / 2;
        infoTable.add(goldenImg).width(goldenImg.getWidth() * headScale).height(goldenImg.getHeight() * headScale).padLeft(goldenOffsetLeft).padTop(innerTop).left().top();

        TextureAtlas.AtlasRegion plusRegion = atlas.findRegion("plus");
        Image plusImg = new Image(plusRegion);
        float plusOffsetLeft = innerWidth / 3 - plusImg.getWidth() * headScale - 5;
        infoTable.add(plusImg).width(plusImg.getWidth() * headScale).height(plusImg.getHeight() * headScale).padLeft(plusOffsetLeft).padTop(innerTop + 1).left().top();

        Image dimondImg = new Image(atlas.findRegion("dimond"));
        infoTable.add(dimondImg).width(dimondImg.getWidth() * headScale).height(dimondImg.getHeight() * headScale).padLeft(10).padTop(innerTop + 1).left().top();

        plusImg = new Image(plusRegion);
        plusOffsetLeft = innerWidth / 3 - plusImg.getWidth() * headScale - 10;
        infoTable.add(plusImg).width(plusImg.getWidth() * headScale).height(plusImg.getHeight() * headScale).padLeft(plusOffsetLeft).padTop(innerTop + 1).left().top();

        layout.add(infoTable);

        //底部面板、底部背景层
        Table bottomTable = new Table();
        bottomTable.setFillParent(true);
        bottomTable.bottom();
        bottomTable.add(new Image(atlas.findRegion("bar_corner"))).left().width(30).height(60);
        bottomTable.add(new Image(atlas.findRegion("bar_inner"))).left().width(GameUIDemo.V_WIDTH - 60).height(60);
        Image rightCorner = new Image(atlas.findRegion("bar_corner"));
        rightCorner.setOriginX(15);
        rightCorner.setScaleX(-1);
        bottomTable.add(rightCorner).right().width(30).height(60);
        bottomTable.row();

        bottomTable.add(new Image(atlas.findRegion("bottom_bg"))).colspan(3).left().width(GameUIDemo.V_WIDTH).height(30);
        bottomTable.row();

        layout.add(bottomTable);

        //底部菜单图标层
        Table iconTable = new Table();
        float iconScaleX = 0.45f, iconScaleY = 0.4f;
        iconTable.setFillParent(true);
        iconTable.center().bottom().padBottom(50);

        Button iconHome = new Button(new TextureRegionDrawable(atlas.findRegion("icon_home")));
        iconTable.add(iconHome).bottom().width(iconScaleX * iconHome.getWidth()).height(iconScaleX * iconHome.getHeight()).pad(0, 5, 0, 10);

        Button iconHero = new Button(new TextureRegionDrawable(atlas.findRegion("icon_hero")));
        iconTable.add(iconHero).bottom().width(iconScaleX * iconHero.getWidth()).height(iconScaleX * iconHero.getHeight()).pad(0, 10, 0, 10);

        Button iconAdventure = new Button(new TextureRegionDrawable(atlas.findRegion("icon_adventure")));
        iconTable.add(iconAdventure).bottom().width(iconAdventure.getWidth() * iconScaleX).height(iconAdventure.getHeight() * iconScaleX).pad(0, 10, 0, 10);

        Button iconBag = new Button(new TextureRegionDrawable(atlas.findRegion("icon_bag")));
        iconTable.add(iconBag).bottom().width(iconScaleX * iconBag.getWidth()).height(iconScaleX * iconBag.getHeight()).pad(0, 10, 0, 10);

        Button iconUnit = new Button(new TextureRegionDrawable(atlas.findRegion("icon_unit")));
        iconTable.add(iconUnit).bottom().width(iconScaleX * iconUnit.getWidth()).height(iconScaleX * iconUnit.getHeight()).pad(0, 10, 0, 5);

        layout.add(iconTable);

        stage.addActor(layout);

        Gdx.input.setInputProcessor(stage);
    }

    public void draw(float dt){
        stage.draw();
        stage.act(dt);

    }

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

启动入口类

package com.mygdx.game.ui;

import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.utils.ScreenUtils;

public class GameUIDemo extends Game {
    public static final float V_WIDTH = 480;
    public static final float V_HEIGHT = 800;
    public SpriteBatch batch;
    public Skin skin;
    public BitmapFont font;

    private GameHUD gameHUD;

    @Override
    public void create() {
        skin = new Skin(Gdx.files.internal("ui/uiskin.json"));
        font = new BitmapFont(Gdx.files.internal("bitmapfont_big.fnt"));

        batch = new SpriteBatch();

        gameHUD = new GameHUD(this);

    }

    @Override
    public void render() {
        super.render();

        ScreenUtils.clear(Color.WHITE);

        gameHUD.draw(Gdx.graphics.getDeltaTime());
    }

    @Override
    public void resize(int width, int height) {
        super.resize(width, height);

    }

    @Override
    public void dispose() {
        super.dispose();
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dyyaries

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值