簡體   English   中英

單擊按鈕時嘗試更改游戲動作但不起作用

[英]Trying to change game move when clicked on a button but it doesn't work

我正在 react.js 中構建一個棋盤游戲,現在我正在嘗試添加一個允許用戶瀏覽游戲的功能。 我以為我搞定了,但它不起作用。 我檢查了我的對象是否是不可變的(它們應該是),我還檢查了是否調用了返回游戲步驟的 function,都沒有問題。 我不知道為什么它不起作用。 我該如何解決?

這是帶有游戲數據的構造函數 function:

constructor(props) {
        super(props);
        this.state = {
            // The Game Data Comes Here
            history: [{
                squares: [
                    Array(8).fill(null),
                    Array(8).fill(null),
                    Array(8).fill(null),
                    [null,null,null,'black','white',null,null,null],
                    [null,null,null,'white','black',null,null,null],
                    Array(8).fill(null),
                    Array(8).fill(null),
                    Array(8).fill(null)
                ]
            }],
            stepNumber: 0,
            blackIsNext: true,
            winner: null
        }
    }

這是我渲染的地方:

render() {
        // datas that will be rendered regularly come here
        const history = this.state.history
        const current = history[this.state.stepNumber]
        const moves = history.map((_, move) => {
            const desc = move ? 'Go to move #' + move : 'Go to game start';
            return (
              <li key={move}>
                <button onClick={() => this.jumpTo(move)}>{desc}</button>
              </li>
            );
        });

        // Return the game scene here
        return (
            <div className="master-container">
                <GameBoard squares={current.squares} onClick={(row,col) => {
                    if (!this.state.winner) {
                        const elems = this.checkElementsAround(this.checkEmptySpaces())
                        for (let el=0;el<elems.length;el++) {
                            const turning = this.checkTurningStones(elems[el].directions, this.state.blackIsNext)
                            if (turning.length !== 0) {
                                turning.unshift([row,col])
                                if (row === elems[el].coordinates[0] && col === elems[el].coordinates[1]) {
                                    this.handleMove(turning)
                                    this.setWinnerAndTurn()
                                    // Debug
                                    //console.log(history.length)
                                    console.log(moves)
                                    break
                                }
                            }                        
                        }
                    }
                }}/>
                <div>{(!this.state.winner) ? "Player Turn: " + `${(this.state.blackIsNext) ? 'Black' : 'White'}` : 'WINNER: ' + this.state.winner}</div>
                <div>{(this.state.winner) ? moves : null}</div>
            </div>
        )
    }

有些函數我不會放,因為它們所做的幾乎無關緊要,它們不會更改數據。 而且我也不會設置 setWinnerAndTurn function ,因為它只在游戲結束或切換玩家回合時定義游戲獲勝者,但這里的問題必須與我處理history數據的方式有關。

Function 處理移動和跳到游戲另一步驟的移動

handleMove(cords) {
        // You'll return if the game is already over or the value of the square is NOT null
        if (this.state.winner) {
            return
        }
        // Handle the recently made move here
        const history = this.state.history.slice(0, this.state.stepNumber + 1);
        const current = history[this.state.stepNumber];
        const squares = current.squares.slice()

        // You'll handle the click here
        for (var i=0;i<cords.length;i++) {
            squares[cords[i][0]][cords[i][1]] = (this.state.blackIsNext) ? "black" : "white"
        }


        this.setState({
            history: history.concat([{squares: squares}]),
            stepNumber: history.length,
        });
}

jumpTo(step) {
        this.setState({
          stepNumber: step,
          blackIsNext: (step % 2) === 0,
        });
    }

如果您認為缺少解決問題的方法,請告訴我。

此行中的賦值操作是您組件的 state 的突變。

squares[cords[i][0]][cords[i][1]] = (this.state.blackIsNext) ? "black" : "white"

這是一個突變,因為squares是來自this.state的數組的淺拷貝。 squares數組是新的,但正方形內的 arrays 是相同的。

您正在處理深度嵌套的數據,因此如果沒有 mutation 就很難更新 老實說,我會推薦一個像immer這樣的助手,它允許您對草稿 state 進行分配操作。

如果沒有助手,您必須通過squares map 並修改內部 arrays (至少是具有更改元素的那些)。 認為這是正確的,但請仔細檢查我沒有混淆行和列。

// Handle the recently made move here
const history = this.state.history.slice(0, this.state.stepNumber + 1);
const current = history[this.state.stepNumber];

// Apply changes to every square
const color = this.state.blackIsNext ? "black" : "white";
const nextSquares = current.squares.map((row, y) =>
  row.map((square, x) =>
    // find if this [x,y] is in the cords array and replace it if it is
    cords.some((cord) => cord[0] === x && cord[1] === y) ? color : square
  )
);

// Update the state
this.setState({
  history: history.concat({ squares: nextSquares }),
  stepNumber: history.length
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM