如何使用Java加载游戏,还可以返回游戏所处的状态?

时间:2015-11-10 20:15:45

标签: java serialization deserialization

我想首先说我在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;       
    }
}

1 个答案:

答案 0 :(得分:1)

好的,所以我做了一些挖掘,基本上我不应该使用静态变量来使用序列化作为保存方法,因为静态变量不是GamePanel对象的一部分而是类,所以当save方法保存时对象它实际上并没有保存静态变量。我制作了所有需要保存非静态的变量,一切都很好用