【问题标题】:GUI hangman game- how can I get these different parts to work together?GUI 刽子手游戏 - 我怎样才能让这些不同的部分一起工作?
【发布时间】:2014-04-04 11:19:01
【问题描述】:

我有(几乎)游戏的工作部分,但它们不能一起工作。我是一个完整的初学者,所以我不知道如何解决问题所在。 我有 3 节课:

  • GameControls 包含游戏的主要功能。
  • Hangman 设置一个 JFrame,调用 drawHangman 方法并包含 main 方法
  • drawHangman 有绘制刽子手图形的说明
    我怀疑这可能不是最好的方法,所以如果课程没有意义,请告诉我(并告诉我原因!)。

问题

  1. GameControls 自行运行良好。用户可以选择要猜测的字母,显示有效,如果猜测错误,则剩余寿命计数会下降。
    但是
    如果我从hangman main 方法运行,则会出现窗口并且控件不起作用没有了。
  2. 即使 lifeRemaining 计数减少,我也不知道如何让 drawHangman 部分使用该变量并实现 switch 语句来绘制刽子手。

我的想法

  • 在我看来,类/方法的编写/设计方式可能会导致问题(但我不知道如何诊断和解决此问题。我已经尝试过!)
  • 我认为问题 1 的原因可能是当两个窗口都打开时,程序不再知道动作来自何处和/或我需要添加更多 ActionListener 内容。
    由于我对编程很陌生,所以我需要很长时间才能查看和尝试不同的东西,我真的很想要一些指针。我的代码如下。

刽子手类

    public class Hangman extends JFrame
    {
        public Hangman()
    {
        super("You have nine lives...");
        setSize(600,600);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        drawHangman draw = new drawHangman();
        add(draw);
        setVisible(true);
        }
    
        public static void main(String[] args)
        {
            GameControls play = new GameControls();
            Hangman game = new Hangman();
        
        }
        }
    }

GameControls 类

    import java.awt.event.*;
    import javax.swing.*;
    import java.awt.*;

    public class GameControls extends JFrame implements ActionListener
    {

        String secretWord = "elephant"; //I'm assuming I will call a method that generates the  secretWord
        String clueGiven = "animal";
        int letterN = 0;
        int secretWordLength = secretWord.length();
        int livesRemaining = 10;
        boolean[] alreadyGuessed = new boolean[26];
    
        JLabel secretWordLabel = new JLabel("Word to guess: ", SwingConstants.RIGHT);
        JTextField displaySecretWord = new JTextField(secretWordLength);
        JLabel clueLabel = new JLabel("Clue: ", SwingConstants.RIGHT);
        JTextField clue = new JTextField(clueGiven, 15);
        JLabel guessLabel = new JLabel("Choose a letter: ", SwingConstants.RIGHT); 
        String[] letters = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
        JComboBox selectGuess = new JComboBox(letters);
        JButton submit = new JButton("Submit");
        JTextField displayGuessedLetters = new JTextField(15);
    
        public GameControls()
        {
            super("Hangman Game");
            setSize(340,170);
            setBounds(600,0,340,170);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setLookAndFeel();
         
            selectGuess.addActionListener(this); 
            submit.addActionListener(this);
            displaySecretWord.setEditable(false);
            clue.setEditable(false);
            displayGuessedLetters.setEditable(false);
        
            //show _ for all the letters of the secretWord
            for (letterN=0; letterN < secretWordLength; letterN++)
            {
                String displayedSoFar = displaySecretWord.getText();
                displaySecretWord.setText(displayedSoFar + " " + "_");
            }
        
            JPanel pane = new JPanel();
            GridLayout display = new GridLayout(4,2);
            pane.setLayout(display);
            pane.add(secretWordLabel);
            pane.add(displaySecretWord);
            pane.add(clueLabel);
            pane.add(clue);
            pane.add(guessLabel);
            pane.add(selectGuess);
            pane.add(displayGuessedLetters);
            pane.add(submit);
            add(pane);
            setVisible(true);
        
        }
    

        public void actionPerformed(ActionEvent event)
        {
            /*this works just fine when I run just this part of the program
            **but if I run it from the hangman main method it doesn't work.
            **I think it might be because then it has an extra window
            **so it doesn't know where the action is coming from for these bits here
            */
            Object source = event.getSource();
        
            boolean guessInWord;
            String prevGuesses = displayGuessedLetters.getText();
            char hideLetter = '_';
            int guessInt = selectGuess.getSelectedIndex();
            String guessChar = (String)selectGuess.getItemAt(guessInt);
        
            if (source == submit)
            {
                //store word as alreadyGuessed              
                alreadyGuessed[guessInt]=true;
                //check if it's in the word
                guessInWord = (secretWord.indexOf(guessChar)) != -1;
                boolean wordComplete = false;
            
                if (guessInWord == true)
                {
                    //print out the secretWord with the guessed letters showing
                    displaySecretWord.setText(" ");
                    for (letterN=0; letterN < secretWordLength; letterN++)
                    {
                    
                        String displayedSoFar = displaySecretWord.getText();
                        char letterToCheck = secretWord.charAt(letterN);
                        int letterToCheckIndex = (int)(letterToCheck)- 97;
                    
                        if (alreadyGuessed[letterToCheckIndex]==true)
                        {
                            displaySecretWord.getText();
                            displaySecretWord.setText(displayedSoFar + " " + letterToCheck);
                        }
                        else if (alreadyGuessed[letterToCheckIndex]==false)
                        {
                            displaySecretWord.getText();    
                            displaySecretWord.setText(displayedSoFar + " " + hideLetter);
                        }
                    }
                //check if the word is complete or not
                String displayedSoFar = displaySecretWord.getText();
                wordComplete = displayedSoFar.indexOf("_")== -1;
                if (wordComplete == true)
                {
                    //this bit opens but I haven't finished it yet
                    youWinPopup win = new youWinPopup();
                }
                }
            
                else if (guessInWord == false)
                {
                    //I can't figure out how to link this to my hangman drawing part!
                    livesRemaining --;
                    System.out.println(livesRemaining);
                    displayGuessedLetters.setText(prevGuesses + " " + guessChar);
                }
            } 
        }
    
        private void setLookAndFeel()
        {
            try
            {
                    UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
                SwingUtilities.updateComponentTreeUI(this);
            }
            catch (Exception exc)
            {
                System.out.println("Couldn't use the system " + "look and feel: " + exc);
            }
        }

        /*public static void main (String[] args)
        {
            GameControls play = new GameControls(); //runs fine from here, without the hangman part
        }*/
    }

drawHangman 类

        import java.awt.*;
        import java.awt.geom.*;
        import javax.swing.*;

        public class drawHangman extends JPanel 
        {
        /**
         * 
         */
        private static final long serialVersionUID = -3924721752542320241L;

        public void paintComponent (Graphics comp)
        {
            Graphics2D comp2D = (Graphics2D) comp;
            comp2D.setColor(Color.white);
            comp2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
            Rectangle2D.Float background = new Rectangle2D.Float(0F,0F,400,600/*(float)getSize().width,(float)getSize().height*/);
                comp2D.fill(background);
        
            //setting for colour etc
            comp2D.setColor(Color.black);
            BasicStroke pen = new BasicStroke(2.0f,BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND);
            comp2D.setStroke(pen);      
        
            int livesRemaining = 10;
            switch (livesRemaining)
            {
            case '9':
                Line2D.Float gallowsBase = new Line2D.Float(50F,500F,500F,500F);
                comp2D.draw(gallowsBase); 
                break;
            case '8':   
                Line2D.Float gallowsVertical = new Line2D.Float(150F,500F,150F,100F);
                comp2D.draw(gallowsVertical);
                break;
            case '7':
                Line2D.Float gallowsTop = new Line2D.Float(150F,100F,400F,100F);
                comp2D.draw(gallowsTop);
                break;
            case '6':
                Line2D.Float rope = new Line2D.Float(400F,100F,400F,150F);
                comp2D.draw(rope);
                break;
            case '5':
                Ellipse2D.Float head = new Ellipse2D.Float(362F,150F,76F,76F);
                comp2D.draw(head); 
                break;
            case '4':
                Line2D.Float body = new Line2D.Float(400F,226F,400F,325F);
                comp2D.draw(body);
                break;
            case '3':
                Line2D.Float arm1 = new Line2D.Float(400F,226F,300F,275F);
                comp2D.draw(arm1);
                break;
            case '2':
                    Line2D.Float arm2 = new Line2D.Float(400F,226F,500F,275F);
                comp2D.draw(arm2);
                break;
            case '1':
                Line2D.Float leg1 = new Line2D.Float(400F,325F,300F,400F);
                comp2D.draw(leg1);
                break;
            case '0':
                Line2D.Float leg2 = new Line2D.Float(400F,325F,500F,400F);
                comp2D.draw(leg2);
                /*youLosePopup lose = new youLosePopup();*/
            }    
        }
        /*public static void main (String[] args)
        {
            drawHangman draw = new drawHangman(); 
        }*/
    }
    


    

【问题讨论】:

  • 错过super.paintComponent 作为public void paintComponent (Graphics comp 中的第一个代码行),也许dispose() 作为同一代码块中的最后一个代码行(与super.paintComponent 相比真的不重要)
  • UIManager.setLookAndFeel(..... 应该是public static void main(String[] args) 中的第一行代码

标签: java swing class


【解决方案1】:
  • livesRemaining 是一个整数。
  • 当你把它放在switch 语句中时,你的大小写应该是整数而不是字符。

    case 6:
    

    而不是

    case '6':
    

祝你好运。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-14
    • 1970-01-01
    • 1970-01-01
    • 2020-02-03
    • 2014-08-19
    • 2020-06-23
    • 2019-12-12
    • 2017-12-24
    相关资源
    最近更新 更多