玩家第二次尝试时会两次攻击

时间:2017-01-22 20:33:38

标签: java multithreading swing

因此,当我第一次参加战斗时,它会按照预期的方式进行,但之后当我再次去那个地方时,它会一次攻击老板两次然后当我杀了他并去找他时三次然后它攻击老板三次代码如下:

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);
             }
}

1 个答案:

答案 0 :(得分:4)

您在重复自身的代码中添加了ActionListener,这被多次调用,这导致在按下按钮时多次调用操作。

res.send( JSON.stringify( { 'users': users } , null, 4) );

不要这样做。在程序设置期间添加一次ActionListener,而不是在转弯期间添加。此外,您的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); } 循环不属于事件驱动程序,相反,您应该以状态模式对代码进行模式化,其中程序的行为,对用户输入的响应,基于该计划的州。

例如:

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());
        }
    }

}