★前回の記事
現在の実装では、フィールドに新しくピースが置かれたときにフィールドのピースを描画しています。 フィールドに置かれたビースを再描画する際、フィールドに置かれたピースが一気に置き換わる瞬間があります。
このような描画は少し唐突に思うので、 以下のようにピースを"戻す"過程を表示すると、自然に見えます。
今回はこの処理を追加します。
戻した状態をスタックに投入する
ピースを"戻す"表示をするために、戻した状態のフィールドをスタックに投入します。 ピースの種類を変えるたびに"戻す"ので、スタックに投入する際、最初に戻した状態をスタックに投入して、ピースのすべてのスピンを投入します。
"戻す"表示用のスタックデータのspinId
とspin
はnull
にします。
js/solver.js
const solver = { // 中略 init : (targetPieces) => { // 中略 targetPieces.forEach((pieceId) => { // 追加ここから solver.solverStack.push({kataminoField, minEmpty, pieceId, spinId:null, spin:null, unPlacedPiece: targetPiece, placedPieces}) // 追加ここまで KATAMINO_ARR[pieceId].forEach((spin, spinId) => { solver.solverStack.push({kataminoField, minEmpty, pieceId, spinId, spin, unPlacedPiece: targetPiece, placedPieces}) }) }) }, solve : (options) => { // 中略 nextUnPlaced.forEach((nextPieceId) => { // 追加ここから solver.solverStack.push({kataminoField: nextField, minEmpty: nextEmpty, pieceId:nextPieceId, spinId:null, spin: null, unPlacedPiece: nextUnPlaced, placedPieces: nextPlacedPieces}) // 追加ここまで KATAMINO_ARR[nextPieceId].forEach((nextSpin, nextSpinId) => { solver.solverStack.push({kataminoField: nextField, minEmpty: nextEmpty, pieceId:nextPieceId, spinId:nextSpinId, spin: nextSpin, unPlacedPiece: nextUnPlaced, placedPieces: nextPlacedPieces}) }) }) solver.timer = setTimeout(() => solver.solve(options), solver.speed) } // 後略 }
"戻した"状態の表示
spin
がnull
のときに、フィールド上のピースを更新するように変更します。
js/solver.js
const solver = { // 前略 solve : (options) => { const {onUpdatePieces = (placedPieces)=>{}, onSolved = ()=>{}, onNotSolved = ()=>{}} = options if (solver.solverStack.length <= 0) { console.log("解けなかった") onNotSolved() return } const {kataminoField, minEmpty, pieceId, spinId, spin, unPlacedPiece, placedPieces} = solver.solverStack.pop() // 追加ここから if (! spin) { onUpdatePieces(placedPieces) solver.timer = setTimeout(() => solver.solve(options), solver.speed) return } // 追加ここまで console.log("pieceId", pieceId) console.log("spinId", spinId) // 後略 }, // 後略 }
ここまでの実行結果
実行結果です。 ピースを戻すことによって、連続的に見えるようになりました。
しかし1つのピースの配置が長く表示される場合が出てきてしまいました。2回以上同じ表示がされているためです。1度"戻す"表示をして、そのまま別のピースが置かれず、再度同じ表示がされています。
表示時間の制御
前回と同じ表示の場合は、すぐに次のスタックを呼ぶ出すように変更します。前回と同じ表示かは、state.placedPieces
と表示しようとするplacedPieces
の長さが同じかどうかで判定します。
const solver = { // 前略 solve : (options) => { // 前略 const {kataminoField, minEmpty, pieceId, spinId, spin, unPlacedPiece, placedPieces} = solver.solverStack.pop() if (! spin) { // 変更ここから const timeout = state.placedPieces.length === placedPieces.length ? 0 : solver.speed onUpdatePieces(placedPieces) solver.timer = setTimeout(() => solver.solve(options), timeout) // 変更ここまで return } console.log("pieceId", pieceId) console.log("spinId", spinId) // 後略 }, // 後略 }
実行結果
実行結果です。フィールドに置かれたピースが等間隔で更新されるようになりました。
以上でピースを戻す表示を追加することができました。
おわりに
以上でKATAMINOを解くプログラムのチュートリアルはおしまいです。おつかれさまでした!
★目次