网页版扫雷 -- React练习
開會不準帶電腦,手機app玩掃雷玩到眼快瞎,而且每次都要忍受長達十秒的廣告,自己寫一個算了。
詳細代碼在git里,還在更新。
第一步: React & webpack setup
用webpack主要目的是為了搭建一個簡單的webpack server, 順帶著直接用它打包發(fā)布好了.
set up React
React需要安裝一系列相關包,什么ReactDom啊之類的,直接 npm install XX --save-dev安裝之就好。
set up webpack
npm install webpack --save-dev
npm install webpack-dev-server --save-dev
npm install html-webpack-plugin --save-dev
--save-dev是因為這些包只為開發(fā)用,不是給user用的
然后配置一下webpack.config.js:
然后在package.json里面的
scripts里面添加:
這樣就可以用 npm run build來打包所有代碼到site里
用npm run start:dev來啟動本地的webpack server
webpack要點大概就這些了。配置好了之后就開始寫代碼了。
第二步: 生成一個布好雷的方格:
數據結構:
掃雷的數據結構沒什么可以糾結的,一個二維數組。
數據類型:
也沒啥好糾結的,數字嘛。
數字范圍就是1-8,也沒啥懸念嘛。 表示周圍有1-8個雷(玩了幾千把掃雷,只遇到過一次8)。
空白的格子就用0表示了,表示周圍沒有雷嘛。
還剩下一個9就用來表示雷好雷嘛。到此為止,一位數的數字全部用上了。
生成數組:
剩下的問題就是,怎么把這個數組生成出來。
首先,根據我?guī)浊О褣呃椎慕涷?#xff0c;這應該是個隨機生成的數組。不大可能有什么庫之類的。
那么如何隨機生成?
每一盤,雷的個數是不變的,那也就是說,我們可以隨機找?guī)讉€為止把雷放進去,然后計算剩下的每個格子周圍有多少個雷就可以了。
事情就簡單起來了:(以簡單為例子,10*8的矩陣,10個雷。)
- 可以先放進去10個9,70個0,然后shuffle 打亂順序
- 也可以先生成一個80個0 的數組,然后隨機抽取10個位置替換為9.
一個由0-9組成的二維數組就好了。注意數雷的時候小心處理邊界條件。
第三步:template和js入口
html
react的話 html 的template就很簡單了。只有幾行:
<!DOCTYPE html> <html> <head><meta charset="utf-8"><meta content="width=device-width, initial-scale=1" name="viewport" /><title>saolei</title> </head> <body> <div id="game-wrapper"/> </body> </html>第二行 meta是為了以后調mobile用的css用的
實際上html的本體只有一行,game-wrapper。 不用提react的事,也不用提css,也不用提scripts。
react入口:
上面的webpack說好了,入口要從src/index.js開始, 所以這個文件就是入口了,也很簡單:
import React from 'react'; import ReactDOM from 'react-dom' import Game from './components/Game';ReactDOM.render(<Game />, document.getElementById('game-wrapper'));將id為game-wrapper的元素替換為Game component. Game是從 ./components/Game里import的,但是不用提html的事情。 這兩個會在webpack打包的時候結合為一體。
打包之后的html: site/index.html:
第四步: Components:
請不要吐槽變量名字
最頂層的Components是Game
然后看,Game要包含啥
掃雷嘛,就一個MN的格子加上幾個按鈕(開始,難度),所以需要兩種Component: GameBoard和Button
最后:
GameBoard其實是有MN個小的格子組成,所以GameBoard需要一種Component: SingleGrid
所以components包如圖:
在下面解釋中,Game是GameBoard和Button的爸爸,GameBoard是SingleGrid的爸爸。
Game.jsx:
作為最頂層的Game,
GameBoard.jsx:
作為大格子,需要知道它爸爸定義了的游戲等級,自己有多少行多少列(從Game那里得到)
- fail: 左鍵點擊到了一個雷。
- win: 左鍵點擊到了最后一個還沒打開的數字。
- 都不是上面兩種情況,則是還在進行中。
除此之外,還需要知道哪些格子被打開了(如果點到空白的格子,需要檢查周圍的格子)。所以,在這一層維護了一個opened數組,用來記錄被打開了的格子,和方便計算成功或者失敗。
import React from 'react'; import SingleGrid from './SingleGrid'; import {generateGame} from "../service/dataService"; import '../styles/grid.css'class GameBoard extends React.Component {constructor(props) {super(props);const {totalRows, totalColumns, totalLei} = props;this.state = {gameMatrix: generateGame(totalRows, totalColumns, totalLei),opened: [],};//方法綁定this}gameFail(status) {/*被兒子調用,然后調用爸爸的gameFail方法*/};openGrid(position) {/*被兒子調用然后計算是不是最后一個數字格子,如果是,調用爸爸的gameWin方法*/};handleZero(position, totalRows, totalColumns){/*如果被兒子通知,點到空白的格子了,*//*則需要檢查四周格子,把所有空白格子都打開*/}render () {const { totalRows, totalColumns, gameStatus } = this.props;return (<ul> // 用兩個map加載小格子們{this.state.gameMatrix.map((row, rowNumber)=>(<p className="row" key={ rowNumber }>{row.map((grid, gridNumber) =><SingleGrid value={grid} {/*其他需要傳給小格子的屬性*/}></SingleGrid>)}</p>))}</ul>)} } export default GameBoardSingleGrid.jsx:
作為最小的單元,也是和user直接交互的component,需要知道:
如果輸了,還需要判斷被標記的狀態(tài)和實際狀態(tài)是不是相符,如果不是需要給出錯誤判斷:
Button.jsx:
一個簡單的component
class Button extends React.Component {render() {const {color,content,onClick,} = this.props;return (<button className={color} onClick={onClick}>{content}</button>)} } export default Button第五步: 處理用戶點擊事件:
這大概是最好玩兒最頭疼的一個步驟了。邏輯比較復雜,如果需要,請看源碼
在最開始的時候,所有的小格子都需要藏起來,這時候小格子的狀態(tài)是沒被打開過的。
左鍵點擊
根據上面的component設計,用戶點擊的是每一個小格子。每個小格子都知道自己的值,用戶點擊之后:
- 如果小格子的值是9, 那就是點到雷了,應該直接宣布失敗。這時候要一層層的告訴爸爸和爸爸的爸爸,游戲失敗了。
- 如果小格子的值是0,那么就是點到空白地方了,這時候要往外擴散。所以除了改自己的狀態(tài)之外,還需要告訴爸爸,點到0了,讓爸爸去打開自己周圍的格子,這時候爸爸需要一個遞歸,來打開這個格子周圍的所有為0的格子以及0外面一圈的格子。這時候,這個格子周圍的格子的狀態(tài)是由爸爸改變的,而不是通過用戶點擊。
- 如果小格子的值是1-8,這是最簡單的,直接翻開顯示數字就行。小格子的狀態(tài)改為打開。這時候有可能是最后一個還沒打開的格子,所以需要告訴爸爸,自己打開了,求檢查是不是最后一個,如果是,爸爸則會宣布游戲結束。
- 如果這個格子已經被打開了,則什么都不能做了
- 如果這個格子被標記成小紅旗了,則改到問號狀態(tài),或者是標記成問號狀態(tài),則改回到小紅旗。
右鍵點擊事件:
小紅旗和隱藏切換。
右鍵點擊事件比較抓狂的是,手機不支持右鍵,這個糾結過程在另一個博客里了
最后,圖片
小紅旗的圖片和雷的圖片用css就可以綁定到狀態(tài)上。className可以根據情況拼一個字符串出來。
最后的最后,戳這里可以直接開會的時候玩兒掃雷了。
總結
以上是生活随笔為你收集整理的网页版扫雷 -- React练习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言在函数中传递指针,[求助]关于文件
- 下一篇: Linux 文件系统 EXT4 的前世今