这段代码有什么问题?我是以正确的方式来做这件事的吗?

时间:2014-03-21 14:45:03

标签: javascript svg raphael

好的,所以我对编程很新。我已经学习了很长一段时间的代码,但我还没有真正做过任何事情。考虑到这一点,我试图使用JavaScript制作我的第一个项目并进行蛇形游戏。不幸的是,我遇到了多个问题,这显然是与编程同时出现的问题,但我很新,而且我被卡住了。有人可以帮我弄清楚我是否能以有效的方式编码。另外,我有一个更具体的问题。我已经在我的蛇头上添加了基本的动作功能,但是我无法弄清楚如何让其余部分跟随。如果有人能向我解释如何做到这一点,那将是不可思议的。我现在已经工作了大约两个星期,试图弄清楚它,我只是难倒了。我使用Raphael的JavaScript库在SVG画布上生成图形。

/*

Libraries in use:

1.  Rapheal
2.  jQuery

*/

// This variable is set to an array so that we can add multiple snakeParts to our PrimarySnake.
var snakeParts = [],
// This variable uses Raphael to generate a canvas.
    snakeCanvas = Raphael(10, 10, 400, 400),
// This generates a rectangle that fills the canvas.
    snakeCanvasBg = snakeCanvas.rect(0,0,400,400),
// This variable is set to an array so that we can use each and every direction that is pressed.
    direction = [],
// This variable is set to an array so that we can use the turn coordinates of our first snake part.
    turnCoords = [];

// Generates and returns a random number between 0 and 400. This function is used to help generate the goal of our snake at a random location on the canvas.
function getRandNum () {
    var rand = Math.round(Math.random()*400);
    // This while loop ensures that our snakeGoal never exceeds the coordinates x = 390 or y = 390. If it did, it's parts would be cut from the canvas.
    while (rand > 395) {
        rand = Math.round(Math.random()*400);
    }
    // This while loop ensures that our rand variabe will always be divisible by 10, which is used to make sure our snakeGoal and snakePart elements are always rendered in coordinates divisible by 10.
    while (rand % 10 !== 0) {
        var randString = rand.toString(),
            // This variable stores the whole length of our randString variable.
            randStringLength = randString.length,
            // This variable stores the last number of our rand as a string character.
            subtractionChar = randString.charAt(randStringLength - 1),
            // This variable stores the last number of our rand as a integer.
            subtractionInt = parseInt(subtractionChar),
            // Finally, this line subtracts the last number of our rand from the entirety and then sets that value equal to rand, ensuring that rand is always divisible by 10.
            rand = rand - subtractionInt;
    }
    return rand;
}

// This function is called any time a button is pressed. The jQuery which method allows our code to compare if the key pressed is equal to the keyCode of a designated key.
$(document).keydown(
    function (pressedDirection) {
        if (pressedDirection.which === 37) {
            direction.push("left");
        } else if (pressedDirection.which === 38) {
            direction.push("up");
        } else if (pressedDirection.which === 39) {
            direction.push("right");
        } else if (pressedDirection.which === 40) {
            direction.push("down");
        } else if (pressedDirection.which === 32) {
            direction.push("stop");
        }

        if (pressedDirection.which === 37 || pressedDirection.which === 38 || pressedDirection.which === 39 || pressedDirection.which === 40 || pressedDirection.which === 32) {
            console.log(direction[direction.length - 1]);
            PrimarySnake.addTurnCoords();
            PrimarySnake.movePeice();
        }

        // This prevents our screen from scrolling when an arrow key is
        pressedDirection.preventDefault();
    }
);

function Snake () {
    // This method generates a new peice to the Snake.
    this.addPart = function () {
        console.log(snakeParts.length);
        snakeParts[snakeParts.length] = snakeCanvas.rect(0,0,10,10);
        snakeParts[snakeParts.length - 1].attr("fill", "blue");
        snakeParts[snakeParts.length - 1].attr("stroke-width", ".25");
    }

    // This method provides the movement functionality of our Snake.
    this.moveDirection = function () {
        for (value in snakeParts) {
            var currentCoord = [snakeParts[value].attr("x"), snakeParts[value].attr("y")];
            // This if-else statement moves the snakePart at the -value- index up, down, left, or right according to the last direction pressed.
            if (direction[direction.length - 1] === "up") {
                snakeParts[value].attr("y", currentCoord[1] - 10);
            } else if (direction[direction.length - 1] === "down") {
                snakeParts[value].attr("y", currentCoord[1] + 10);
            } else if (direction[direction.length - 1] === "left") {
                snakeParts[value].attr("x", currentCoord[0] - 10);
            } else if (direction[direction.length - 1] === "right") {
                snakeParts[value].attr("x", currentCoord[0] + 10);
            }
        }
    }

    this.moveInterval;

    // This function makes our moveDirection move our snakePeice every 50 milliseconds.
    this.movePeice = function () {
        var moveDirection = this.moveDirection;
        // clearInterval is used to eliminate any interval previously running, ensuring that our peices only move one direction at a time.
        clearInterval(this.moveInterval);
        this.moveInterval = setInterval(function(){moveDirection()}, 50);
    }

    // This function adds an array of coordinates to the turnCoords array.
    this.addTurnCoords = function () {
        turnCoords.push([snakeParts[0].attr("x"), snakeParts[0].attr("y")]);
    }
}

// This generates a new instance of our Snake class.
var PrimarySnake = new Snake();
// This generates a new part on the canvas.
PrimarySnake.addPart();
// This fills our snakeCanvasBg with a grey color, giving us a grey background.
snakeCanvasBg.attr("fill", "#CDCDCD");

1 个答案:

答案 0 :(得分:1)

嗯,你的代码看起来不错,或者至少是“高效”,因为你正在调用它。

为了让你的蛇的部分跟随它的头部,你必须遍历它的部分并为每个(n + 1)分配来自(n)的坐标。为此,从最后一个部分开始并迭代到第一个部分,该移动由用户定义,如:

this.moveDirection = function () {
    // Move every piece except the head.
    for (var i = snakeParts.length - 1; i > 0; i--) {
        snakeParts[i].attr("x", snakeParts[i-1].attr("x"));
        snakeParts[i].attr("y", snakeParts[i-1].attr("y"));
    }

    // Now move the head.
    if (direction[direction.length - 1] === "up") {
        snakeParts[value].attr("y", currentCoord[1] - 10);
    } else if (direction[direction.length - 1] === "down") {
        snakeParts[value].attr("y", currentCoord[1] + 10);
    } else if (direction[direction.length - 1] === "left") {
        snakeParts[value].attr("x", currentCoord[0] - 10);
    } else if (direction[direction.length - 1] === "right") {
        snakeParts[value].attr("x", currentCoord[0] + 10);
    }           
}

该代码可能需要一些工作,但这就是想法。希望它有所帮助!