團隊名稱:Sweephtml
團隊成員介紹:陳玉婷,彭佳妮,羅梅麗git
任務分配:算法
陳玉婷:文件管理,及掃雷遊戲算法實現,畫UML圖數組
彭佳妮:GUI登錄界面設置,用戶密碼驗證及其監聽,寫博客架構
羅梅麗:GUI登錄界面設置,寫博客ide
成員 | 博客連接 |
陳玉婷(組長) | https://www.cnblogs.com/chenyutin/p/10279348.html
|
彭佳妮 | http://www.javashuo.com/article/p-hspflokp-q.html |
羅梅麗 | https://www.cnblogs.com/luomeili/p/10281816.html |
https://gitee.com/pengjiani/mine_clearance佈局
提交記錄this
掃雷遊戲介紹:spa
《掃雷》是一款大衆類的益智小遊戲。遊戲目標是在最短的時間內根據點擊格子出現的數字找出全部非雷格子,同時避免踩雷,踩到一個雷即全盤皆輸。.net
遊戲設定:
遊戲區包括雷區,肯定大小的矩形雷區中隨機佈置必定數量的地雷(初級爲9*9個方塊9個雷,中級爲14*14個方塊14個雷,高級爲16*16個方塊16個雷,玩家須要儘快找出雷區中的全部不是地雷的方塊,而不準踩到地雷。
功能流程圖
功能構架圖
優秀設計部分
能夠保存遊戲進度,增長遊戲的靈活性和用戶體驗
保存遊戲進度
再次登錄時進入上一次遊戲
界面顯示模塊
//登錄界面設置 setSize(496, 557); setLayout(new GridLayout(2, 1)); // JMenuBar bar=new JMenuBar(); HomePanel panelN = new HomePanel("2018-01-10_12-55-41.gif"); HomePanel panelS = new HomePanel("ApplicationFrameHost_2018-01-10_13-37-17.png"); panelN.setLayout(new FlowLayout()); JButton button=new JButton(); button.setIcon(new ImageIcon("ApplicationFrameHost_2018-01-10_13-39-56.png")); //button.setOpaque(false); //設置控件透明 button.setBorder(null); //設置邊框 button.setContentAreaFilled(false); //設置控件透明 button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { System.exit(0); } }); //鍵盤監聽 KeyListener key_Listener = new KeyListener() { public void keyTyped(KeyEvent e) {} public void keyReleased(KeyEvent e){} public void keyPressed(KeyEvent e){ if(e.getKeyChar() == KeyEvent.VK_ENTER ) { String name = usenameField.getText(); String word = new String(passwordField.getPassword()); if(judge(name,word) == 0) JOptionPane.showMessageDialog(null, "用戶名不存在!"); else if(judge(name,word) == -1) JOptionPane.showMessageDialog(null, "密碼錯誤!"); else { Selection selection=new Selection(file); MFrame.this.dispose(); } try { file.setFileName(usenameField.getText()); // Selection selection=new Selection(file); } catch (Exception e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } } }; passwordField.addKeyListener(key_Listener);
咱們的掃雷由n x m 的方格區域構成,當咱們點擊其中一個方塊的時候,若是它不是雷,它就應當以數字的形式表示出在它外圈的一圈內包含有多少個雷,這個數字的範圍是1到8,在它不是雷的前提下,若是它周圍也沒有雷的話,那咱們點擊的方塊在下一秒應當展開當前的一片無雷的區域,以數字做爲邊界,該邊界指出外圈的雷的數目,咱們的作法是,以二維數組的形式定義一片區域,每二維數組上的每個數字映射着咱們雷區的每一塊方格,而後就是該二維數組的數字的範圍,咱們取整型數字的範圍爲0到9,用9來表示雷,用0到8來表示外圍雷的數目,咱們這裏的0在 後是不用來顯示在方塊上的,咱們判斷到方塊下面的數字是0的話咱們會讓雷區展開一片空白區域。
也就是說,咱們剛開始初始化了一個二維數組map,來映射一片雷區,其中的整型數字範圍爲0到9,用9來表示雷。
因此剛開始的代碼,將二維數組初始化爲0,接下來按行隨機和列隨機的方式隨機佈下指定數目的雷的數量,這樣,咱們 開始的並且也是掃雷中 實際的「雷區」(map)也就生成了。
但 終要實現用戶交互界面,因此須要將咱們的map映射到frame上,並能實現點擊交互。咱們這裏的作法是,使用按鈕,以爲使用按鈕能夠沒必要再去鼠標點擊的區域的具體座標,直接使用按鈕監聽器來實現對點擊位置的具體把控。
因此咱們在交互界面,frame上,咱們初始化了JButton數組,而後使用了gridlayout的網格佈局將按鈕佈置上去,剛開始的按鈕的外觀慘不忍睹,後來才採用了圖片的形式來替代默認的按鈕外觀。這些是外在,內在咱們還有不少須要考慮的地方。先記住咱們的初始化雷區map是0到9的二維數組。
好比,咱們剛開始須要爲用戶提供一個初始界面,就是都沒有被動過的按鈕,當用戶點擊的時候,須要展開區域,仍是顯示數字,仍是顯示雷,仍是標記此位置爲雷,每個按鈕的「狀態」即外觀都是不同的,而這些「狀態」的改變與咱們的map上面的數字不能直接造成一一映射的關係,也就是說,咱們狀態須要改變,可是咱們的map是咱們基本的雷區,是不能被改變的,並且0到9的範圍有10種狀態選擇,但咱們的交互界面須要的狀態變化有13種,因此爲了解決這種問題,咱們引入了一層隱藏層,來表示咱們的frame上面的每一塊方塊的狀態變化,咱們爲隱藏層命名爲hiddenmap,一樣爲咱們的int型以便於儲存多「狀態」。
部分代碼:
public void findZero(int i, int j) { if (hiddenmap[i][j] != 0) { if (map[i][j] == 0) { hiddenmap[i][j] = 0; if (i == 0) { if (j == 0) { if (map[i][j + 1] != 0 && map[i][j + 1] != 9) hiddenmap[i][j + 1] = map[i][j + 1]; if (map[i + 1][j] != 0 && map[i + 1][j] != 9) hiddenmap[i + 1][j] = map[i + 1][j]; } else if (j == length - 1) { if (map[i][j - 1] != 0 && map[i][j - 1] != 9) hiddenmap[i][j - 1] = map[i][j - 1]; if (map[i + 1][j] != 0 && map[i + 1][j] != 9) hiddenmap[i + 1][j] = map[i + 1][j]; } else { if (map[i][j - 1] != 0 && map[i][j - 1] != 9) hiddenmap[i][j - 1] = map[i][j - 1]; if (map[i + 1][j] != 0 && map[i + 1][j] != 9) hiddenmap[i + 1][j] = map[i + 1][j]; if (map[i][j + 1] != 0 && map[i][j + 1] != 9) hiddenmap[i][j + 1] = map[i][j + 1]; } } if (i == width - 1) { if (j == 0) { if (map[i][j + 1] != 0 && map[i][j + 1] != 9) hiddenmap[i][j + 1] = map[i][j + 1]; if (map[i - 1][j] != 0 && map[i - 1][j] != 9) hiddenmap[i - 1][j] = map[i - 1][j]; } else if (j == length - 1) { if (map[i - 1][j] != 0 && map[i - 1][j] != 9) hiddenmap[i - 1][j] = map[i - 1][j]; if (map[i][j - 1] != 0 && map[i][j - 1] != 9) hiddenmap[i][j - 1] = map[i][j - 1]; } else { if (map[i][j + 1] != 0 && map[i][j + 1] != 9) hiddenmap[i][j + 1] = map[i][j + 1]; if (map[i - 1][j] != 0 && map[i - 1][j] != 9) hiddenmap[i - 1][j] = map[i - 1][j]; if (map[i][j - 1] != 0 && map[i][j - 1] != 9) hiddenmap[i][j - 1] = map[i][j - 1]; } } if (j == 0) { if (i != 0 && i != width - 1) { if (map[i - 1][j] != 0 && map[i - 1][j] != 9) hiddenmap[i - 1][j] = map[i - 1][j]; if (map[i + 1][j] != 0 && map[i + 1][j] != 9) hiddenmap[i + 1][j] = map[i + 1][j]; if (map[i][j + 1] != 0 && map[i][j + 1] != 9) hiddenmap[i][j + 1] = map[i][j + 1]; } } if (j == length - 1) { if (i != 0 && i != width - 1) { if (map[i - 1][j] != 0 && map[i - 1][j] != 9) hiddenmap[i - 1][j] = map[i - 1][j]; if (map[i + 1][j] != 0 && map[i + 1][j] != 9) hiddenmap[i + 1][j] = map[i + 1][j]; if (map[i][j - 1] != 0 && map[i][j - 1] != 9) hiddenmap[i][j - 1] = map[i][j - 1]; } } if (i != 0 && i != width - 1 && j != 0 && j != length - 1) { if (map[i][j + 1] != 0 && map[i][j + 1] != 9) hiddenmap[i][j + 1] = map[i][j + 1]; if (map[i + 1][j] != 0 && map[i + 1][j] != 9) hiddenmap[i + 1][j] = map[i + 1][j]; if (map[i][j - 1] != 0 && map[i][j - 1] != 9) hiddenmap[i][j - 1] = map[i][j - 1]; if (map[i - 1][j] != 0 && map[i - 1][j] != 9) hiddenmap[i - 1][j] = map[i - 1][j]; } if (j >= 1) findZero(i, j - 1); if (i >= 1) findZero(i - 1, j); if (j <= getLength() - 2) findZero(i, j + 1); if (i <= getWidth() - 2) findZero(i + 1, j); } } }
ObjectInputStream readFile; if (file.isNewOne() == false) { try { readFile = new ObjectInputStream(new FileInputStream(file.getFileName())); this.minefield = (Minefield) readFile.readObject(); readFile.close(); if (minefield.isBoom() == true) { boom.play(); upset.play(); } else { playGame.play(); } } catch (FileNotFoundException e) { //不存在上局時,自動生成一局 this.minefield = new Minefield(file.getWidth(), file.getLength(), file.getLambnumber()); playGame.play(); // JOptionPane.showMessageDialog(null, "您還未開始遊戲,不存在上局哦!"); // e.printStackTrace(); } catch (IOException e) { // e.printStackTrace(); } }
改正步驟
第一種錯誤:缺乏覆蓋標誌@Override
第二種:缺乏大括號
不足:沒有設置計時器和剩餘雷的個數。按鈕沒法改變大小,因此限制了遊戲界面沒法改變大小。
改良:設置一下計時器和剩餘雷的個數,而後將按鈕設置成能隨着框的改變個改變大小,這就比較能夠了。