问答详情
源自:2-5 游戏实例代码的调试(2)

简略版的完整代码,可以玩一哈~

<!DOCTYPE html>

<html>


<head>

    <meta charset="UTF-8">

    <title>Document</title>

    <style>

    #stage {

        width: 300px;

        height: 300px;

        position: relative;

    }


    #background {

        width: 300px;

        height: 300px;

        position: absolute;

        top: 0;

        left: 0;

        background: yellow;

    }


    #cannon {

        width: 20px;

        height: 20px;

        position: absolute;

        top: 270px;

        left: 140px;

        background: red;

    }


    #alien {

        width: 20px;

        height: 20px;

        position: absolute;

        top: 20px;

        left: 80px;

        background: blue;

    }


    #missile {

        width: 10px;

        height: 10px;

        position: absolute;

        top: 270px;

        left: 140px;

        background: black;

    }


    #explosion {

        width: 20px;

        height: 20px;

        position: absolute;

        top: 0;

        left: 0;

        background: pink;

        display: none;

    }

    </style>

</head>


<body>

    <div id="stage">

        <div id="background"></div>

        <div id="cannon"></div>

        <div id="missile"></div>

        <div id="alien"></div>

        <div id="explosion"></div>

    </div>

    <p id="output">请输入x和y坐标(0-300),然后点击fire</p>

    <input type="text" id="inputX" placeholder="X...">

    <input type="text" id="inputY" placeholder="Y...">

    <button>fire</button>

    <script>

    function BinaryTree() {

        var Node = function(key) {

            this.key = key;

            this.left = null;

            this.right = null;

            this.selected = false;

        };


        var root = null;


        var insertNode = function(node, newNode) {

            if (newNode.key < node.key) {

                if (node.left === null) {

                    node.left = newNode;

                } else {

                    insertNode(node.left, newNode);

                }

            } else {

                if (node.right === null) {

                    node.right = newNode;

                } else {

                    insertNode(node.right, newNode);

                }

            }

        }


        this.insert = function(key) {

            var newNode = new Node(key);

            if (root == null) {

                root = newNode;

            } else {

                insertNode(root, newNode);

            }

        };


        var inOrderTraverseNode = function(node, callback) {

            if (node !== null) {

                inOrderTraverseNode(node.left, callback);

                callback(node.key);

                inOrderTraverseNode(node.right, callback);

            }

        }


        this.inOrderTraverse = function(callback) {

            inOrderTraverseNode(root, callback);

        }


        var searchNode = function(node, key) {

            if (node === null) {

                return false;

            }


            if (key < node.key) {

                return searchNode(node.left, key);

            } else if (key > node.key) {

                return searchNode(node.right, key);

            } else {

                return node;

            }

        }


        this.search = function(key) {

            return searchNode(root, key);

        }




    }



    var callback = function(key) {

        console.log(key);

    };



    // init alienSiteArray

    var nodesForAlien = [];

    for (var i = 0; i < 10; i++) {

        nodesForAlien.push(Math.floor(Math.random() * 281));

    }


    // nodesArray for selected

    var nodesForSelected = [];

    for (var i = 0; i < 10; i++) {

        nodesForSelected.push({selected: false});

    }


    // activate first alienSite

    var alienNodeSelect = Math.floor(Math.random() * 9);

    nodesForSelected[alienNodeSelect].selected = true;


    var binaryTree = new BinaryTree();

    nodesForAlien.forEach(function(key) {

        binaryTree.insert(key)

    });




    //Game section

    var alienX = 20;

    var alienY = 20;

    var guessX = 0,

        guessY = 0,

        shotsRemaning = 8,

        shotsMade = 0,

        gameState = "",

        gameWon = false;


    var cannon = document.querySelector("#cannon"),

        alien = document.querySelector("#alien"),

        missile = document.querySelector("#missile"),

        explosion = document.querySelector('#explosion');


    var inputX = document.querySelector('#inputX'),

        inputY = document.querySelector('#inputY'),

        output = document.querySelector('#output');


    var button = document.querySelector("button");

    button.style.cursor = "pointer";

    button.addEventListener("click", clickHandler, false);

    window.addEventListener("keydown", keydownHandler, false);


    function clickHandler() {

        validateInput();

    }


    function keydownHandler() {

        if (event.keyCode === 13) {

            validateInput();

        }

    }


    function validateInput() {

        guessX = parseInt(inputX.value);

        guessY = parseInt(inputY.value);

        if (isNaN(guessX) || isNaN(guessY)) {

            output.innerHTML = "请输入数字坐标";

        } else if (guessX > 300 || guessY > 300) {

            output.innerHTML = "坐标不能大于300"

        } else {

            playGame();

        }

    }


    function playGame() {

        shotsRemaning--;

        shotsMade++;

        gameState = "炮弹:" + shotsMade + ",数量:" + shotsRemaning;


        guessX = parseInt(inputX.value);

        guessY = parseInt(inputY.value);

        var alienNode = binaryTree.search(guessX);

        var alienFlag = -1;

        if (alienNode) {

            nodesForAlien.forEach(function(val, index) {

                if (val === alienNode.key) {

                    alienFlag = index;

                }

            })

        }

        if (alienNode !== null && alienNodeSelect === alienFlag) {

            if (guessY >= alienY && guessY <= alienY + 20) {

                gameWon = true;

                endGame();

            }

        } else {

            output.innerHTML = "没有击中" + "<br>" + gameState;

            if (shotsRemaning < 1) {

                endGame();

            }

        }


        if (!gameWon) {

            alienNodeSelect = Math.floor(Math.random() * 9);

            alienX = nodesForAlien[alienNodeSelect];

            alienY += 30;

        }


        render();

        console.log("X" + alienX);

        console.log("Y" + alienY);

    }



    function render() {

        alien.style.left = alienX + 'px';

        alien.style.top = alienY + 'px';


        cannon.style.left = guessX + 'px';


        missile.style.left = guessX + 'px';

        missile.style.top = guessY + 'px';


        if (gameWon) {

            explosion.style.display = 'block';

            explosion.style.left = alienX + 'px';

            explosion.style.top = alienY + 'px';


            alien.style.display = "none";

            missile.style.display = "none";

        }

    }


    function endGame() {

        if (gameWon) {

            output.innerHTML = "Hit! 你拯救了地球" + "<br>" + "你发射了炮弹" + shotsMade;

        } else {

            output.innerHTML = "失败了!" + "<br>" + "地球被外星人侵略!";

        }


        button.removeEventListener("click", clickHandler, false);

        button.disabled = true;

        window.removeEventListener("keydown", keydownHandler, false);

        inputX.disabled = true;

        inputY.disabled = true;

    }

    </script>

</body>


</html>


提问者:Qzhor 2017-10-06 14:02

个回答

  • 大米小米米
    2020-09-17 19:20:27

    试一下

    <html>

    <head>

    <meta charset="UTF-8" />

    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <title>Document</title>

    <style>

    #stage {

    width: 300px;

    height: 300px;

    position: relative;

    }


    #background {

    width: 300px;

    height: 300px;

    position: absolute;

    top: 0;

    left: 0;

    background-image: url(./images/background.jpg);

    }


    #cannon {

    width: 20px;

    height: 20px;

    position: absolute;

    top: 270px;

    left: 140px;

    background-image: url(./images/cannon.jpg);

    background-size: 100%;

    }


    #alien {

    width: 20px;

    height: 20px;

    position: absolute;

    top: 20px;

    left: 80px;

    background-image: url(./images/alien.jpg);

    background-size: 100%;

    }


    #missile {

    width: 10px;

    height: 10px;

    position: absolute;

    top: 270px;

    left: 140px;

    background-image: url(./images/missllie.jpg);

    background-size: 100%;

    }


    #explosion {

    width: 20px;

    height: 20px;

    position: absolute;

    top: 0;

    left: 0;

    background-image: url(./images/explosion.jpg);

    background-size: 100%;

    display: none;

    }

    </style>

    </head>

    <body>

    <div id="stage">

    <div id="background"></div>

    <div id="cannon"></div>

    <div id="missile"></div>

    <div id="alien"></div>

    <div id="explosion"></div>

    </div>

    <p id="output">请输入X和Y坐标(0-300),然后点击fire.</p>

    <input type="text" id="inputX" placeholder="X..." />

    <input type="text" id="inputY" placeholder="Y..." />

    <button id="button">fire!</button>


    <script>

    function BinaryTree() {

    var Node = function (key) {

    this.key = key;

    this.left = null;

    this.right = null;

    this.selected = false;

    };


    root = null;


    var insertNode = function (node, newNode) {

    if (newNode.key < node.key) {

    if (node.left === null) {

    node.left = newNode;

    } else {

    insertNode(node.left, newNode);

    }

    } else {

    if (node.right === null) {

    node.right = newNode;

    } else {

    insertNode(node.right, newNode);

    }

    }

    };


    this.insert = function (key) {

    var newNode = new Node(key);

    if (root === null) {

    root = newNode;

    } else {

    insertNode(root, newNode);

    }

    };


    // 中序遍历

    var inOrderTraverseNode = function (node, callback) {

    if (node !== null) {

    inOrderTraverseNode(node.left, callback);

    callback(node);

    inOrderTraverseNode(node.right, callback);

    }

    };


    this.inOrderTraverse = function (callback) {

    inOrderTraverseNode(root, callback);

    };


    // 前序遍历

    var preOrderTraverseNode = function (node, callback) {

    if (node !== null) {

    callback(node);

    preOrderTraverseNode(node.left, callback);

    preOrderTraverseNode(node.right, callback);

    }

    };


    this.preOrderTraverse = function (callback) {

    preOrderTraverseNode(root, callback);

    };


    // 后序遍历

    var postOrderTraverseNode = function (node, callback) {

    if (node !== null) {

    postOrderTraverseNode(node.left, callback);

    postOrderTraverseNode(node.right, callback);

    callback(node);

    }

    };


    this.postOrderTraverse = function (callback) {

    postOrderTraverseNode(root, callback);

    };


    // 最小值

    var minNode = function (node) {

    if (node) {

    while (node && node.left !== null) {

    node = node.left;

    }


    return node.key;

    }

    };

    this.min = function () {

    return minNode(root);

    };


    // 最大值

    var maxNode = function (node) {

    if (node) {

    while (node && node.right !== null) {

    node = node.right;

    }


    return node.key;

    }

    };

    this.max = function () {

    return maxNode(root);

    };


    // 查找

    function searchNode(node, key) {

    if (node === null) {

    return false;

    }


    if (key < node.key) {

    return searchNode(node.left, key);

    } else if (key > node.key) {

    return searchNode(node.right, key);

    } else {

    return node;

    }

    }

    this.search = function (key) {

    return searchNode(root, key);

    };


    var findMinNode = function (node) {

    if (node) {

    while (node && node.left !== null) {

    node = node.left;

    }


    return node;

    }

    };

    // 删除节点

    function removeNode(node, key) {

    if (node === null) {

    return null;

    }

    if (key < node.key) {

    node.left = removeNode(node.left, key);

    return node;

    } else if (key > node.key) {

    node.right = removeNode(node.right, key);

    return node;

    } else {

    if (node.left === null && node.right === null) {

    node = null;

    return node;

    }

    if (node.left === null) {

    node = node.right;

    return node;

    } else if (node.right === null) {

    node = node.left;

    return;

    }


    var aux = findMinNode(node.right);

    node.key = aux.key;

    node.right = removeNode(node.right, aux.key);

    return node;

    }

    }

    this.remove = function (key) {

    return removeNode(root, key);

    };

    }


    var binaryTree = new BinaryTree();

    [31, 55, 50, 201, 116, 241, 78, 140, 144].forEach(function (key) {

    binaryTree.insert(key);

    });

    var nodesForAlien = [];

    var callback = function (node) {

    nodesForAlien.push(node);

    };


    binaryTree.preOrderTraverse(callback);

    var alienNodeSelect = Math.floor(Math.random() * 9);

    nodesForAlien[alienNodeSelect].selected = true;


    var alienX = nodesForAlien[alienNodeSelect].key;


    // var calllback = function (key) {

    //     console.log(key);

    // };


    // binaryTree.inOrderTraverse(calllback);

    // binaryTree.preOrderTraverse(calllback);

    // binaryTree.postOrderTraverse(calllback);

    // console.log('min node is: ' + binaryTree.min());

    // console.log('max node is: ' + binaryTree.max());

    // console.log(binaryTree.search(7) ? 'key 7 is found' : 'key 7 is not found');

    // console.log(binaryTree.search(9) ? 'key 9 is found' : 'key 9 is not found');


    // binaryTree.remove(10);


    // Game section

    var alienY = 20;

    var guessX = 0;

    var guessY = 0;

    var shotsRemaing = 8;

    var shotsMade = 0;

    var gameState = '';

    var gameWon = false;


    var cannon = document.querySelector('#cannon');

    var alien = document.querySelector('#alien');

    var missile = document.querySelector('#missile');

    var explosion = document.querySelector('#explosion');


    var inputX = document.querySelector('#inputX');

    var inputY = document.querySelector('#inputY');

    var output = document.querySelector('#output');


    var button = document.querySelector('#button');

    button.style.curor = 'pointer';

    button.addEventListener('click', clickHandler, false);

    window.addEventListener('keydown', keydownHandler, false);


    function clickHandler() {

    validateInput();

    }


    function keydownHandler(e) {

    if (e.keyCode == 13) {

    validateInput();

    }

    }


    function validateInput() {

    guessX = parseInt(inputX.value);

    guessY = parseInt(inputY.value);


    if (isNaN(guessX) || isNaN(guessY)) {

    output.innerHTML = '请输入坐标';

    } else if (guessX > 300 && guessY > 300) {

    output.innerHTML = '坐标不能大于300。';

    } else {

    playGame();

    }

    }


    function playGame() {

    shotsRemaing--;

    shotsMade++;

    gameState = '炮弹:' + ',数量:' + shotsRemaing;


    guessX = parseInt(inputX.value);

    guessY = parseInt(inputY.value);


    var alienNode = binaryTree.search(guessX);

    if (alienNode !== null && alienNode.selected === true) {

    if (guessY >= alienY && guessY < alienY + 20) {

    gameWon = true;

    endGame();

    }

    } else {

    output.innerHTML = '炮弹没有击中!<br>' + gameState;

    if (shotsRemaing < 1) {

    endGame();

    }

    }


    if (!gameWon) {

    nodesForAlien[alienNodeSelect].selected = false;

    alienNodeSelect = Math.floor(Math.random() * 9);

    nodesForAlien[alienNodeSelect].selected = true;

    alienX = nodesForAlien[alienNodeSelect].key;

    alienY += 30;

    }


    render();

    console.log(alienX, alienY);

    }


    function render() {

    alien.style.left = alienX + 'px';

    alien.style.top = alienY + 'px';


    cannon.style.left = guessX + 'px';


    missile.style.left = guessX + 'px';

    missile.style.top = guessY + 'px';


    if (gameWon) {

    alien.style.display = 'none';

    explosion.style.display = 'block';

    explosion.style.left = alienX + 'px';

    explosion.style.top = alienY + 'px';

    }

    }


    function endGame() {

    if (gameWon) {

    output.innerHTML = 'Hit!拯救了地球。<br>发射炮弹' + shotsMade + '枚。';

    } else {

    output.innerHTML = '你失败了!';

    }

    button.removeEventListener('click', clickHandler, false);

    button.disable = true;

    window.removeEventListener('keydown', keydownHandler, false);

    inputX.disable = true;

    inputY.disable = true;

    }

    </script>

    </body>

    </html>



  • 猴犀利的7号
    2018-11-14 22:23:38

    其实js array对象有这些方法,这(二叉树)有何优势?

  • 枫叶咚咚咚
    2018-01-18 13:03:58

    给楼主点赞。楼上慕粉的方法不可行,把callback函数内容改为nodesForAlien.push(node)时,只能成功将根结点复制进新数组的[0]号元素,后面的复制都会报错,因为老师构造的二叉树,结点之间的关系是靠node.left(或者node.righht)指向另一个node维系的,使用push并不能得到nodesForAlien的[0]号元素是一个结点,[1]号元素是另一个结点。


  • 慕粉2124514671
    2017-10-14 22:13:02

    //生成一个随机数的数组nodesArr[]

    var nodesArr = [];

    for(var i =0; i < 10 ; i++){

    nodesArr[i] = Math.floor((Math.random() * (281-20))+20);

    }

    for(var i=0;i<10;i++){

    console.log(nodesArr[i]);

    }


    var binaryTree = new BinaryTree();

    nodesArr.forEach(function (key) {

    binaryTree.insert(key);

    });

    var nodesForAlien = [];  //存放二叉树节点的数组

    var callback = function (node) {

    nodesForAlien.push(node);

    console.log(nodesForAlien);

    }

    var call = function(key){

    console.log(key);

    }

    //binaryTree.inOrderTraverse(call);

    binaryTree.preOrderTraverse(callback);  //通过前序遍历复制二叉树存入数组nodesForAlien中



    //建立第一次外星人横坐标

    var alienNodeSelect = Math.floor(Math.random() * 9);

    nodesForAlien[alienNodeSelect].selected = true;

    var alienX = nodesForAlien[alienNodeSelect].key;


  • 慕粉2124514671
    2017-10-14 22:10:59

    应该不是给每个node另外附上selected:false 属性,而是新建一个nodesForAlien数组,利用前序遍历的方法复制二叉树中的节点给nodesForAlien数组,这样二叉树中的node属性(key,selected……)在nodesForAlien数组中的元素也有。

  • Qzhor
    2017-10-06 14:04:50

    试试可以采纳我自己么O__O "…