简体   繁体   English

如何在不手动单击屏幕来激发事件的情况下进入我的事件处理程序?

[英]How can I get inside my event handler without manually clicking the screen to stimulate an event?

I'm using cm-chessboard to create a chess opening trainer game.我正在使用cm-chessboard创建一个国际象棋开场教练游戏。 I will be controlling one side and eventually I will get the computer to move specific openings.我将控制一侧,最终我会让计算机移动特定的开口。

cm-chessboard has an examples page, and I started of with this example which is closest to my final idea. cm-chessboard 有一个示例页面,我从这个最接近我最终想法的示例开始。 At the moment, the computer moves randomly from the set of possible moves.目前,计算机从一组可能的移动中随机移动。

The example from github is only ever played from white's side. github 的例子只在白方播放。 I have tweaked the code to allow for black to play.我已经调整了代码以允许黑色播放。 However, when the game starts and I am playing black, I have to click a black piece to stimulate an event which causes white to make its first move, and we play on from there.然而,当游戏开始并且我在玩黑棋时,我必须点击一个黑棋来激发一个导致白棋迈出第一步的事件,然后我们从那里继续游戏。 This is because white always goes first.这是因为白色总是先行。

Here is my code:这是我的代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Chess Opening Trainer</title>
    <meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1.0"/>
    <link rel="stylesheet" href="/cm-chessboard/styles/cm-chessboard.css"/> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/chess.js/0.10.2/chess.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>

<div class="board" id="board" style="width: 800px; max-width: 800px"></div>

<div id="output"></div>

<script type="module">


    var side = 'black'

    if (side == 'white'){var colour = 'w'}else{var colour = 'b'}

    

    import {INPUT_EVENT_TYPE, COLOR, Chessboard, MARKER_TYPE} from "/cm-chessboard/src/cm-chessboard/Chessboard.js"
    import {BORDER_TYPE} from "/cm-chessboard/src/cm-chessboard/Chessboard.js"


    const chess = new Chess() //Creates a new Chess() object. Add a FEN string as an argument to start from a FEN.

    var oneTimeBool = true;

    function inputHandler(event) {

        console.log("event", event)
        event.chessboard.removeMarkers(undefined, MARKER_TYPE.dot)

        //Do this only once
        if (oneTimeBool == true && side == 'black'){
            event.chessboard.disableMoveInput()
            event.chessboard.setPosition(chess.fen())
            const possibleMoves = chess.moves({verbose: true})
                if (possibleMoves.length > 0) {
                    const randomIndex = Math.floor(Math.random() * possibleMoves.length)
                    const randomMove = possibleMoves[randomIndex]
                    setTimeout(() => { // smoother with 500ms delay
                        chess.move({from: randomMove.from, to: randomMove.to})
                        event.chessboard.enableMoveInput(inputHandler, colour)
                        event.chessboard.setPosition(chess.fen())
                    }, 500)
                }

            oneTimeBool = false;
        }

        //Before move. Clicking about, and showing dot for possible moves and such.
        if (event.type === INPUT_EVENT_TYPE.moveStart) {
            const moves = chess.moves({square: event.square, verbose: true});
            for (const move of moves) {
                event.chessboard.addMarker(move.to, MARKER_TYPE.dot)
            }
            return moves.length > 0

        //Here is once a move has been attempted    
        } else if (event.type === INPUT_EVENT_TYPE.moveDone) {
            const move = {from: event.squareFrom, to: event.squareTo} //gets which move was attempted from event
            const result = chess.move(move) //gets result of move
            
            if (result) { //if result is anyting then we processed
                event.chessboard.disableMoveInput()
                event.chessboard.setPosition(chess.fen())
                const possibleMoves = chess.moves({verbose: true})
                if (possibleMoves.length > 0) {
                    const randomIndex = Math.floor(Math.random() * possibleMoves.length)
                    const randomMove = possibleMoves[randomIndex]
                    setTimeout(() => { // smoother with 500ms delay
                        chess.move({from: randomMove.from, to: randomMove.to})
                        event.chessboard.enableMoveInput(inputHandler, colour)
                        event.chessboard.setPosition(chess.fen())
                    }, 500)
                }
            } else { //If result returns null, then we will loop back to the begining of the function to have another go with new dots.
                console.warn("invalid move", move)
            }
            return result
        }
    }

    const board = new Chessboard(document.getElementById("board"), {
        position: chess.fen(),
        sprite: {url: "/cm-chessboard/assets/images/chessboard-sprite-staunty.svg"},
        style: {moveMarker: MARKER_TYPE.square, hoverMarker: undefined},
        orientation: colour
    })
    board.enableMoveInput(inputHandler, colour)


</script>
</body>
</html>

It's pretty bad, I know.这很糟糕,我知道。 I'm sure there's much more elegant ways to do this.我确信有更优雅的方法可以做到这一点。

My problem is that when board.enableMoveInput(inputHandler_black, COLOR.black) calls the inputhandler_black function, the function waits for an event in order to begin.我的问题是,当board.enableMoveInput(inputHandler_black, COLOR.black)调用inputhandler_black function 时,function 等待事件才能开始。 When I play as white and inputHandler_white is called, this is fine because I have to make the first move anyway.当我扮演白棋并inputHandler_white时,这很好,因为无论如何我都必须迈出第一步。 When I play as black, I want the computer to automatically play the move without me having to click a random black piece to get it to start.当我玩黑棋时,我希望计算机自动下棋,而不必单击随机的黑棋子来启动它。

Anyone know how can I do that?有谁知道我该怎么做? Is there a way to force it into the function somehow without manually creating an event with the mouse?有没有办法以某种方式强制它进入 function 而无需使用鼠标手动创建事件?

This code piece makes the move against the player, so you should run this piece initially (right after chessboard initialize) when the player is black.此代码段对玩家进行移动,因此您应该在玩家为黑色时最初(在棋盘初始化之后)运行此代码段。

const possibleMoves = chess.moves({verbose: true})
if (possibleMoves.length > 0) {
    const randomIndex = Math.floor(Math.random() * possibleMoves.length)
    const randomMove = possibleMoves[randomIndex]
    setTimeout(() => { // smoother with 500ms delay
        chess.move({from: randomMove.from, to: randomMove.to})
        board.enableMoveInput(inputHandler, COLOR.black)
        board.setPosition(chess.fen())
    }, 500)
}

Here is the whole code:这是整个代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Chess Opening Trainer</title>
    <meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1.0"/>
    <link rel="stylesheet" href="/cm-chessboard/styles/cm-chessboard.css"/> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/chess.js/0.10.2/chess.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>

<div class="board" id="board" style="width: 800px; max-width: 800px"></div>

<div id="output"></div>

<script type="module">

    import {INPUT_EVENT_TYPE, COLOR, Chessboard, MARKER_TYPE} from "/cm-chessboard/src/cm-chessboard/Chessboard.js"
    import {BORDER_TYPE} from "/cm-chessboard/src/cm-chessboard/Chessboard.js"

    const side = 'black' //select which side to play as
    const chess = new Chess() //Creates a new Chess() object. Add a FEN string as an argument to start from a FEN.

    function inputHandler(event) {
        console.log("event", event)
        event.chessboard.removeMarkers(undefined, MARKER_TYPE.dot)

        //Before move. Clicking about, and showing dot for possible moves and such.
        if (event.type === INPUT_EVENT_TYPE.moveStart) {
            const moves = chess.moves({square: event.square, verbose: true});
            for (const move of moves) {
                event.chessboard.addMarker(move.to, MARKER_TYPE.dot)
            }
            return moves.length > 0

        //Here is once a move has been attempted    
        } else if (event.type === INPUT_EVENT_TYPE.moveDone) {
            const move = {from: event.squareFrom, to: event.squareTo} //gets which move was attempted from event
            const result = chess.move(move) //gets result of move
            
            if (result) { //if result is anyting then we processed
                event.chessboard.disableMoveInput()
                event.chessboard.setPosition(chess.fen())
                const possibleMoves = chess.moves({verbose: true})
                if (possibleMoves.length > 0) {
                    const randomIndex = Math.floor(Math.random() * possibleMoves.length)
                    const randomMove = possibleMoves[randomIndex]
                    setTimeout(() => { // smoother with 500ms delay
                        chess.move({from: randomMove.from, to: randomMove.to})
                        if(side === 'white') {
                            event.chessboard.enableMoveInput(inputHandler, COLOR.white)
                        }
                        else {
                            event.chessboard.enableMoveInput(inputHandler, COLOR.black)
                        }
                        event.chessboard.setPosition(chess.fen())
                    }, 500)
                }
            } else { //If result returns null, then we will loop back to the begining of the function to have another go with new dots.
                console.warn("invalid move", move)
            }
            return result
        }
    }


    if (side == 'white'){
        const board = new Chessboard(document.getElementById("board"), {
            position: chess.fen(),
            sprite: {url: "/cm-chessboard/assets/images/chessboard-sprite-staunty.svg"},
            style: {moveMarker: MARKER_TYPE.square, hoverMarker: undefined},
            orientation: COLOR.white
        })
        board.enableMoveInput(inputHandler, COLOR.white)
    }
    else{
        const board = new Chessboard(document.getElementById("board"), {
            position: chess.fen(),
            sprite: {url: "/cm-chessboard/assets/images/chessboard-sprite-staunty.svg"},
            style: {moveMarker: MARKER_TYPE.square, hoverMarker: undefined},
            orientation: COLOR.black
        })
        const possibleMoves = chess.moves({verbose: true})
        if (possibleMoves.length > 0) {
            const randomIndex = Math.floor(Math.random() * possibleMoves.length)
            const randomMove = possibleMoves[randomIndex]
            setTimeout(() => { // smoother with 500ms delay
                chess.move({from: randomMove.from, to: randomMove.to})
                board.enableMoveInput(inputHandler, COLOR.black)
                board.setPosition(chess.fen())
            }, 500)
        }
        console.log(board)
    }

</script>
</body>
</html>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在事件处理程序中获取javascript事件对象? - How can I get the javascript event object inside a event handler? 如何在javascript事件处理程序中获取对象? - How can I get an object inside a javascript event handler? 如何防止事件处理程序内的回调内的Default? - How can I preventDefault inside a callback inside an event handler? 当图像实际出现在屏幕上时,如何让jQuery调用事件处理程序? - How can I get jQuery to call an event handler when an image actually appears on-screen? 如何让 clientX 和 clientY 在 Firefox 上的“拖动”事件处理程序中工作? - How do I get clientX and clientY to work inside my “drag” event handler on Firefox? 如何手动触发骨干点击事件而无需实际点击 - How to manually trigger a backbone click event without actually clicking 如何从Marionette事件处理程序中选择元素? - How can I select an element from inside a Marionette event handler? 我可以在事件中调用另一个事件处理程序吗? - Is it possible that I can call another event handler inside an event? 如何让我的“点击”事件处理程序引用这些特定元素? - How can I get my 'click' event handler to reference these specific elements? 如何将我的元素带入事件处理函数? - how can I carry my element into the event handler function?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM