实现一个JAVA Game—— Hang man Game可视化编程
1.游戏截图:
模块设计
2.1 班( class的名词复数 )
这个项目包括三个类别:HangmanL词汇on和HangmanPanel。每一班将详细说明如下:
2.2 HangmanLexicon
创建这个类是为了读取HangmanLDicon.txt文件,并从这个txt文件中随机选择一个单词。
2.2.1公共汉曼词典(String词汇表FileDir)
这个函数是构造函数。它将读取easy.txt、medium.txt和hard.txt文件,将每一行视为给定的Hangman词汇表文件中的一个单词,并将该单词存储到不同的列表中(容易) 单词列表,中间单词列表和硬单词列表)。在easy.txt中,每个单词有4~6个字母,中间单词有7~10个字母,hard.txt中有10个字母。
2.2.2公共字符串随机选择Word(int级)
随机选择一个具有给定级别的单词,其中0表示容易级别,1表示中等级别,2表示硬级别。
2.3 HangmanPanel
这个类用于绘制Hangman,面板是作为游戏GUI的左侧组件创建的。这个类扩展了javax.swing.JPanel
2.3.1私人不法猜测;
用于记录错误猜测计数的私有非静态值,它是用0初始化的。
2.3.2公共无效涂料成分(图形g)
根据错误的估计画绞刑架,如果错误的数字等于0,只画脚手架,如果错误的数字等于1,画脚手架和头,如果错误的数字等于2,画脚手架,头和身体,如果错误的话。 SES等于3,绘制脚手架头、车身和左臂…如果错误猜测等于6,请绘制整个朝鲜人。
2.3.3公共无效增量–WrongGuess()
增加错误值,并重新绘制组件。
2.3.4公空重设()
让错误的数字等于0并重新绘制组件,在重新启动游戏时调用。
Hangman.java
import java.awt.Container; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.HashSet; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.border.EmptyBorder; public class Hangman extends JFrame{ private final int MAX_WRONG_GUESSES = 6; // record the incorrect count private int incorrectCount; private Container content; private JMenuBar menuBar; private JMenu menuStart; private JMenuItem menuItemRestart; // panel containing displayedCharsPanel, inputPanel and missesPanel private JPanel rightPanel; // right guessed chars private JLabel displayedCharsLabel; private JTextField displayedCharsTextField; // input field private JLabel inputLabel; private JTextField inputTextField; // misses prompt private JLabel missesLabel; private JTextField missesTextField; private HangmanPanel hangmanPanel; private HangmanLexicon hangmanLexicon; // This is the word being guessed private String hiddenWord; // display right letters private char[] displayedLetters; private char[] correctLetters; //This set keeps track of all the incorrect guessed letters private HashSet missedLettersSet = new HashSet(); private String missedLetters = ""; public Hangman() { super("HangmanGame"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // initialize hangmanLexicon used to random select word hangmanLexicon = new HangmanLexicon("data"); //creates a JMenuBar at the top of the GUI menuBar = new JMenuBar(); menuStart = new JMenu("start"); menuItemRestart = new JMenuItem("Restart"); menuItemRestart.addActionListener(new MenuHandler()); menuStart.add(menuItemRestart); menuBar.add(menuStart); // set content layout content = getContentPane(); setLayout(null); setSize(800, 500); // create hangman panel and right panel hangmanPanel = new HangmanPanel(); setupRightPannel(); content.add(hangmanPanel); hangmanPanel.setBounds(-50, 0, 400, 400); content.add(rightPanel); rightPanel.setBounds(400, 0, 400, 400); setJMenuBar(menuBar); // focus on input textfield when window show on addWindowListener( new WindowAdapter() { public void windowOpened( WindowEvent e ){ inputTextField.requestFocus(); } }); setLocationRelativeTo(null); // place the window in the center of the screen. setVisible(true); //makes the JFrame visible selectDifficultyLevel(); // create a optionPane and select difficulty level } private void setupRightPannel() { // create rightPanel rightPanel = new JPanel(); rightPanel.setLayout(null); Font newFont = new Font(Font.SANS_SERIF,Font.PLAIN, 20); //Creates a new Font displayedCharsLabel = new JLabel("Word:"); displayedCharsLabel.setFont(newFont); displayedCharsTextField = new JTextField(20); displayedCharsTextField.setEditable(false); displayedCharsTextField.setFont(newFont); displayedCharsTextField.setBorder(new EmptyBorder(0,0,0,0)); displayedCharsTextField.setOpaque(false); rightPanel.add(displayedCharsLabel); rightPanel.add(displayedCharsTextField); displayedCharsLabel.setBounds(0, 50, 80, 20); displayedCharsTextField.setBounds(80, 35, 250, 50); inputLabel = new JLabel("Guess:"); inputLabel.setFont(newFont); inputTextField = new JTextField(5); inputTextField.setEditable(true); inputTextField.setFont(newFont); rightPanel.add(inputLabel); rightPanel.add(inputTextField); inputLabel.setBounds(0, 150, 80, 20); inputTextField.setBounds(80, 130, 50, 50); inputTextField.addKeyListener(new inputKeyListener()); missesLabel = new JLabel("Misses:"); missesLabel.setFont(newFont); missesTextField = new JTextField(5); missesTextField.setEditable(false); missesTextField.setFont(newFont); missesTextField.setBorder(new EmptyBorder(0,0,0,0)); missesTextField.setOpaque(false); rightPanel.add(missesLabel); rightPanel.add(missesTextField); missesLabel.setBounds(0, 250, 80, 20); missesTextField.setBounds(80, 230, 250, 50); } private void selectDifficultyLevel() { String[] options = {"Easy", "Medium", "Hard"}; int level = JOptionPane.showOptionDialog(null, "Select difficulty level of words(easy 4-6 letters, Medium 7-10 letters, Hard 10+ letters)", "Difficulty Level", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, options, options[0]); System.out.println("level: " + options[level]); hiddenWord = hangmanLexicon.randomSelectWord(level).toUpperCase(); System.out.println(hiddenWord + ", length:" + hiddenWord.length()); // set displayedChars displayedLetters = new char[hiddenWord.length() * 2 - 1]; correctLetters = new char[hiddenWord.length()]; for (int i = 0; i < displayedLetters.length; i++) { if (i % 2 == 0) displayedLetters[i] = '_'; else displayedLetters[i] = ' '; } displayedCharsTextField.setText(String.copyValueOf(displayedLetters)); } /** * when enter key is pressed, check letter */ private class inputKeyListener extends KeyAdapter { @Override public void keyReleased(KeyEvent e) { if(e.getKeyCode() == KeyEvent.VK_ENTER){ if (inputTextField.getText().length() > 1) { JOptionPane.showMessageDialog(new JFrame(), "Please guess one letter at a time!", "Warninig", JOptionPane.WARNING_MESSAGE); } else if (inputTextField.getText().length() == 1) { char letter = inputTextField.getText().toUpperCase().charAt(0); if (!(letter >= 'A' && letter <= 'Z')) JOptionPane.showMessageDialog(new JFrame(), "Please input a letter!", "Warninig", JOptionPane.WARNING_MESSAGE); else checkLetter(letter); } inputTextField.setText(""); } } } /** * check the input letter * @param letter input letter */ private void checkLetter(char letter) { int index = hiddenWord.indexOf(letter); // hiddenWord doesn't contain the given letter if (index < 0) { incorrectCount++; hangmanPanel.incrementWrongGuesses(); // when wrong guess count greater than max wrong guesses, loss if (incorrectCount >= MAX_WRONG_GUESSES) { String[] options = {"Restart", "Quit"}; int level = JOptionPane.showOptionDialog(null, "You lose - the answer was " + hiddenWord + ".", "You lose", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, options, options[0]); if (level == 0) restart(); else System.exit(0); } else { if (!missedLettersSet.contains(letter)) { missedLettersSet.add(letter); if (missedLetters.isEmpty()) missedLetters = String.valueOf(letter); else missedLetters += "," + letter; // displayed missed letters missesTextField.setText(missedLetters); } } } else { // if guess right, writes it in all its correct positions. for (int i = 0; i < hiddenWord.length(); i++) { if (hiddenWord.charAt(i) == letter) { displayedLetters[i * 2] = letter; correctLetters[i] = letter; } } displayedCharsTextField.setText(String.copyValueOf(displayedLetters)); // check whether guess win if (String.copyValueOf(correctLetters).equals(hiddenWord)) { String[] options = {"Restart", "Quit"}; int level = JOptionPane.showOptionDialog(null, "You win - the answer was " + hiddenWord + ".", "You win", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, options, options[0]); if (level == 0) restart(); else System.exit(0); } } } private class MenuHandler implements ActionListener { @Override public void actionPerformed (ActionEvent e) { if(e.getSource() == menuItemRestart) { restart(); } } } /** * restart game */ private void restart() { missedLettersSet = new HashSet(); incorrectCount = 0; missesTextField.setText(""); missedLetters = ""; hangmanPanel.reset(); selectDifficultyLevel(); } public static void main(String[] args) { Hangman hangman = new Hangman(); } }
HangmanLexicon.java
import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.Random; public class HangmanLexicon { public static final int EASY = 0; // words with 4~6 letters public static final int MEDIUM = 1; // words with 7~10 letters public static final int HARD = 2; // words with 10+ letters private ArrayList easyWordList = new ArrayList(); private ArrayList mediumWordList = new ArrayList(); private ArrayList hardWordList = new ArrayList(); public HangmanLexicon(String lexiconFileDir) { try { // read easy.txt BufferedReader hangmanWords = new BufferedReader(new FileReader(new File(lexiconFileDir, "easy.txt"))); String line; while((line = hangmanWords.readLine()) != null) { line = line.toUpperCase(); easyWordList.add(line); } hangmanWords.close(); // read medium.txt hangmanWords = new BufferedReader(new FileReader(new File(lexiconFileDir, "medium.txt"))); while((line = hangmanWords.readLine()) != null) { line = line.toUpperCase(); mediumWordList.add(line); } hangmanWords.close(); // read hard.txt hangmanWords = new BufferedReader(new FileReader(new File(lexiconFileDir, "hard.txt"))); while((line = hangmanWords.readLine()) != null) { line = line.toUpperCase(); hardWordList.add(line); } hangmanWords.close(); } catch (IOException e) { e.printStackTrace(); } } /** Returns the word at the specified index. */ public String randomSelectWord(int level) { ArrayList wordList = null; switch (level) { case 0: wordList = easyWordList; break; case 1: wordList = mediumWordList; break; case 2: wordList = hardWordList; break; default: wordList = easyWordList; } int size = wordList.size(); Random rand = new Random(); int index = rand.nextInt(size); return wordList.get(index); } }
HangmanPanel.java
import java.awt.BasicStroke; import java.awt.Graphics; import java.awt.Graphics2D; import javax.swing.JPanel; public class HangmanPanel extends JPanel { // wrong guessed count private int wrongGuesses; /* Constants for the simple version of the picture (in pixels) */ private static final int SCAFFOLD_WIFTH = 20; private static final int BEAM_WIDTH = 12; private static final int HANGMAN_WIDTH = 5; private static final int SCAFFOLD_HEIGHT = 300; private static final int BEAM_LENGTH = 120; private static final int ROPE_LENGTH = 20; private static final int BASE_LENGTH = 200; private static final int HEAD_RADIUS = 36; private static final int BODY_LENGTH = 110; private static final int ARM_LENGTH = 70; private static final int ARM_ANGLE = 30; private static final int LEG_LENGTH = 85; private static final int LEG_ANGLE = 45; /** * This method should never be directly invoked, but is invoked by the repaint() method. * Depending on the number of wrongGuesses, it knows which body parts to draw. It also * sets the stroke of the lines so they are thicker than the default setting. */ public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; // paint scaffold drawScaffold(g2d); // paint hangman if (wrongGuesses == 1) { drawHead(g2d); } else if (wrongGuesses == 2) { drawHead(g2d); drawBody(g2d); } else if (wrongGuesses == 3) { drawHead(g2d); drawBody(g2d); drawLeftArm(g2d); } else if (wrongGuesses == 4) { drawHead(g2d); drawBody(g2d); drawLeftArm(g2d); drawRightArm(g2d); } else if (wrongGuesses == 5) { drawHead(g2d); drawBody(g2d); drawLeftArm(g2d); drawRightArm(g2d); drawLeftLeg(g2d); } else if (wrongGuesses == 6) { drawHead(g2d); drawBody(g2d); drawLeftArm(g2d); drawRightArm(g2d); drawLeftLeg(g2d); drawRightLeg(g2d); } } /** * Increments wrongGuesses, then repaints the man */ public void incrementWrongGuesses(){ wrongGuesses++; repaint(); } /** * Resets wrongGuesses back to zero and repaints the pain */ public void reset() { wrongGuesses = 0; repaint(); } private void drawScaffold(Graphics2D g2d) { // draw scaffold g2d.setStroke(new BasicStroke((float)SCAFFOLD_WIFTH)); int scaffoldX = getWidth()/2 + BEAM_LENGTH; int scaffoldTopY = getHeight()/2 - SCAFFOLD_HEIGHT/2; int scaffoldBottomY = getHeight()/2 + SCAFFOLD_HEIGHT/2; g2d.drawLine(scaffoldX, scaffoldTopY, scaffoldX, scaffoldBottomY); // draw base int baseRightX = (BASE_LENGTH - BEAM_LENGTH)/2 + scaffoldX; int baseLeftX = baseRightX - BASE_LENGTH; int baseY = scaffoldBottomY; g2d.drawLine(baseLeftX, baseY, baseRightX, baseY); // draw beam g2d.setStroke(new BasicStroke((float)BEAM_WIDTH)); int beamLeftX = scaffoldX - BEAM_LENGTH; int beamRightX = scaffoldX; int beamY = scaffoldTopY - (SCAFFOLD_WIFTH - BEAM_WIDTH)/2; g2d.drawLine(beamLeftX, beamY, beamRightX, beamY); // draw rope int ropeTopY = beamY; int ropeBottomY = ropeTopY + ROPE_LENGTH; int ropeX = beamLeftX; g2d.drawLine(ropeX, ropeTopY, ropeX, ropeBottomY); } private void drawHead(Graphics2D g2d) { g2d.setStroke(new BasicStroke((float)HANGMAN_WIDTH)); int x = getWidth()/2 - HEAD_RADIUS/2; int y = getHeight()/2 - SCAFFOLD_HEIGHT/2 - SCAFFOLD_WIFTH/2 + BEAM_WIDTH + ROPE_LENGTH; g2d.drawOval(x, y, HEAD_RADIUS, HEAD_RADIUS); } private void drawBody(Graphics2D g2d) { g2d.setStroke(new BasicStroke((float)HANGMAN_WIDTH)); int x = getWidth()/2 + BEAM_LENGTH - BEAM_LENGTH; int topY = getHeight()/2 - SCAFFOLD_HEIGHT/2 - SCAFFOLD_WIFTH/2 + BEAM_WIDTH + ROPE_LENGTH + HEAD_RADIUS; int bottomY = topY + BODY_LENGTH; g2d.drawLine(x, topY, x, bottomY); } private void drawLeftArm(Graphics2D g2d) { g2d.setStroke(new BasicStroke((float)HANGMAN_WIDTH)); int rightX = getWidth()/2 + BEAM_LENGTH - BEAM_LENGTH; int rightY = getHeight()/2 - SCAFFOLD_HEIGHT/2 - SCAFFOLD_WIFTH/2 + BEAM_WIDTH + ROPE_LENGTH + HEAD_RADIUS + BODY_LENGTH /3; int leftX = (int) (rightX - ARM_LENGTH * Math.cos((double)ARM_ANGLE / 180 * Math.PI)); int leftY = (int) (rightY - ARM_LENGTH * Math.sin((double)ARM_ANGLE / 180 * Math.PI)); g2d.drawLine(leftX, leftY, rightX, rightY); } private void drawRightArm(Graphics2D g2d) { g2d.setStroke(new BasicStroke((float)HANGMAN_WIDTH)); int leftX = getWidth()/2 + BEAM_LENGTH - BEAM_LENGTH; int leftY = getHeight()/2 - SCAFFOLD_HEIGHT/2 - SCAFFOLD_WIFTH/2 + BEAM_WIDTH + ROPE_LENGTH + HEAD_RADIUS + BODY_LENGTH / 3; int rightX = (int) (leftX + ARM_LENGTH * Math.cos((double)ARM_ANGLE / 180 * Math.PI)); int rightY = (int) (leftY - ARM_LENGTH * Math.sin((double)ARM_ANGLE / 180 * Math.PI)); g2d.drawLine(leftX, leftY, rightX, rightY); } private void drawLeftLeg(Graphics2D g2d) { g2d.setStroke(new BasicStroke((float)HANGMAN_WIDTH)); int rightX = getWidth()/2 + BEAM_LENGTH - BEAM_LENGTH; int rightY = getHeight()/2 - SCAFFOLD_HEIGHT/2 - SCAFFOLD_WIFTH/2 + BEAM_WIDTH + ROPE_LENGTH + HEAD_RADIUS + BODY_LENGTH; int leftX = (int) (rightX - LEG_LENGTH * Math.sin((double)LEG_ANGLE / 180 * Math.PI)); int leftY = (int) (rightY + LEG_LENGTH * Math.cos((double)LEG_ANGLE / 180 * Math.PI)); g2d.drawLine(leftX, leftY, rightX, rightY); } private void drawRightLeg(Graphics2D g2d) { g2d.setStroke(new BasicStroke((float)HANGMAN_WIDTH)); int leftX = getWidth()/2 + BEAM_LENGTH - BEAM_LENGTH; int leftY = getHeight()/2 - SCAFFOLD_HEIGHT/2 - SCAFFOLD_WIFTH/2 + BEAM_WIDTH + ROPE_LENGTH + HEAD_RADIUS + BODY_LENGTH; int rightX = (int) (leftX + LEG_LENGTH * Math.cos((double)LEG_ANGLE / 180 * Math.PI)); int rightY = (int) (leftY + LEG_LENGTH * Math.sin((double)LEG_ANGLE / 180 * Math.PI)); g2d.drawLine(leftX, leftY, rightX, rightY); } }