如何让我的游戏中的玩家拦截画布上掉落的物体?

时间:2016-12-07 20:55:10

标签: javascript

我正在制作一个游戏,其中玩家拦截掉落的物体,但我不知道该怎么做。我已经有了创建可以通过鼠标移动的播放器的代码,并且我随机生成了落下的对象。 这是代码:

(() => {
    let canvas = document.getElementById("game");
    let game = canvas.getContext("2d");
    let lastTimestamp = 0;
    let score = document.getElementById("playerScore");

    const FRAME_RATE = 60;
    const FRAME_DURATION = 1000 / FRAME_RATE;

    let fallers = [];

    const DEFAULT_DESCENT = 0.0003; // This is per millisecond.
    let Faller = function (x, y, width, height, dx = 0, dy = 0, ax = 0, ay = DEFAULT_DESCENT) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;

        // Velocity.
        this.dx = dx;
        this.dy = dy;

        // Acceleration.
        this.ax = ax;
        this.ay = ay;
    };

    Faller.prototype.draw = function () {
        game.fillStyle = "blue";
        game.fillRect(this.x, this.y, this.width, this.height);
    };

    Faller.prototype.move = function (millisecondsElapsed) {
        this.x += this.dx * millisecondsElapsed;
        this.y += this.dy * millisecondsElapsed;

        this.dx += this.ax * millisecondsElapsed;
        this.dy += this.ay * millisecondsElapsed;
    };

    const DEFAULT_PLAYER_WIDTH = 45;
    const DEFAULT_PLAYER_HEIGHT = 15;
    const DEFAULT_PLAYER_Y = canvas.height - DEFAULT_PLAYER_HEIGHT;
    let Player = function (x, y = DEFAULT_PLAYER_Y, width = DEFAULT_PLAYER_WIDTH, height = DEFAULT_PLAYER_HEIGHT) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    };

    Player.prototype.draw = function () {
        game.fillStyle = "darkred";
        game.beginPath();
        game.moveTo(this.x - this.width / 2, this.y + this.height);
        game.lineTo(this.x, this.y);
        game.lineTo(this.x + this.width / 2, this.y + this.height);
        game.closePath();
        game.fill();
    };

    let player = new Player(canvas.width / 2);

    let draw = (millisecondsElapsed) => {
        game.clearRect(0, 0, canvas.width, canvas.height);

        fallers.forEach((faller) => {
            faller.draw();
            faller.move(millisecondsElapsed);
        });

        player.draw();

        // Remove fallers that have hit the ground. 
        fallers = fallers.filter((faller) => {
            return faller.y < canvas.height;
        });
    };

    // It is responsible for generating falling objects at random.
    const MIN_WIDTH = 10;
    const WIDTH_RANGE = 20;
    const MIN_HEIGHT = 10;
    const HEIGHT_RANGE = 20;
    const MILLISECONDS_BETWEEN_FALLERS = 800;

    let fallerGenerator;
    let startFallerGenerator = () => {
        fallerGenerator = setInterval(() => {

            let fallerWidth = Math.floor(Math.random() * WIDTH_RANGE) + MIN_WIDTH;
            fallers.push(new Faller(
                Math.floor(Math.random() * (canvas.width - fallerWidth)), 0,
                fallerWidth, Math.floor(Math.random() * HEIGHT_RANGE) + MIN_HEIGHT
            ));
        }, MILLISECONDS_BETWEEN_FALLERS);
    };

    let stopFallerGenerator = () => clearInterval(fallerGenerator);

    // This section is responsible for moving the "player" around based on mouse movement
    let setPlayerPositionBasedOnMouse = (event) => {
        player.x = event.clientX / document.body.clientWidth * canvas.width;
    };

    document.body.addEventListener("mouseenter", setPlayerPositionBasedOnMouse);
    document.body.addEventListener("mousemove", setPlayerPositionBasedOnMouse);

    let running = false;
    let nextFrame = (timestamp) => {
        if (!lastTimestamp) {
            lastTimestamp = timestamp;
        }

        if (timestamp - lastTimestamp < FRAME_DURATION) {
            if (running) {
                window.requestAnimationFrame(nextFrame);
            }

            return;
        }

        draw(timestamp - lastTimestamp);

        lastTimestamp = timestamp;
        if (running) {
            window.requestAnimationFrame(nextFrame);
        }
    };

    document.getElementById("start-button").addEventListener("click", () => {
        running = true;
        lastTimestamp = 0;
        startFallerGenerator();
        window.requestAnimationFrame(nextFrame);
    });

    document.getElementById("stop-button").addEventListener("click", () => {
        stopFallerGenerator();
        running = false;
    });
})();
canvas {
    border: solid 1px gray;
    display: block;
    margin-left: auto;
    margin-right: auto;
    width: 1024px;
}

p {
    text-align: center;
}
<!doctype html>

<html>
  <head>
    <meta charset="utf-8" />
    <title>Undefined</title>

    <link rel="stylesheet" href="falling.css">
  </head>
  <body>
    <h1>Not finished</h1>
    <p>
      <b>Score:</b> <span id="playerScore">0</span>
    <canvas id="game" width="1024" height="536">
      Sorry, but you need a web browser that supports the
      <code>canvas</code> element.
    </canvas>

    <p>
      <button id="start-button">Start</button>
      <button id="stop-button">Stop</button>
    </p>

    <script src="falling.js"></script>
  </body>
</html>

1 个答案:

答案 0 :(得分:0)

isCollision = false
fallers.forEach((faller) => {
     isCollision = isCollision || checkCollision(faller,player) 
    });
if (isCollision) {
    //decide what you want to do here
    //maybe you want to display the gameOver screen and return
    //before drawing the fallers.
}
fallers.forEach((faller) => {
        faller.draw();
        faller.move(millisecondsElapsed);
    });

checkCollision()中确定您的碰撞需要准确的程度。可能absolute(player.x - faller.x) < delta对您来说足够准确。如果摔跤手或球员有宽度,你需要检查球员x间隔是否与球员x间隔重叠。还要确保你也检查高度。