问题
当我从PetUI
类中的actionPerformed
函数启动StartGUI
主类时,PetUI
对话框没有从屏幕上的任何内容开始,但似乎在后台运行。为了进行调试,宠物会在几秒钟内死亡。宠物死亡后,屏幕将更新,您可以看到正确的屏幕,直到您按OK(确定)为止,它将再次加载StartGUI
类,以便您可以制作新的宠物并重新开始。
笔记
当我直接从IDE中运行PetUI
main时,它将正确加载并执行所有功能,而不会出现错误。
图片:
从StartGUI
类开始时:
左边的对话框是StartGUI
类,然后右边的对话框是从StartGUI
类开始的PetUI类。
宠物死亡后:
现在宠物已经死了,您可以简单地看到PetUI
类已经更新了其对话框,并且可以看到正确显示的内容。
直接从IDE(IntelliJ Idea)运行PetUI
现在您可以看到它可以正常工作。
代码PetUI
类别:
package vps.main.gui;
import vps.main.Pet;
import vps.util.io;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* Created by XXXX on 3/23/2016.
*/
public class PetUI extends JFrame implements ActionListener {
public static Pet mainPet = new Pet("Unknown Pet", 100, 100, 100, 100);
static JProgressBar healthBar = new JProgressBar(0, 100);
static JProgressBar hungerBar = new JProgressBar(0, 100);
static JProgressBar happinessBar = new JProgressBar(0, 100);
static JLabel foodCount = new JLabel();
static JLabel medpackCount = new JLabel();
static int medpacks = 10;
static int food = 25;
static JMenuBar menuBar = new JMenuBar();
JLabel petInfo = new JLabel("Name:" + mainPet.getName() + " | Age: "+mainPet.getAge());
JMenu file = new JMenu("File");
JMenuItem save = new JMenu("Save");
JButton healButton = new JButton("", new ImageIcon("src\\vps\\files\\ambulanceIcon.png"));
JButton feedButton = new JButton("", new ImageIcon("src\\vps\\files\\feedIcon.png"));
JButton playButton = new JButton("", new ImageIcon("src\\vps\\files\\playIcon.png"));
JButton quitButton = new JButton("", new ImageIcon("src\\vps\\files\\quitIcon.png"));
JPanel buttons = new JPanel();
JPanel bars = new JPanel();
public PetUI() {
super("Pet UI");
setLayout(new FlowLayout());
buttons.add(healButton);
buttons.add(feedButton);
buttons.add(playButton);
buttons.add(quitButton);
bars.add(healthBar);
bars.add(hungerBar);
bars.add(happinessBar);
happinessBar.setStringPainted(true);
hungerBar.setStringPainted(true);
healthBar.setStringPainted(true);
happinessBar.setString("Happiness");
hungerBar.setString("Hunger");
healthBar.setString("Health");
healButton.setBorderPainted(false);
healButton.setContentAreaFilled(false);
healButton.setFocusPainted(false);
feedButton.setBorderPainted(false);
feedButton.setContentAreaFilled(false);
feedButton.setFocusPainted(false);
playButton.setBorderPainted(false);
playButton.setContentAreaFilled(false);
playButton.setFocusPainted(false);
quitButton.setBorderPainted(false);
quitButton.setContentAreaFilled(false);
quitButton.setFocusPainted(false);
playButton.addActionListener(this);
healButton.addActionListener(this);
feedButton.addActionListener(this);
quitButton.addActionListener(this);
save.addActionListener(this);
add(petInfo);
add(medpackCount);
add(buttons);
add(foodCount);
add(bars);
menuBar.add(file);
file.add(save);
}
public static int getMedpacks() {
return medpacks;
}
public static void setMedpacks(int medpacks) {
PetUI.medpacks = medpacks;
}
public static void main(String[] args) {
PetUI p = new PetUI();
p.setJMenuBar(menuBar);
p.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
p.setSize(640, 480);
p.setVisible(true);
while (true) {
happinessBar.setValue((int) Math.round(mainPet.getHappiness()));
healthBar.setValue((int) Math.round(mainPet.getHealth()));
hungerBar.setValue((int) Math.round(mainPet.getHunger()));
mainPet.setHappiness(mainPet.getHappiness() - 0.1);
mainPet.setHunger(mainPet.getHunger() - 0.5);
//color set
/**
* if val greater than 75 = great
* if val less than 75 = good
* if val less than 50 = OK
* if val less than 25 = bad
* if val less than or equ 0 = dead/horrible
*/
if (mainPet.getHappiness() > 75) {
happinessBar.setString("Ecstatic");
happinessBar.setForeground(Color.green);
}
if (mainPet.getHappiness() <= 75) {
happinessBar.setString("Happy");
happinessBar.setForeground(Color.magenta);
}
if (mainPet.getHappiness() <= 50) {
happinessBar.setString("OK");
happinessBar.setForeground(Color.orange);
}
if (mainPet.getHappiness() <= 25) {
happinessBar.setString("Sad");
happinessBar.setForeground(Color.red);
}
if (mainPet.getHappiness() <= 0) {
happinessBar.setString("Horrible");
happinessBar.setForeground(Color.black);
}
if (mainPet.getHealth() > 75) {
healthBar.setString("Great");
healthBar.setForeground(Color.green);
}
if (mainPet.getHealth() <= 75) {
healthBar.setString("Good");
healthBar.setForeground(Color.magenta);
}
if (mainPet.getHealth() <= 50) {
healthBar.setString("OK");
healthBar.setForeground(Color.orange);
}
if (mainPet.getHealth() <= 25) {
healthBar.setString("Requires attention");
healthBar.setForeground(Color.red);
}
if (mainPet.getHealth() <= 0) {
healthBar.setString("Death");
healthBar.setForeground(Color.black);
JOptionPane.showMessageDialog(null, "Your pet: " + mainPet.getName() + " has died.");
p.dispose();
StartGUI.main(null);
break;
}
if (mainPet.getHunger() > 75) {
hungerBar.setString("Full");
hungerBar.setForeground(Color.green);
}
if (mainPet.getHunger() <= 75) {
hungerBar.setString("Great");
hungerBar.setForeground(Color.magenta);
}
if (mainPet.getHunger() <= 50) {
hungerBar.setString("Hungry");
hungerBar.setForeground(Color.orange);
}
if (mainPet.getHunger() <= 25) {
hungerBar.setString("Empty");
hungerBar.setForeground(Color.red);
}
if (mainPet.getHunger() <= 0) {
hungerBar.setString("Starving");
hungerBar.setForeground(Color.black);
}
//death values
if (mainPet.getHunger() <= 5) {
mainPet.setHealth(mainPet.getHealth() - 1);
}
if (mainPet.getHealth() <= 45) {
mainPet.setHappiness(mainPet.getHappiness() - 1);
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static int getFood() {
return food;
}
public static void setFood(int food) {
PetUI.food = food;
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == quitButton) {
int quit = JOptionPane.showConfirmDialog(null, "Are you sure you want to quit?");
if (quit == 0) {
System.exit(0);
} else {
//do nothing, just stay
}
} else if (e.getSource() == feedButton) {
if (getFood() <= 0) {
JOptionPane.showMessageDialog(null, "You are out of food.");
} else if (mainPet.getHunger() > 100) {
JOptionPane.showMessageDialog(null, "You do not need food right now.");
} else {
mainPet.setHunger(mainPet.getHunger() + 20);
setFood(getFood() - 1);
}
} else if (e.getSource() == healButton) {
if (getMedpacks() <= 0) {
JOptionPane.showMessageDialog(null, "You are out of medpacks.");
} else if (mainPet.getHealth() > 100) {
JOptionPane.showMessageDialog(null, "You do not need a medpack right now.");
} else {
if(mainPet.getHealth() + 20 >= 100) {
JOptionPane.showMessageDialog(null, "You do not need a medpack right now.");
}
else {
setMedpacks(getMedpacks() - 1);
}
}
}
else if(e.getSource() == save) {
io.replaceMainPet("");
}
}
}
StartGUI
类别:package vps.main.gui;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import vps.util.io;
import vps.util.io.*;
/**
* Created by XXX on 3/25/2016.
*/
public class StartGUI extends JFrame implements ActionListener {
public static String readPath = "";
static JMenuBar menuBar = new JMenuBar();
JLabel vpstitle = new JLabel("VPS Alpha 1.2",JLabel.CENTER);
JMenu fileMenu = new JMenu("File");
JMenuItem newSave = new JMenuItem("New Save");
JMenuItem openSave = new JMenuItem("Open Save");
JButton play = new JButton("Play");
JButton help = new JButton("Help");
public StartGUI() {
super("Startup");
setLayout(new GridLayout(3,3));
add(vpstitle);
add(play);
add(help);
play.addActionListener(this);
menuBar.add(fileMenu);
fileMenu.add(newSave);
fileMenu.add(openSave);
newSave.addActionListener(this);
openSave.addActionListener(this);
vpstitle.setFont(new Font ("Segoe Print", Font.BOLD , 72));
}
public static void main(String[] args) {
StartGUI s = new StartGUI();
s.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
s.setSize(720,480);
s.setJMenuBar(menuBar);
s.setVisible(true);
}
public static String getReadPath() {
return readPath;
}
public static void setReadPath(String readPath) {
StartGUI.readPath = readPath;
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == play) {
try {
if (readPath.equalsIgnoreCase("")) {
JOptionPane.showMessageDialog(null, "Please select a save file.\nFile --> Open Save / New Save");
}
else {
PetUI.main(null);
}
}
catch(NullPointerException n) {
JOptionPane.showMessageDialog(null,"You didn't choose a file.");
}
}
else if(e.getSource() == newSave) {
String saveName = JOptionPane.showInputDialog(null,"Please name this save file:");
JOptionPane.showMessageDialog(null,"Select your new save directory.");
JFileChooser jf = new JFileChooser();
jf.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
jf.showOpenDialog(null);
readPath = jf.getSelectedFile().getAbsolutePath()+"\\"+ saveName+".bin";
io.write(readPath);
io.replaceMainPet(readPath);
} else if (e.getSource() == openSave) {
JOptionPane.showMessageDialog(null,"Press OK to select your previous save file.");
JFileChooser jf = new JFileChooser();
jf.showOpenDialog(null);
readPath = jf.getSelectedFile().getAbsolutePath();
io.replaceMainPet(readPath);
}
}
}
最佳答案
将您的游戏循环放入线程中。它正在执行您的游戏逻辑,而不是更新swing gui,这就是为什么您需要将它们拆分的原因。我还建议向Pet.java
中添加一个boolean方法作为isAlive()
,以便在您的宠物死亡或游戏结束时线程死亡。例如在PetUI.java
中:
public static void main(String[] args) {
PetUI p = new PetUI();
p.setJMenuBar(menuBar);
p.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
p.setSize(640, 480);
p.setVisible(true);
Thread game = new Thread(new Runnable(){
public void run() {
while (true) { // while(mainPet.isAlive())
happinessBar.setValue((int) Math.round(mainPet.getHappiness()));
healthBar.setValue((int) Math.round(mainPet.getHealth()));
hungerBar.setValue((int) Math.round(mainPet.getHunger()));
mainPet.setHappiness(mainPet.getHappiness() - 0.1);
mainPet.setHunger(mainPet.getHunger() - 0.5);
// the rest of your game method
}
}
}
game.start();
}