1

我正在创建一个简单的战斗游戏。有两名对方球员的目标是消灭对方;我创建了健康栏等。要对对手发起攻击,用户单击某个按钮“攻击”。如果一名玩家的生命值达到零,我希望禁用此按钮。

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

我的程序结构:

main class (public class App extends JFrame) //私有的JButtons、JPanels等

public App() //所有组件的布局和注册的监听器

main 方法 //frame/s (我的 main 方法中有不止一帧。哈哈)

Listener class/es //if else 语句 (if (e.getSource == xyz))

绘制健康条的 JPanel 类/es

----结构结束

这是我到目前为止在面板类上所做的(总源代码是一个 800 行的 txt 文件):

    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 是绘制玩家 2 的 healthbar(fillRect) 的面板类。widthHP、widthRage 是我制作的其他面板类的参数。

一旦widthHP变为零或小于,我希望禁用攻击按钮。我已经研究过 if 语句,但它似乎没用。

我不知道我是否要将它放在我的 Listener 类或我的代码中的其他任何地方。

4

1 回答 1

4

我认为关键是使用观察者设计模式来允许一个对象监听另一个对象的状态变化。

我假设每个 Player 类都有一个健康字段。我将通过为 Player 类提供一个私有 SwingPropertyChangeSupport 字段、通过提供 Player 类addPropertyChangeListenerremovePropertyChangeListener方法以及通过firePropertyChange(...)在其方法内更改健康属性时通过调用方法通知您的听众健康变化来使其成为“绑定”属性setHealth(...)。这样,任何需要监听健康变化的类(或 Player 类的任何其他绑定属性)都可以这样做,并且可以根据需要响应这些变化。这是类字段/属性应该是私有的并且只能通过 setter 方法更改的另一个原因。

例如:

驱动程序类,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。例如,这里有两个来自这个 GUI 的屏幕,一个具有非零的正健康值,另一个是玩家的健康值为零:

在此处输入图像描述

于 2013-10-12T14:28:27.013 回答