8、隨機佈雷數組
/// <summary> /// 隨機布地雷 /// </summary> /// <param name="mineNum">地雷數</param> private void SetRndMine(int mineNum) { for (int k = 0; k < mineNum; k++) { int nullnum = 0; for (int j = 0; j < _gameLevel._colGrid; j++) { for (int i = 0; i < _gameLevel._rowGrid; i++) { if (_backData[j, i] == (int)BackState.BLANK) nullnum++; } } if (nullnum < 1) return; int index = rnd.Next(1, nullnum); nullnum = 0; for (int j = 0; j < _gameLevel._colGrid; j++) { for (int i = 0; i < _gameLevel._rowGrid; i++) { if (_backData[j, i] == 0) { nullnum++; if (nullnum != index) continue; _backData[j, i] = (int)BackState.MINE; // 設置爲地雷 } } } } }
這個方法是否是很熟悉,咱們在2048遊戲中用到過,這裏就再也不多說了。
9、設置地雷旁邊的格子標註的地雷數值
原理就是讀取地雷位置,而後分別給不是地雷的格子數值+1。
/// <summary> /// 設置地雷周圍格子雷數 /// </summary> private void SetCellMineNumber() { for (int y = 0; y < _gameLevel._colGrid; y++) { for (int x = 0; x < _gameLevel._rowGrid; x++) { if (_backData[y, x] == (int)BackState.MINE) // 遇到地雷則周圍8格分別+1 { if (x - 1 > -1 && y - 1 > -1 && _backData[y - 1, x - 1] != (int)BackState.MINE) _backData[y - 1, x - 1]++; if (y - 1 > -1 && _backData[y - 1, x] != (int)BackState.MINE) _backData[y - 1, x]++; if (y - 1 > -1 && x + 1 < _gameLevel._rowGrid && _backData[y - 1, x + 1] != (int)BackState.MINE) _backData[y - 1, x + 1]++; if (x - 1 > -1 && _backData[y, x - 1] != (int)BackState.MINE) _backData[y, x - 1]++; if (x + 1 < _gameLevel._rowGrid && _backData[y, x + 1] != (int)BackState.MINE) _backData[y, x + 1]++; if (y + 1 < _gameLevel._colGrid && x - 1 > -1 && _backData[y + 1, x - 1] != (int)BackState.MINE) _backData[y + 1, x - 1]++; if (y + 1 < _gameLevel._colGrid && _backData[y + 1, x] != (int)BackState.MINE) _backData[y + 1, x]++; if (y + 1 < _gameLevel._colGrid && x + 1 < _gameLevel._rowGrid && _backData[y + 1, x + 1] != (int)BackState.MINE) _backData[y + 1, x + 1]++; } } } }
10、設置背景區圖片組spa
循環讀取背景區數據,根據數值設置對應的圖片源。code
private void SetBackCellImage() { BackCanvas.Children.Clear(); for (int y=0; y<_gameLevel._colGrid; y++) { for (int x=0; x<_gameLevel._rowGrid; x++) { _backImage[y, x] = new Image(); if (_backData[y, x] == (int)BackState.BLANK) { _backImage[y, x].Source = ImageHelper.CutImage(_bmpSpace, new Int32Rect(0, 0, _cellSize.Width, _cellSize.Height)); } else if (_backData[y, x] == (int)BackState.MINE) { _backImage[y, x].Source = ImageHelper.CutImage(_bmpMine, new Int32Rect(0, 0, _cellSize.Width, _cellSize.Height)); } else { for (int i = 0; i < 8; i++) { if (_backData[y, x] == (i+1)) { _backImage[y, x].Source = ImageHelper.CutImage( _bmpNum1_8, new Int32Rect(i * _cellSize.Width, 0, _cellSize.Width, _cellSize.Height)); break; } } } _backImage[y, x].SetValue(Canvas.LeftProperty, x * (double)_cellSize.Width); _backImage[y, x].SetValue(Canvas.TopProperty, y * (double)_cellSize.Height); BackCanvas.Children.Add(_backImage[y, x]); } } }
11、開始遊戲準備blog
根據遊戲級別分別調用隨機佈雷、設置雷邊數值方法,同時添加背景圖片數組到遊戲背景區。遊戲
private void ResetGame() { InitialGameState(); InitGameData(_level); textBlockMineNum.Text = _gameLevel._mineNum.ToString(); SetRndMine(_gameLevel._mineNum); SetCellMineNumber(); SetBackCellImage(); }
將該方法添加到開始遊戲菜單中,並計時器打開。圖片
private void MenuGameStart_Click(object sender, RoutedEventArgs e) { ResetGame(); _gameState = GameState.START; // 開始計時 _stopWatchGame.Start(); _timerSetTimeText.Start(); }
重複點擊開始菜單,看看效果。it
12、調整遊戲級別class
根據菜單設置的當前級別值設置菜單選擇狀態。原理
/// <summary> /// 設置級別菜單狀態 /// </summary> /// <param name="level"></param> private void SetMenuLevelState(Level level) { switch (level) { case Level.SIMPLE: MenuLowLevel.IsChecked = true; MenuMiddleLevel.IsChecked = false; MenuHighLevel.IsChecked = false; break; case Level.NORMAL: MenuLowLevel.IsChecked = false; MenuMiddleLevel.IsChecked = true; MenuHighLevel.IsChecked = false; break; case Level.HARD: MenuLowLevel.IsChecked = false; MenuMiddleLevel.IsChecked = false; MenuHighLevel.IsChecked = true; break; } }
/// <summary> /// 初級級別菜單 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void MenuLowLevel_Click(object sender, RoutedEventArgs e) { if (_level == Level.SIMPLE) return; if (MessageBox.Show("將用新難度級別重置遊戲,確認要繼續嗎?", "警告", MessageBoxButton.YesNo, MessageBoxImage.Asterisk) == MessageBoxResult.Yes) { _level = Level.SIMPLE; SetMenuLevelState(_level); ResetGame(); } } /// <summary> /// 中級級別菜單 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void MenuMiddleLevel_Click(object sender, RoutedEventArgs e) { if (_level == Level.NORMAL) return; if (MessageBox.Show("將用新難度級別重置遊戲,確認要繼續嗎?", "警告", MessageBoxButton.YesNo, MessageBoxImage.Asterisk) == MessageBoxResult.Yes) { _level = Level.NORMAL; SetMenuLevelState(_level); ResetGame(); } } /// <summary> /// 高級級別菜單 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void MenuHighLevel_Click(object sender, RoutedEventArgs e) { if (_level == Level.HARD) return; if (MessageBox.Show("將用新難度級別重置遊戲,確認要繼續嗎?", "警告", MessageBoxButton.YesNo, MessageBoxImage.Asterisk) == MessageBoxResult.Yes) { _level = Level.HARD; SetMenuLevelState(_level); ResetGame(); } }
十3、設置前景區圖片組object
/// <summary> /// 設置前景圖片數組 /// </summary> private void SetForeCellImages() { ForeCanvas.Children.Clear(); for (int y = 0; y < _gameLevel._colGrid; y++) { for (int x = 0; x < _gameLevel._rowGrid; x++) { if (_foreData[y, x] > (int)ForeState.NONE) { _foreImage[y, x] = new Image(); _foreImage[y, x].Source = ImageHelper.CutImage(_bmpForeground, new Int32Rect(0, 0, _cellSize.Width, _cellSize.Height)); _foreImage[y, x].SetValue(Canvas.LeftProperty, x * (double)_cellSize.Width); _foreImage[y, x].SetValue(Canvas.TopProperty, y * (double)_cellSize.Height); ForeCanvas.Children.Add(_foreImage[y, x]); } } } }
在ResetGame()方法最後位置加入對該方法的調用。
運行程序,看看效果。