Отключение кнопок, когда определенная переменная равна нулю? [решено: шаблон проектирования наблюдателя]

Я создаю простую боевую игру. есть два противостоящих игрока, цель которых - устранить другого; я создал полоски здоровья и тому подобное. Чтобы начать атаку на противника, пользователь нажимает определенную кнопку «атака». Я хочу, чтобы эта кнопка была отключена, если полоса здоровья одного игрока достигла нуля.

http://sstatic.net/stackoverflow/img/Untitled.jpg

Структура моей программы:

основной класс (приложение открытого класса расширяет JFrame) // частные JButtons, JPanels и т. д.

public App () // расположение всех компонентов и зарегистрированных слушателей

основной метод // кадр / с (у меня больше одного кадра в моем основном методе. ха-ха)

Класс слушателя / es // операторы if else (if (e.getSource == xyz))

Класс / классы JPanel, которые рисуют полосы здоровья

---- конец структуры

вот что я сделал до сих пор в классе панели (полный исходный код - это 800-строчный текстовый файл):

    class HP2panel extends JPanel {

    public void damageTake() {
    if (widthHP <= 0) {   
    damageToMe = 0;
    }
    else if (widthRage >= 250) {  
    damageToMe = 175 + (int)(Math.random() * 25);
    }
    else if (widthHP > 0 && widthRage < 250) { 
    damageToMe = Math.round(1 + (int)(Math.random() * 15));
    }
    if (widthHP2 <= 0) {
    damageToMe = 0;
    }
    widthHP2 = widthHP2 - damageToMe;

    logtxt.append("\nYour HP: " + widthHP2);
    logtxt.append("\nDamage you've taken: " + damageToMe);
    repaint();
}

public void healdamageTake() {
    if (widthHP2 <= 0) {
    Heal = 0;
    }
    if (widthHP2 >= 250) {
    Heal = 0;
    }
    else {
    Heal = (int)(Math.random() * 25);
    }
    widthHP2 = widthHP2 + Heal;
    logtxt.append("\n");
    logtxt.append("\nHealed HP: " + Heal);
    repaint();
}

public void restartHP2() {
    widthHP2 = 250;
    repaint();
}

    @Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(Color.green);
    g.fillRect(0, 0, widthHP2, 16);
}


    }

HP2panel - это класс панели, в котором отображается полоса здоровья (fillRect) игрока 2. widthHP, widthRage - это параметры из другого созданного мной класса панели.

Я хочу, чтобы кнопка атаки была отключена, когда widthHP станет равным нулю или меньше. Я работал над операторами if, но это казалось бесполезным.

Я не знаю, собираюсь ли я поместить его в свой класс Listener или где-нибудь еще в моем коде.


person FartVader    schedule 12.10.2013    source источник
comment
Помимо случайного, вы, вероятно, захотите прочитать о составные операторы присваивания, большинство программистов вздрагивают при виде x = x - y и не утруждают себя чтением дальше ...   -  person Boris the Spider    schedule 12.10.2013
comment
Я сделаю это позже. Благодарю. на данный момент мне действительно нужно выяснить решение моей проблемы с помощью кого-то отсюда. Я на грани своего остроумия.   -  person FartVader    schedule 12.10.2013
comment
Ваше требование мне не совсем понятно. button.setEnable(false) мог легко сделать трюк с if-else проверкой.   -  person Sage    schedule 12.10.2013
comment
были должны поставить это если заявление? я отредактировал сообщение   -  person FartVader    schedule 12.10.2013


Ответы (1)


Я думаю, что это ключ к использованию Шаблон проектирования наблюдателя, чтобы один объект мог отслеживать изменения состояния другого объекта.

Я предполагаю, что у каждого класса Player есть поле здоровья. Я бы сделал это свойство "связанным", предоставив классу Player частное поле SwingPropertyChangeSupport, предоставив методы класса Player addPropertyChangeListener и removePropertyChangeListener и уведомив ваших слушателей об изменениях состояния здоровья, вызывая метод firePropertyChange(...) всякий раз, когда свойство здоровья изменяется внутри его setHealth(...) метод. Таким образом, любой класс, которому необходимо отслеживать изменения состояния (или любого другого связанного свойства класса Player), может это делать и может реагировать на эти изменения по мере необходимости. Это еще одна причина, по которой поля / свойства класса должны быть закрытыми и изменяться только с помощью методов установки.

Например:

Класс драйвера, PropChangeEg.java

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
import javax.swing.event.*;

public class PropChangeEg {
   private static void createAndShowGui() {
      JFrame frame = new JFrame("Prop Change Example");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(new PlayerPanel(new Player("Pete")));
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

Player.java класс

class Player {
   public static final String HEALTH = "health";
   private SwingPropertyChangeSupport propChangeSupport = 
             new SwingPropertyChangeSupport(this);
   private String name;
   private int health = 100;

   public Player(String name) {
      this.name = name;
   }

   public void addPropertyChangeListener(PropertyChangeListener listener) {
      propChangeSupport.addPropertyChangeListener(listener);
   }

   public void removePropertyChangeListener(PropertyChangeListener listener) {
      propChangeSupport.removePropertyChangeListener(listener);
   }

   public int getHealth() {
      return health;
   }

   public void setHealth(int health) {
      int oldValue = this.health;
      int newValue = health;
      this.health = health;
      propChangeSupport.firePropertyChange(HEALTH, oldValue, newValue);
   }

   public String getName() {
      return name;
   }

}

PlayerPanel.java класс

@SuppressWarnings("serial")
class PlayerPanel extends JPanel {
   private Player player;
   private JButton fireButton = new JButton("Fire");
   private JSlider healthSlider;

   public PlayerPanel(final Player player) {
      this.player = player;
      setBorder(BorderFactory.createTitledBorder("Player: " + 
             player.getName()));

      healthSlider = new JSlider(0, 100, player.getHealth());
      healthSlider.setBorder(BorderFactory.createTitledBorder("Health"));
      healthSlider.setPaintLabels(true);
      healthSlider.setPaintTicks(true);
      healthSlider.setPaintTicks(true);
      healthSlider.setMajorTickSpacing(20);
      healthSlider.setMinorTickSpacing(5);

      add(healthSlider);
      add(fireButton);

      healthSlider.addChangeListener(new ChangeListener() {

         @Override
         public void stateChanged(ChangeEvent evt) {
            player.setHealth(healthSlider.getValue());
         }
      });

      player.addPropertyChangeListener(new PropertyChangeListener() {

         @Override
         public void propertyChange(PropertyChangeEvent evt) {
            if (evt.getPropertyName().equals(Player.HEALTH)) {
               fireButton.setEnabled(player.getHealth() > 0);
            }
         }
      });

   }

   public Player getPlayer() {
      return player;
   }

}

Это приведет к появлению кнопки JButton, которая соответствует значению здоровья игрока. Например, вот два экрана из этого графического интерфейса, один с положительным ненулевым значением здоровья и один, где значение здоровья игрока равно нулю:

введите описание изображения здесь

person Hovercraft Full Of Eels    schedule 12.10.2013