我正在制作一个战舰游戏来学习反应。我生成并随机在船上放置5艘船,如果2艘船共享相同的网格,我想重新生成并重新放置每艘船。我主要尝试while循环,但大多数时候我得到了一个无限循环,或者一些意想不到的东西。我想问题是我不知道如何控制组件何时应该重新渲染。
这是我的代码(我删除了不必要的部分(:
const GameControl = () => {
const [playerBoard, setPlayerBoard] = useState(() => GameBoard('player'));
const [playerShipsArray, setPlayerShipsArray] = useState([]);
//setting up game
useEffect(() => {
generateShips()
}, [])
useEffect(() => {
// while(!checkTakenCells(playerShipsArray)){
// generateShips()
// } **this is the problematic part**
}, [playerShipsArray])
placeShipsOnBoard(playerShipsArray, playerBoard)
//setting up game
function generateShips() {
let shipsArr = [];
while(shipsArr.length < 5){
for(let i = 1; i < 6; i++){
let startCoord = Math.floor(Math.random() * 100);
const ship = Ship(i, i, isVertical(), startCoord)
shipsArr.push(ship)
}
setPlayerShipsArray(shipsArr)
}
function checkTakenCells (array){
let takenCells = [];
array.forEach(ship => takenCells.push(...ship.takenCells()))
//if 2 ships share the same coordinate, the takenCells array will have the shared coordinate twice
return new Set(takenCells).size === takenCells.length //If ships are colliding, returns false
}
function placeShipsOnBoard(array, board){
for (let i = 0; i < array.length; i++){
board.placeShip(array[i], array[i].startCoord)
}
}
return (
<>
//looping through playerBoard to generate a 10x10 grid
</>
)
}
const GameControl = () => {
const [playerBoard, setPlayerBoard] = useState(() => GameBoard('player'));
const [playerShipsArray, setPlayerShipsArray] = useState([]);
//setting up game
useEffect(() => { generateShips() }, [])
useEffect(() => {
// while(!checkTakenCells(playerShipsArray)){
// generateShips()
// } **this is the problematic part**
}, [playerShipsArray])
placeShipsOnBoard(playerShipsArray, playerBoard)
}
使用hooks
编写代码是可以的,但请记住,每当状态发生变化时,GameControl
内的所有内容都将重新运行。
这意味着placeShipsOnBoard
将被一次又一次地调用:(
这可能是一些样板代码,请记住React组件不是游戏机,它不会每毫秒运行一次。它只有在发生变化时才会运行。
const GameControl = () => {
const [ships, setShips] = useState([])
useEffect(() => {
setTimeout(() => {
// for every 50ms,
// move. the location of ships
setShips(newLocationShips)
}, 50)
}, [])
// render ships to the board
return (ships.map(ship => ())
你需要考虑一个没有变化的董事会,然后是基于某种事情而变化的船只,可能是事件或时间。