2013-10-03 72 views
1

我正在完成uni任務,我們獲得了掃雷遊戲的源代碼,並且我們有一定的實施要求。其中之一就是所有遊戲都是在用戶登錄後從磁盤讀取的,用戶可以隨時保存遊戲進度。我一直在閱讀序列化來保存/加載遊戲進度,但我發現有點難以理解這個概念。我不確定在哪裏開始爲此編寫代碼。遊戲並不像許多其他掃雷遊戲那樣使用2D陣列。有人可以給我指出任何易於理解的優秀文檔,我發現一些網頁有點過於技術性,我迷路了!或者如果有人知道更好的方式來保存掃雷遊戲的進度?對不起,如果我的問題很廣泛,我不能100%確定我應該閱讀什麼來了解這一點,所以這就是爲什麼我要求幫助,指出正確的方向。使用序列化保存遊戲(掃雷)進度java

+0

您可以保存並加載實現Serializable接口,流,從而文件任何Java對象。我建議你看看ObjectOutputStream和ObectInputStream。 – Nodebody

回答

0

您想要保存的有關STATE,遊戲中的所有信息。 這意味着,遊戲板(2D網格或者無論你存儲),球員的名字,比分等

技術有關如何序列化對象的部分相對比較簡單...請參閱http://www.javapractices.com/topic/TopicAction.do?Id=57。 但是,你必須小心諸如靜態或瞬態變量之類的東西,並且知道這些變量是如何影響序列化的(例如,靜態類對象不會被序列化,但會丟失)。

一旦你決定需要保存什麼,你可以創建一個包含所有重要對象的變量/引用的類 - 比如一個包裝器。這是如果你想避免保存許多不同的文件。 您也需要將implements Serialiable添加到將被序列化的對象的所有類定義。

所以,在我的例子中,我們編寫了SavedState包裝器對象,但是因爲這包含Board,所以Board也必須是可序列化的。你可以把你想保存的每個對象寫在一個單獨的文件中,但是我更喜歡在1個對象/文件中包含所有重要信息的對象,因爲我覺得它更清潔

然後,您可以進行作業並編寫您的對象。

所以舉例:

import java.io.BufferedInputStream; 
import java.io.BufferedOutputStream; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.ObjectInput; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutput; 
import java.io.ObjectOutputStream; 
import java.io.OutputStream; 
import java.io.Serializable; 
import java.util.ArrayList; 

public class Game { 

    Board board; 
    String name; 

    public static void main(String[] args) { 
     Game game = new Game(); 
     game.InitBoard(); 

     //Now save the board 
     game.SaveBoard(); 
     System.out.println("Player Name is:"+game.name); 
     System.out.println("Saved Board, changing in memory playername to 'test'."); 
     game.name = "test"; 
     game.LoadBoard(); 

     System.out.println("Loaded Board, Player Name is:"+game.name); 
    } 

    public void InitBoard() 
    { 
     board = new Board(); 
     name = "player..."; 
    } 

    public void SaveBoard() 
    { 
     try { 
      SavedState state = new SavedState(board, name); 
      OutputStream file = new FileOutputStream("game.mine"); 
      OutputStream buffer = new BufferedOutputStream(file); 
      ObjectOutput output = new ObjectOutputStream(buffer); 
      output.writeObject(state); 
      output.flush(); 
      output.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

    } 

    public void LoadBoard() 
    { 
     SavedState state; 

     InputStream file; 
     try { 
      file = new FileInputStream("game.mine"); 
      InputStream buffer = new BufferedInputStream(file); 
      ObjectInput input = new ObjectInputStream (buffer); 
      state = (SavedState)input.readObject(); 
      this.board = state.board; 
      this.name = state.playerName; 
      input.close(); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } catch (ClassNotFoundException e) { 
      e.printStackTrace(); 
     } 

    } 

} 

class Board implements Serializable { 
    ArrayList<Integer> boardElements = new ArrayList<Integer>(); // or however 
                    // else you 
                    // store 
                    // your 
                    // values 

    // etc... 

    public Board() { 
     boardElements.add(1); // etc... 
    } 

} 

class SavedState implements Serializable { 

    Board board; 
    String playerName; 

    public SavedState(Board board, String playerName) { 
     this.board = board; 
     this.playerName = playerName; 
    } 

} 
+0

謝謝你非常詳細的解釋,它開始沉入其中。我是否將'implements Serializable'添加到我當前的班級董事會(持有新遊戲的所有代碼),或僅添加到我爲保存要保存的數據而創建的新班級中?此外,您還使用擴展名.mine來保存電路板。我的軟件包被稱爲我的,那麼我將它保存爲什麼?或者說,我使用什麼擴展?我想我正在理解這個概念,但是它是如何保存然後發送到filechooser的,所以用戶可以從保存的遊戲列表中進行選擇。對不起,這可能是一個全新的問題:-) –

+0

你可以使用任何文件名+擴展名。所有保存的對象/數據必須是可序列化的 - 它們必須實現可序列化的接口。如果你忘記實現它,你會得到一個Exception,告訴你哪個類缺少implements方法。另外,如果你檢查許多Java類的定義(例如String和Hashmap),它們將支持序列化。例如。查看所有實現的接口:http://docs.oracle.com/javase/7/docs/api/java/lang/String.html。如果他們沒有,你將無法序列化這些實例。 –

1

基本上你實現序列化是什麼力量,你把它抱到一個序列化過程中,因此它可以被保存在內存中的所有對象的轉換。

序列化的正確實施,如果僅用於實體

class MinesweeperState implements Serializable { 
    private Board board; 
} 

class Board implements Serializable { 
    private int[][] mineTable; 
} 

不超過設置和獲取,邏輯內initializating表,填補了礦山並設置其周邊礦山櫃檯,我想設置代理或適配器。

爲節省本身,只使用一個經理與此代碼

FileOutputStream fos = null; 
    ObjectOutputStream out = null; 
try { 
    fos = new FileOutputStream(YOUR_FILENAME_CONSTANT,false); 
    out = new ObjectOutputStream(fos); 
    out.writeObject(minesweeperState); 
    out.close(); 
    System.out.println("Minesweeper state persisted"); 
} catch (IOException ex) { 
    LOGGER.err(ex); 
}