2017-01-22 73 views
0

因此,当我第一次参加战斗时,它会按照它应该做的那样做,但之后当我再次去那个地方时,它会攻击老板两次在点击,然后当我杀了他,去了他三次,然后它的攻击老板三次的代码如下:玩家在第二次尝试攻击时攻击两次

public class temp extends JFrame implements Runnable{ 

public static JPanel game=new JPanel(); 
public JPanel town_map=new JPanel(null); 
public JPanel level1=new JPanel(null); 
public JLabel character; 
public Thread turn; 
public JButton attack1=new JButton("reduce health"); 
public int health,healthleft; 
public JLabel healthleftbl=new JLabel(); 

public boolean a=false; 

CardLayout page= new CardLayout(); 

public static void main(String []args) 
{ 
    new temp().setVisible(true); 
} 

public temp() 
{ 
    super("Temporary Debug"); 
    setSize(640,510); 
    setDefaultCloseOperation(EXIT_ON_CLOSE); 

    game.setLayout(page); 
    game.add(town_map,"map"); 
    game.add(level1, "lhealthleft1"); 
    add(game); 
    town(); 
} 

    public void town() 
    { 
     page.show(game, "map"); 
     JButton test=new JButton("Go to Battle"); 
     test.setBounds(0, 0, 150, 150); 
     town_map.add(test); 
     test.addActionListener(new ActionListener(){ 
      public void actionPerformed(ActionEvent e) 
      { 
       level01(); 
      } 
     }); 
    } 
    public void level01() 
    { 

     page.show(game, "lhealthleft1"); 
     attack1.setBounds(315, 368, 163, 57); 
     health=800; 
     healthleft=health; 
     level1.add(attack1); 
     healthleftbl.setBounds(150, 0, 100, 100); 
     level1.add(healthleftbl); 
     if(a==true) 
     System.out.println(turn.getState()); 

     turn=new Thread(this); 

     turn.start(); 
    } 
     public void run() { 
      a=true; 
       attack1.addActionListener(new ActionListener() 
       { 
        public void actionPerformed(ActionEvent e) 
        { 
          healthleft=healthleft-100; 
        }}); 

       do{ 
       healthleftbl.setText(healthleft+"/"+health); 
       if(healthleft<=0) 
       { 
        page.show(game, "map"); 
        break; 
       } 
       System.out.println(healthleft); 
       }while(turn.getState()!=null); 
      } 
} 
+0

见[检测/为挂Ç修复失去代码块的支架](http://meta.stackexchange.com/q/251795/155831),因为我不能再纠缠于此问题。 –

+0

请参阅编辑以回答 –

+0

我已经制作了一个新程序,显示了一个事件驱动的状态驱动代码示例。没有什么时候可以找到真正的循环。 –

回答

4

您要添加内重演代码的ActionListeners,被称为多次,并且这会导致在按钮按下时多次调用这些操作。

public void run() { 
    a = true; 

    // ************************************** 
    // this add ActionListener gets called with every creation 
    // of a new Thread, and then calling .start() on the Thread 
    attack1.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      healthleft = healthleft - 100; 
     } 
    }); 


    // ************************************** 
    // this code does not belong in an event-driven program 
    do { 
     healthleftbl.setText(healthleft + "/" + health); 
     if (healthleft <= 0) { 
      page.show(game, "map"); 
      break; 
     } 
     System.out.println(healthleft); 
    } while (turn.getState() != null); 
} 

不要这样做。在程序设置期间添加一次ActionListeners,而不是在转身期间。此外,您的while (true)循环不属于事件驱动的程序,相反,您应该将代码设置为状态模式,其中程序的行为(对用户输入的响应)会根据程序的状态进行更改。

例如:

import java.awt.BorderLayout; 
import java.awt.CardLayout; 
import java.awt.Dimension; 
import java.awt.FlowLayout; 
import java.awt.GridBagLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.KeyEvent; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 

import javax.swing.*; 
import javax.swing.event.SwingPropertyChangeSupport; 

public class Temp2 extends JPanel { 
    private CardLayout cardLayout = new CardLayout(); 
    private GamePanel gamePanel = new GamePanel(this); 
    private IntroPanel introPanel = new IntroPanel(this); 

    public Temp2() { 
     setLayout(cardLayout); 
     add(introPanel, IntroPanel.class.getName()); 
     add(gamePanel, GamePanel.class.getName()); 
    } 

    public void showCard(String name) { 
     cardLayout.show(this, name); 
    } 

    private static void createAndShowGui() { 
     Temp2 mainPanel = new Temp2(); 

     JFrame frame = new JFrame("Temp2"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> createAndShowGui()); 
    } 
} 

@SuppressWarnings("serial") 
class GamePanel extends JPanel { 
    private static final int PREF_W = 400; 
    private static final int PREF_H = 350; 
    public static final int DAMAGE_AMOUNT = 100; 
    private Temp2 temp2; 
    private Player2 player2 = new Player2(); 
    private JLabel statusLabel = new JLabel(); 

    public GamePanel(Temp2 temp2) { 
     this.temp2 = temp2; 
     player2.addPropertyChangeListener(Player2.HEALTH, new PlayerListener()); 

     JPanel statusPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 5, 5)); 
     statusPanel.add(new JLabel("Health")); 
     statusPanel.add(statusLabel); 
     displayHealth(); 

     JPanel battlePanel = new JPanel(new GridBagLayout()); 
     battlePanel.add(new JButton(new BattleAction("Battle", KeyEvent.VK_B))); 

     setLayout(new BorderLayout()); 
     add(statusPanel, BorderLayout.PAGE_START); 
     add(battlePanel, BorderLayout.CENTER); 
    } 

    private void displayHealth() { 
     String healthText = String.format("%03d/%03d", player2.getHealth(), Player2.MAX_HEALTH); 
     statusLabel.setText(healthText); 
    } 

    public void reset() { 
     player2.setHealth(Player2.MAX_HEALTH); 
     temp2.showCard(IntroPanel.class.getName()); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     if (isPreferredSizeSet()) { 
      return super.getPreferredSize(); 
     } 
     return new Dimension(PREF_W, PREF_H); 
    } 

    private class BattleAction extends AbstractAction { 
     public BattleAction(String name, int mnemonic) { 
      super(name); 
      putValue(MNEMONIC_KEY, mnemonic); 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      int health = player2.getHealth() - DAMAGE_AMOUNT; 
      player2.setHealth(health); 
     } 
    } 

    private class PlayerListener implements PropertyChangeListener { 
     @Override 
     public void propertyChange(PropertyChangeEvent evt) { 
      int health = (int) evt.getNewValue(); 
      displayHealth(); 
      if (health <= 0) { 
       reset(); 
      } 
     } 
    } 

} 

@SuppressWarnings("serial") 
class IntroPanel extends JPanel { 
    private Temp2 temp2; 

    public IntroPanel(Temp2 temp2) { 
     this.temp2 = temp2; 
     setLayout(new GridBagLayout()); 
     add(new JButton(new GoToBattleAction("Go To Battle", KeyEvent.VK_G))); 
    } 

    private class GoToBattleAction extends AbstractAction { 
     public GoToBattleAction(String name, int mnemonic) { 
      super(name); 
      putValue(MNEMONIC_KEY, mnemonic); 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      temp2.showCard(GamePanel.class.getName()); 
     } 
    } 

} 

class Player2 { 
    // make health a "bound property" by using property change support and listeners 
    public static final String HEALTH = "health"; 
    public static final int MAX_HEALTH = 800; 
    private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(this); 
    private int health; 

    public Player2() { 
     this.health = MAX_HEALTH; 
    } 

    public int getHealth() { 
     return health; 
    } 

    // notify all listeners if health changes 
    public void setHealth(int health) { 
     int oldValue = this.health; 
     int newValue = health; 
     this.health = health; 
     pcSupport.firePropertyChange(HEALTH, oldValue, newValue); 
    } 

    // allow outside code to listen for changes to all bound properties 
    // should also have the associated remove listener methods too 
    public void addPropertyChangeListener(PropertyChangeListener listener) { 
     pcSupport.addPropertyChangeListener(listener); 
    } 

    public void addPropertyChangeListener(String name, PropertyChangeListener listener) { 
     pcSupport.addPropertyChangeListener(name, listener); 
    } 

} 
+0

这使得更多的意义非常感谢! –