我想首先说我在Java中使用swing相对较新。我可以做摇摆做事,比如在游戏中,但我不确定我是否真的了解幕后发生的事情。所以,我开始研究游戏,有点像文明,用Java,我已经取得了不错的进展。我想把注意力转移到保存游戏并加载它。但是,我遇到了一些麻烦。所以我做了一些研究,我发现了一个可以序列化的对象并从那里保存/加载。这很有效,我可以保存我的游戏并加载它。问题是,一切都出现在屏幕上(地形图块,单位,HUD),但似乎存储在我的一些对象中的数据已经被设置回其初始化点。例如,我可以在X方向上以区块41结束,但是当我加载游戏时,它将其设置为0。
我如何设置游戏的简要说明:我有一个Main类,它创建一个新的Window对象。 Window对象本质上是一个包含按钮信息的JFrame和一个Panel类,它只是游戏绘制的JPanel。游戏中发生的一切都是在JPanel中创建的。我不是编程的新手,我是计算材料科学家,但我是用Java编写游戏的新手,我觉得我犯的是一个非常简单的错误。我将在下面发布JFrame和JPanel(部分内容,它很长)。
框架
public class GameWindow extends JFrame implements ActionListener
{
//ints
private int fCounter = 0;
//timers
private Timer t;
//Panels
private GamePanel gamePanel;
//menu bars
private JMenuBar menuBar;
//menus
private JMenu fileMenu;
//menu items
private JMenuItem save;
private JMenuItem load;
private JMenuItem exit;
private JMenuItem newGame;
//menu panels
private JPanel menuPanel;
//File objects
private File file;
//File Chooser
private JFileChooser chooser;
//user objects
private Player humanPlayer;
private AI aIPlayer;
private FileActions fileActions;
//**************************************************************************constructor
public GameWindow()
{
//set specifications for frame
super("New Game v 0.00: pre-Alpha");
this.setResizable(false);
setFocusable(true);
setSize(1600, 800);
//creates a new menubar
menuBar = new JMenuBar();
//craetes a new file menu
fileMenu = new JMenu("File");
//creates the file options
save = new JMenuItem("Save");
save.addActionListener(this);
load = new JMenuItem("Load");
load.addActionListener(this);
newGame = new JMenuItem("New Game");
newGame.addActionListener(this);
exit = new JMenuItem("Exit");
exit.addActionListener(this);
//adds file options to the file menu
fileMenu.add(save);
fileMenu.add(load);
fileMenu.add(newGame);
fileMenu.add(exit);
//adds the file menu to the menubar
menuBar.add(fileMenu);
//establishes the menu panel as a new JPanel
menuPanel = new JPanel();
//adds the menu to the menubar
menuPanel.add(menuBar);
//sets user class objects
humanPlayer = new Player();
aIPlayer = new AI();
fileActions = new FileActions();
//panels
gamePanel = new GamePanel();
gamePanel.setSize(750, 750);
gamePanel.setFocusable(true);
addKeyListener(gamePanel);
addMouseListener(gamePanel);
addMouseMotionListener(gamePanel);
setVisible(true);
//adds panels to the frame with layout
add(menuPanel, BorderLayout.EAST);
add(gamePanel, BorderLayout.CENTER);
//add file choosers
chooser = new JFileChooser();
//adds file objects
file = new File("");
//timers
t = new Timer(1, this);
t.start();
}
@Override
public void actionPerformed(ActionEvent e)
{
// TODO Auto-generated method stub
//save a game
if(e.getSource() == save)
{
//fCounter = chooser.showSaveDialog(this);
//if(fCounter == JFileChooser.APPROVE_OPTION)
//{
//file = chooser.getSelectedFile();
fileActions.addObject(gamePanel);
fileActions.saveGame();
//}
}
//load a save file
if(e.getSource() == load)
{
this.remove(gamePanel);
gamePanel = fileActions.loadGame();
this.add(gamePanel);
gamePanel.setFocusable(true);
addKeyListener(gamePanel);
addMouseListener(gamePanel);
addMouseMotionListener(gamePanel);
add(gamePanel, BorderLayout.CENTER);
setVisible(true);
}
//starts a new game
if(e.getSource() == newGame)
{
//gamePanel = null;
//gamePanel = new GamePanel();
gamePanel.setNewGameSetup(true);
gamePanel.setMainMenuView(false);
}
//exits the game
if(e.getSource() == exit)
{
System.exit(0);
}
gamePanel.repaint();
}
}
Panel Class的一部分
public class GamePanel extends JPanel implements
ActionListener,KeyListener,MouseListener,MouseMotionListener,Serializable
{
//globals
private static int mapHeight = 0;
private static int mapWidth= 0;
private static int currentMapHoriztonal= 0;
private static int currentMapVertical= 0;
private static int currentMouseMapHoriztonal= 0;
private static int currentMouseMapVertical= 0;
private static int turnNumber= 0;
private int unitFocusNumber = -1;
private int cityFocusNumber = -1;
private Terrain[][] terrain;
private ArrayList<Unit> playerUnits = new ArrayList<Unit>();
private ArrayList<City> playerCities = new ArrayList<City>();
private boolean terrainCreate = true;
private boolean mainMenu = true;
private boolean newGameSetup = false;
private boolean mapView = false;
private boolean mapSizeOptions = false;
private boolean playerTurn = true;
private boolean[] move = new boolean[4];
private Font mainMenuTitle = new Font("Algerian",Font.BOLD,75);
private Font mainMenuOptions = new Font("Calibri",Font.BOLD,15);
private Player player = new Player();
private FileActions fA;
private AI aI = new AI();
public GamePanel()
{
}
//getters
public int getMapHeight()
{
return mapHeight;
}
public boolean getMapView()
{
return mapView;
}
public Terrain[][] getTerrain()
{
return terrain;
}
//setters
public void setMapHeight(int height)
{
mapHeight = height;
}
public void setMapWidth(int width)
{
mapWidth = width;
}
public void setMapView(boolean b)
{
mapView = b;
}
public void setMainMenuView(boolean b)
{
mainMenu = b;
}
public void setNewGameSetup(boolean b)
{
newGameSetup = b;
}
//painters
//paints the game
public void paintComponent(Graphics g)
{
if(mainMenu == true)
{
paintMainMenu(g);
}
if(newGameSetup == true)
{
paintSetupScreen(g);
}
else if(mapView == true)
{
if(terrainCreate == true)
{
//sets the terrain
terrain = new Terrain[mapHeight][mapWidth];
for(int i = 0; i < mapHeight; i++)
{
for(int j = 0; j < mapWidth; j++)
{
terrain[i][j] = new Terrain(j,i,mapWidth,mapHeight);
terrain[i][j].setTerrain(j,i);
}
}
for(int i = 0; i < 4; i++)
{
playerUnits.add(new Scout(75*i,75*i));
}
playerUnits.add(new Settler(75*9,75*8));
playerUnits.add(new Settler(75*14,75*12));
terrainCreate = false;
}
if(terrainCreate == false)
{
paintTerrain(g);
paintCities(g);
paintUnits(g);
paintHud(g);
}
}
}
非常感谢任何帮助!
编辑: 这是实际加载和保存游戏的类。
public class FileActions implements Serializable
{
private ArrayList<Object> objects = new ArrayList<Object>();
//setters
public void addObject(Object o)
{
objects.add(o);
}
//getters
public void saveGame()
{
try
{ // Catch errors in I/O if necessary.
// Open a file to write to, named SavedObj.sav.
FileOutputStream saveFile=new FileOutputStream("NTT.sav");
// Create an ObjectOutputStream to put objects into save file.
ObjectOutputStream save = new ObjectOutputStream(saveFile);
// Now we do the save.
for(int i = 0; i < objects.size();i++)
{
save.writeObject(objects.get(i));
}
// Close the file.
save.close(); // This also closes saveFile.
}
catch(Exception exc)
{
exc.printStackTrace(); // If there was an error, print the info.
}
}
public GamePanel loadGame()
{
GamePanel stuff = new GamePanel();
try
{
// Open file to read from, named SavedObj.sav.
FileInputStream saveFile = new FileInputStream("NTT.sav");
// Create an ObjectInputStream to get objects from save file.
ObjectInputStream save = new ObjectInputStream(saveFile);
stuff = (GamePanel) save.readObject();
// Close the file.
save.close(); // This also closes saveFile.
}
catch(Exception exc)
{
exc.printStackTrace(); // If there was an error, print the info.
}
System.out.println(stuff);
return stuff;
}
}
答案 0 :(得分:1)
好的,所以我做了一些挖掘,基本上我不应该使用静态变量来使用序列化作为保存方法,因为静态变量不是GamePanel对象的一部分而是类,所以当save方法保存时对象它实际上并没有保存静态变量。我制作了所有需要保存非静态的变量,一切都很好用