1

我在这里有两个时间问题,一旦获胜,都涉及到这个游戏的过程:https ://codepen.io/acchang/pen/XWePpWB

理想情况下,我应该(1)选择获胜空间(2)看到获胜空间被填满(3)有警报宣布获胜者。

我看到和不喜欢的是:

*checkForWinners()运行

  • winDeclared()运行并alert "winner"首先弹出

  • 然后在清除警报后,drawboard()运行,将获胜的棋子添加到游戏板上。

这在 Firefox 中并没有那么糟糕。这件作品是在警报弹出的同时添加的。

然后,在 中winDeclared(),我还更改了右上角的显示以指示获胜者。但swapTurns()似乎执行之前winDeclared()

那是因为winDeclared()两个功能深入checkForWinners()吗?有什么办法可以延缓吗?

谢谢!



let gameboard = [
                 [1,2,3,4,5,6,7],
                 [8,9,10,11,12,13,14],
                 [15,16,17,18,19,20,21],
                 [22,23,24,25,26,27,28],
                 [29,30,31,32,33,34,35],
                 [36,37,38,39,40,41,42]
                ];

let playerOne
let playerTwo
let indexPick
let availableSpots
let gameType
let playerOneTurn = true
document.getElementsByName("announcements")[0].innerHTML = "Current Player: " + whosPlaying() + " "

let itsAOnePlayerGame = true
let isThereAWinner = false

let mainDiv = document.createElement("div");
mainDiv.setAttribute('class', 'mainDiv')
document.body.append(mainDiv);

let selectorHolder = document.createElement("div") 
selectorHolder.setAttribute('class', 'selectorHolder')
selectorHolder.setAttribute('id', 'selectorHolder')
mainDiv.append(selectorHolder)

let selectorTable = document.createElement("table") 
selectorTable.setAttribute('class', 'selectorTable')
selectorTable.setAttribute('id', 'selectorTable')
selectorHolder.append(selectorTable)

function drawSelector() {  
    let selectorRow = document.createElement("tr") 
    selectorRow.setAttribute('class', 'selectorRow')
    selectorTable.append(selectorRow)

    for (i=0; i<7; i++){
        let selectorCell = document.createElement("td") 
        selectorCell.setAttribute('class', 'selectorCell')

        let innerSelectorCell = document.createElement("div") 
        innerSelectorCell.setAttribute('class', 'innerSelectorCell')
        innerSelectorCell.setAttribute('id', [i])
        selectorCell.append(innerSelectorCell)
        
        innerSelectorCell.addEventListener("mouseover", function(event) {
            if (playerOneTurn == true) {
            innerSelectorCell.classList.add('yellowBG')}
            else {innerSelectorCell.classList.add('redBG')
            }
        })

        innerSelectorCell.addEventListener("mouseout", function(event) {
            if (playerOneTurn == true) {
            innerSelectorCell.classList.remove('yellowBG')}
            else {innerSelectorCell.classList.remove('redBG')
            }
        })

        innerSelectorCell.onclick = function(){
                if (isThereAWinner == true){return}
                else {
                    indexPick = parseInt(this.id)
                    console.log(indexPick)
                    claimSpot()
                    }
        }

        selectorRow.append(selectorCell)
    }        
};


drawSelector()

// Draw Main Gameboard

let mainTable = document.createElement("table");
mainTable.setAttribute('class', 'mainTable')
mainDiv.append(mainTable)

function drawBoard() {
    for (i=0; i<gameboard.length; i++){
            let row = document.createElement("tr")
            mainTable.append(row)

                for (j=0; j<gameboard[i].length; j++){
                    let outerCell = document.createElement('td')
                    outerCell.setAttribute('class', 'outerCell')
                    row.append(outerCell)
                    let innerCell = document.createElement('div')
                    innerCell.setAttribute('class', 'innerCell')
                    innerCell.classList.add(gameboard[i][j])
                    innerCell.setAttribute('innerHTML', gameboard[i][j])
                    outerCell.append(innerCell)
                }   
            }
};

drawBoard()

function validateRadio() {
    let ele = document.getElementsByName('gameType');    
            for(i = 0; i < ele.length; i++) {
                if(ele[i].checked){
                gameType = (ele[i].value)
                beginGame()
                }
            }
};

function beginGame() {
    if (gameType == "1PEasy"){
        itsAOnePlayerGame = true
        resetBoard()
        onePlayerPickSides()
        play1PGame()
        }
    else if (gameType == "1PHard"){
        itsAOnePlayerGame = true
        resetBoard()
        onePlayerPickSides()
        play1PGame()
        }
    else if (gameType == "2P"){
        itsAOnePlayerGame = false
        resetBoard()
        twoPlayerPickSides()
        play2PGame()
        }
};

function resetBoard() {
    playerOneTurn = true
    isThereAWinner = false
    gameboard = [
        [1,2,3,4,5,6,7],
        [8,9,10,11,12,13,14],
        [15,16,17,18,19,20,21],
        [22,23,24,25,26,27,28],
        [29,30,31,32,33,34,35],
        [36,37,38,39,40,41,42]
       ];
}


function swapTurns() {
    selectorTable.innerHTML = ""
    drawSelector()
    playerOneTurn = !playerOneTurn
    document.getElementsByName("announcements")[0].innerHTML = "Current Player: " + whosPlaying() + "&nbsp;"
};

// GAMEPLAY

function playerSelects2P() {
    findAvailableSpots()

    // put an eventListener here?
    columnPick = prompt(whosPlaying() +  ', choose which column 1-7')


    if (availableSpots.includes(parseInt(columnPick))) 
        {console.log(columnPick)}
    else {
        alert("not available")
        playerSelects2P()}
};



function playerSelects1P() {
    if (whosPlaying() == playerTwo) {
        findAvailableSpots()
        columnPick = availableSpots[Math.floor(Math.random() * availableSpots.length)]
        return
    }
    else {playerSelects2P()}
};    

function whosPlaying() {
    if (playerOneTurn) {
    return "Yellow"
    } else {
    return "Red"
    }
};

// starts from the bottom row and claims spot when there it is a number (unoccupied)
function claimSpot(){
    findAvailableSpots()
    if (availableSpots.includes(indexPick+1)) {

    let i;
    for (i = 5; i > -1; i--) 
        {if (Number.isInteger(gameboard[i][indexPick])) {
            gameboard[i].splice((indexPick), 1, whosPlaying())
            mainTable.innerHTML = ""
            drawBoard()
            checkForWinners() 

            // do I need to put some sort of delay here for it not to go to swap turns right away?
            swapTurns()
            return
            }
        }
    }
    else {
        console.log(availableSpots)
        alert("Forbidden")
    }

};

// if there is a string in row[0], that column is no longer available.
// the cells are numbered from 1 to 7, not per index so you need to add one to indexPick to identify
function findAvailableSpots() {
    availableSpots = gameboard[0].filter(x => Number.isInteger(x) == true)
};


function checkForWinners() {
    horizontalCheck()
    verticalCheck()
    downrightCheck()
    uprightCheck()
}

// WIN CHECKERS
// a forloop evaluates a section of the matrix, moving through it and seeing if the 3 ahead match.
// it stops before going out of bounds

function findFour(w,x,y,z) {
    // Checks first cell against current player and all cells match that player
    return ((w == whosPlaying()) && (w === x) && (w === y) && (w === z));
};

function winDeclared() {
    isThereAWinner = true
    alert("winner")

    document.getElementsByName("announcements")[0].innerHTML = whosPlaying() + " wins!&nbsp;"
    // this does not show, it snaps to swap places
};

function uprightCheck() {
    for (r=5; r>2; r--) {
        for (c=0; c<4; c++){
            if (findFour(gameboard[r][c], gameboard[r-1][c+1], gameboard[r-2][c+2], gameboard[r-3][c+3])) {
                winDeclared()
                return
            }
        }
    }
};

function downrightCheck() {
    for (r=0; r<3; r++) {
        for (c=0; c<4; c++){
            if (findFour(gameboard[r][c], gameboard[r+1][c+1], gameboard[r+2][c+2], gameboard[r+3][c+3])) {
                winDeclared()
                return
            }
        }
    }
};


function verticalCheck() {
    for (r=5; r>2; r--) {
        for (c=0; c<7; c++){
            if (findFour(gameboard[r][c], gameboard[r-1][c], gameboard[r-2][c], gameboard[r-3][c])) {
                winDeclared()
                return
            }
        }
    }
};

function horizontalCheck() {
    for (r=0; r<6; r++) {
        for (c=0; c<4; c++){
            if (findFour(gameboard[r][c], gameboard[r][c+1], gameboard[r][c+2], gameboard[r][c+3])) {
                winDeclared()
                return
            }
        }
    }
};

4

1 回答 1

1

当您操作 DOM 时,操作本身是同步的,但浏览器决定用户何时真正看到更改。有时,在提示出现之前,浏览器没有时间重绘。为了解决这个问题,您可以将警报包装在 setTimeout() 中以延迟警报。

setTimeout(
function() {
  alert("winner")
}, 10)
于 2022-01-13T02:40:00.537 回答