【发布时间】:2014-04-04 11:19:01
【问题描述】:
我有(几乎)游戏的工作部分,但它们不能一起工作。我是一个完整的初学者,所以我不知道如何解决问题所在。 我有 3 节课:
- GameControls 包含游戏的主要功能。
- Hangman 设置一个 JFrame,调用 drawHangman 方法并包含 main 方法
- drawHangman 有绘制刽子手图形的说明
我怀疑这可能不是最好的方法,所以如果课程没有意义,请告诉我(并告诉我原因!)。
问题
- GameControls 自行运行良好。用户可以选择要猜测的字母,显示有效,如果猜测错误,则剩余寿命计数会下降。
但是
如果我从hangman main 方法运行,则会出现窗口并且控件不起作用没有了。 - 即使 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)中的第一行代码