Java Libgdx更新表中的标签

Java Libgdx更新表中的标签,java,android,libgdx,label,Java,Android,Libgdx,Label,表和更新标签有问题!这是一个进退两难的问题,我在游戏中有一个卖出按钮,每当玩家卖出物品时,它都会更新玩家的硬币,这一部分工作得非常好。我遇到的问题是试图在屏幕上更新硬币的价值,而在这个单独的菜单中(见附图,硬币在左上角)。问题是硬币的价值在另一个等级中处于另一个阶段。这是因为当我点击底部的不同按钮时,我有不同的表格在中间弹出。我尝试过帮助器方法,用于进入并清除该表并更新它,然后将我发送回该项目页面,但它不起作用,我可以发布任何需要的代码,但这更像是一个关于如何在阶段中更新表内标签的一般性问题

表和更新标签有问题!这是一个进退两难的问题,我在游戏中有一个卖出按钮,每当玩家卖出物品时,它都会更新玩家的硬币,这一部分工作得非常好。我遇到的问题是试图在屏幕上更新硬币的价值,而在这个单独的菜单中(见附图,硬币在左上角)。问题是硬币的价值在另一个等级中处于另一个阶段。这是因为当我点击底部的不同按钮时,我有不同的表格在中间弹出。我尝试过帮助器方法,用于进入并清除该表并更新它,然后将我发送回该项目页面,但它不起作用,我可以发布任何需要的代码,但这更像是一个关于如何在阶段中更新表内标签的一般性问题

更新:所以总结一下我的问题,我有一个屏幕,其中有三个表格,底部的表格,左上角和右上角。然后我把表格添加到中间的阶段,当他们按下清单或商店按钮等。我想做的是保持项目页面打开,只需更新硬币标签的值,我知道我可以使用StTrimeTo()更改文本。我只是不知道如何更新屏幕的这一部分

更新2:如果我只是将屏幕设置回此屏幕的新屏幕,它会更新硬币值,但我不再在项目页面上,这并不理想

更新3:感谢各位迄今为止的帮助,@John您的回答也非常有用。虽然这里有一些处理标签的代码,但我仍然无法实现这一点

playerCoinLabel = new Label(playerSave.getCoinsString(),skin,"defaultMiddle");
这就是它被添加到表中的地方

tableLeft = new Table(skin);
stage.addActor(tableLeft);
tableLeft.setBounds(0,0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
tableLeft.setFillParent(true);
tableLeft.top().left();
tableLeft.add(healthNonButton).size(84,80).left().padLeft(10).padTop(5);
tableLeft.add(playerHealthLabel).left().padLeft(15);
tableLeft.row();
tableLeft.add(levelNonButton).size(74,70).center().padLeft(10);
tableLeft.add(playerLevelLabel).left().padLeft(19);
tableLeft.row();
tableLeft.add(coinNonButton).size(74,70).center().padLeft(10);
tableLeft.add(this.playerCoinLabel).left().padLeft(15);          //This line
tableLeft.row();
然后我有了这个方法,可以像你们告诉我的那样,使用setText更新我的标签

public void updatePlayerCoins() {
    playerCoinLabel.setText(playerSave.getCoinsString());
}
如果我在任何地方调用这个方法,render()或在我设置新硬币值的地方,它不会更新/更改屏幕左上角的标签。如果我需要发布涉及标签的内容,我可以将所有代码发布到github。这只是一个项目,我的工作,以提高我的技能集,所以很抱歉,如果我听起来业余,这是因为我


谢谢大家

您似乎在问两件事-如何更新标签?我如何构造我的代码?很难说前者出了什么问题,因为我们看不到您的代码,但@Tenfour04是正确的-您希望在某个地方保留对标签的引用,并在更改金额时调用
setText()

至于代码的结构,我建议采用一种简单的OOP设计,然后将其演变为:

首先,我们需要一个对象来表示玩家:

class Player {
  private int coins; // Pretend there are getters / setters.
  private int health;
  private int level;
}
现在,您可能有多种方式来表示此播放器信息,因此我们将渲染代码拆分为一个单独的类或一组类:

class StatWidget {
  private Stage stage;
  private Player player;
  private Label lblCoins;

  public StatWidget(Player player) { // Pseudo-code
    this.player = player;
    this.stage = new Stage();
    Table tbl = new Table();
    this.lblCoins = new Label(); // Notice we keep a reference to the label
    tbl.add( this.coins );
  }

  public void update() {
    lblCoins.setText(player.getCoins());
  }
}
现在,只需调用
player\update()
,即可将UI与播放器对象的状态同步。但是你什么时候叫它

可以在渲染方法中调用
update()
。这有点低效,因为无论是否需要更新对象,都要更新对象,但这非常简单,如果只以这种方式更新几个UI元素,可能并不重要。就我个人而言,我就到此为止

如果你想说得更准确些,你只会在你实际更改玩家的硬币时调用
update()
。您可以在代码中找到设置玩家硬币的位置,然后添加更新调用,如下所示:

player.setCoins( A_LOT_OF_MONEY );
statWidget.update();
问题是,当你添加更多的小部件时,这会变得更加麻烦——你所有的游戏逻辑现在都必须了解StatWidget并调用它。通过使用事件驱动架构,我们可以稍微减少这种依赖性。本质上,只要玩家的状态发生变化,它就会向相关方发送一个事件,通知他们该变化。您可以使用下面的伪代码:

interface Publisher {
  void subscribe(Subscriber subby);
  void unsubscribe(Subscriber subby);
}

class Player implements Publisher {
  private List<Subscriber> subscribers;
  private int coins;
  // ...

  public void setCoins(int amount) {
    this.coins = amount;
    for(Subscriber subscriber : subscribers) subscriber.notify("COINS", amount);
  }

  public void subscribe(Subscriber subby) {
    this.subscribers.add(subby);
  }
  public void unsubscribe(Subscriber subby) {
    this.subscribers.remove(subby);
  }
}

interface Subscriber {
  void notify(String event, int qty);
  void dispose();
}

class StatWidget implements Subscriber {
  private Publisher player;
  private Label label;
  // ...

  public StatWidget(Player player) {
    this.player = player;
    this.player.addSubscriber(this);

  void notify(String event, int qty) {
    if(event.equals("COINS")) label.setText(qty);
  }

  void dispose() {
    this.player.unsubscribe(this);
  }
}
接口发布器{
无效认购(认购人代理);
无效退订(订户代理);
}
类播放器实现Publisher{
私人名单订户;
私人货币;
// ...
公共货币(整数金额){
这个。硬币=数量;
(订户:订户)订户。通知(“硬币”,金额);
}
公共无效订阅(订阅人子用户){
this.subscribers.add(subby);
}
公开作废退订(订户代理){
此.subscribers.remove(subby);
}
}
接口用户{
作废通知(字符串事件,整数数量);
无效处置();
}
类StatWidget实现订阅服务器{
私人出版商播放器;
自有品牌;
// ...
公共游戏者(游戏者){
this.player=player;
this.player.addSubscriber(this);
作废通知(字符串事件,整数数量){
如果(事件等于(“硬币”))标签设置文本(数量);
}
无效处置(){
this.player.unsubscribe(此);
}
}

上面的事件系统当然可以改进,并且您可以使用泛型做一些聪明的事情(或者使用一个为您的应用程序考虑了所有这些的库),但希望它能说明这些概念。

您似乎在问两件事-如何更新标签?以及如何构造代码?很难说前者出了什么问题,因为我们看不到您的代码,但@Tenfour04是对的-您希望在某个地方保留对标签的引用并调用
setText()
当您想更改金额时

至于代码的结构,我建议采用一种简单的OOP设计,然后将其演变为:

首先,我们需要一个对象来表示玩家:

class Player {
  private int coins; // Pretend there are getters / setters.
  private int health;
  private int level;
}
现在,您可能有多种方式来表示此播放器信息,因此我们将渲染代码拆分为一个单独的类或一组类:

class StatWidget {
  private Stage stage;
  private Player player;
  private Label lblCoins;

  public StatWidget(Player player) { // Pseudo-code
    this.player = player;
    this.stage = new Stage();
    Table tbl = new Table();
    this.lblCoins = new Label(); // Notice we keep a reference to the label
    tbl.add( this.coins );
  }

  public void update() {
    lblCoins.setText(player.getCoins());
  }
}
现在,只需调用
player#update()
.B,即可将UI与播放器对象的状态同步