我一直在研究应该是一个相对简单的游戏,Mormon Sim。目标是在挨家挨户时进行成功的对话。这很简单,只需单击一个按钮,它就会根据调用的按钮和方法更改JLabel的文本。例如,使用Knock按钮将激活方法knockResponse,它将计算是否有人会来到门口。根据计算结果,有人会回答您的门,否则您将被拒之门外。问题是,经过几次点击后,通常一旦玩家通过敲击检查,JLabel就会开始回复到其他文本,并在几个不同的东西之间来回,有时完全无视他们的挥动计时器。我真的不知道这里发生了什么,我真的找不到这种情况会发生的原因。整整一周的谷歌搜索没有产生类似的问题或解决方案。 TL; DR Java已经自我意识
import java.util.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.Timer;
//To do: ASCII art in JLabels
public class mainMenu implements ActionListener{
static JButton start = new JButton("Start!"), knock = new JButton("Knock"), talk = new JButton("Talk"), stats = new JButton("Stats");
static int level = 1, stamina = 100, knocking = 1, speech = 1, points = 0;
static JFrame frame = new JFrame("Mormon Sim");
static mainMenu game = new mainMenu();
static JLabel text = new JLabel(), knockSkill, speechSkill, staminaBar;
static JPanel DoorMenu = new JPanel();
JTextField name = new JTextField("Enter your name here", 25);
static String playerName;
public JPanel createStartMenu(){//JPanel for the start menu. Replaced on start click
JPanel startMenu = new JPanel();
JLabel instructions = new JLabel("<html>Welcome to Mormon Adventure, the first text-based mormon sim. Your goal is to <br>hold as many successful door to door<br>conversations as possible. Every successful conversation earns you a<br>skill point and a level. Level 15 is a win!<br>A conversation requires stamina as it goes on, find Orange Crush to replenish your stamina<html>");
startMenu.setLayout(null);
startMenu.setLocation(0, 0);
startMenu.setSize(500, 500);
start.setLocation(200, 300);
start.setSize(100, 50);
start.addActionListener(this);
startMenu.add(start);
instructions.setLocation(100, 100);
instructions.setSize(300, 200);
startMenu.add(instructions);
name.setSize(150, 25);
name.setLocation(100, 50);
name.addActionListener(this);
startMenu.add(name);
startMenu.setOpaque(true);
return startMenu;
}
public JPanel createDoorMenu(){//used for knocking, speaking, and going to the stat page. The problem is here
talk.setEnabled(false);
String knockText = "<html>You walk up the driveway of the next house on your<br>list. As you approach the door, you adjust your<br>tie, and smooth your hair. Your mouth is dry, and<br>you could really go for a bottle of orange crush.<br>You decide you should get one after this house.<br>Time to knock, someone is clearly home.<html>";
DoorMenu.setLayout(null);
DoorMenu.setLocation(0, 0);
DoorMenu.setSize(500, 500);
text = new JLabel(knockText);
text.setLocation(100, 150);
text.setSize(300, 200);
DoorMenu.add(text);
knock.setLocation(100, 400);
knock.setSize(100, 50);
knock.addActionListener(this);
DoorMenu.add(knock);
talk.setLocation(200, 400);
talk.setSize(100, 50);
talk.addActionListener(this);
DoorMenu.add(talk);
stats.setLocation(300, 400);
stats.setSize(100, 50);
stats.addActionListener(this);
DoorMenu.add(stats);
knockSkill = new JLabel("Knocking: " +knocking+ " Speech: " +speech+ " Level: " +level+ " Skill Points: " +points);
knockSkill.setLocation(100, 25);
knockSkill.setSize(500, 50);
DoorMenu.add(knockSkill);
DoorMenu.setOpaque(true);
return DoorMenu;
}
public JPanel createStatMenu(){//still doesn't do anything
JPanel statMenu = new JPanel();
return statMenu;
}
public static void knockResponse(){//generates a response from a knock based on knock level (1 <= x <= 10). Random number (1 <= y <= 10) is generated, level determines how many are successful
//max knock level will shatter the door. 50/50 chance of conversation or police. max speech + police will talk them into letting you go
knock.setEnabled(false);
Random rand = new Random();
int n = rand.nextInt(10) + 1;
if(n > knocking){//knock check loss
text.setText("<html>All you hear is someone yelling to go away...<br>Oh well. You chipper up and go to<br>the next house on your list. That orange Crush<br>will have to wait!<html>");
ActionListener taskPerformer = new ActionListener(){//delay the label reset
public void actionPerformed(ActionEvent evt){
text.setText("<html>You walk up the driveway of the next house on your<br>list. As you approach the door, you adjust your<br>tie, and smooth your hair. Your mouth is dry, and<br>you could really go for a bottle of orange crush.<br>You decide you should get one after this house.<br>Time to knock, someone is clearly home.<html>");
knock.setEnabled(true);
}
};
new Timer(1000, taskPerformer).start();
}
if(n <= knocking && knocking != 10){//successful knock check
knock.setEnabled(false);
stats.setEnabled(false);
text.setText("<html>Someone's coming to the door!<br>You straighten your hair and adjust your tie.<html>");
ActionListener taskPerformer = new ActionListener(){//delay the label reset
public void actionPerformed(ActionEvent evt){
text.setText("<html>The door opens, and you introduce yourself;<br>\"Hi! my name is " +playerName+ ". Have you accepted my homeboy JC as your lord and savior?\"<html>");//I couldn't really think of anything to make him say other than that
talk.setEnabled(true);
}
};
new Timer(1000, taskPerformer).start();
}
if(knocking == 10){//door breaks
text.setText("<html>You managed to shatter the door thanks to<br>your orange crush powered knocking skeelz.<html>");
n = rand.nextInt(1) + 1;
if(n == 0){//response check. Both are empty for now
text.setText("0");
}else if(n == 1){
text.setText("1");
}
}
}
public static void successCalc(){//calculate the success in talking to someone by
talk.setEnabled(false);
Random rand = new Random();
int n = rand.nextInt(10) + 1;
if(n <= speech && speech != 10){
level++;
points++;
text.setText("<html>After some time, your conversation is over.<br>That went well. Better than you thought.<br>As you leave, you feel a rumbling in your gut.<br>It soon becomes painful. You fall to<br>the ground, and a gleaming light comes from<br>your stomach, as a skill point bursts out.<br>You hear a faint \"dunananaaa...\"<html>");
talk.setEnabled(false);
knockSkill.setText("Knocking: " +knocking+ " Speech: " +speech+ " Level: " +level+ " Skill Points: " +points);
}else if(n > speech){
talk.setEnabled(false);
text.setText("<html>After a moment of you speaking, all they do<br>is start blaring death metal.<br>You decide it's time to leave!<html>");
}else if(speech == 10){
text.setText("<html>Your golden, heavenly voice convinces them<br>to convert immediately.<br>You run down to the nearest convenience store<br>and grab yourself an orange Crush. Bottled, of course.<html>");
}
}
public void actionPerformed(ActionEvent e){
if(e.getSource() == start){
frame.getContentPane().removeAll();
frame.setContentPane(createDoorMenu());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setResizable(false);
frame.setVisible(true);
}else if(e.getSource() == knock){
knock.setEnabled(false);
knockResponse();
}else if(e.getSource() == talk){
talk.setEnabled(false);
successCalc();
}
playerName = name.getText();
}
public static void createAndShowGUI(){
JFrame.setDefaultLookAndFeelDecorated(false);
frame.setContentPane(game.createStartMenu());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setResizable(false);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run(){
createAndShowGUI();
}
});
}
}
感谢您的帮助,我很难提问。
答案 0 :(得分:4)
默认情况下为Timer
starts out repeating。所以,你的计时器每一秒都在燃烧,永远。
你应该致电setRepeats(false)
:
void doLater(ActionListener action, int delay) {
Timer timer = new Timer(delay, action);
timer.setRepeats(false);
timer.start();
}