JavaScript画布球弹跳算法与绘图函数优化

问题描述 投票:0回答:1

我的

#work
方法一旦遇到墙壁就达到了目的。然而,这些点也应该相互反弹。我必须如何调整该方法才能使其按预期工作?

我也想优化游戏。对我来说最重要的是积分运行得更顺畅。由于

gridSize
游戏“滞后”。我这里还需要调整什么?

let canvas = document.querySelector("canvas"),
    context = canvas.getContext("2d"),
    settings = {
        height: canvas.height = 400,
        width: canvas.width = 400,
        duration: 50,
        gridSize: 20,
        dotCount: 10,
        possibleDirections: [-1, 1],
        colors: {
            background: "#ccc"
        }
    };

class Dot {
    constructor() {
        this.position = new Position;
        this.direction = new Direction;
        this.color = this.#getRandomColor();
    }

    #getRandomColor() {
        let r = this.#getRandomHex(),
            g = this.#getRandomHex(),
            b = this.#getRandomHex();
        return `#${r}${g}${b}`;   
    }

    #getRandomHex = _ => Math.floor(Math.random() * 255).toString(16);
}

class Position {
    constructor(x, y) {
        this.x = x || this.#getRandomPositionX();
        this.y = y || this.#getRandomPositionY();
    }

    #getRandomPositionX = _ => Math.round(Math.floor(Math.random() * (settings.width / settings.gridSize)) * settings.gridSize);
    #getRandomPositionY = _ => Math.round(Math.floor(Math.random() * (settings.height / settings.gridSize)) * settings.gridSize);
}

class Direction {
    constructor(x, y) {
        this.x = x || this.#getDirection();
        this.y = y || this.#getDirection();
    }

    #getDirection = _ => settings.possibleDirections[Math.floor(Math.random() * settings.possibleDirections.length)];
}

class Game {
    constructor() {
        this.#generateDots();
        setInterval(() => {
            this.#clear();
            this.#work();
            this.#draw();
        }, settings.duration);
    }

    #clear() {
        context.fillStyle = settings.colors.background;
        context.fillRect(0, 0, settings.height, settings.width);
    }

    #work() {
        for (let dot of this.dots) {
            if (dot.position.x + dot.direction.x >= settings.width - settings.gridSize) dot.direction.x = -1;
            else if (dot.position.x - dot.direction.x < 0) dot.direction.x = 1;

            if (dot.position.y + dot.direction.y >= settings.width - settings.gridSize) dot.direction.y = -1
            else if (dot.position.y - dot.direction.y < 0) dot.direction.y = 1;

            // START: HELP
            let els = this.dots.filter(cur => (dot.position.x + dot.direction.x === cur.position.x + cur.direction.x && 
                                              dot.position.y + dot.direction.y === cur.position.y + cur.direction.y) ||
                                              dot.position.x === cur.position.x && dot.position.y === cur.position.y);
            if (els.length > 0) {
                if (dot.direction.x === 1) dot.direction.x = -1;
                else if (dot.direction.x === -1) dot.direction.x = 1;

                if (dot.direction.y === 1) dot.direction.y = -1;
                else if (dot.direction.y === -1) dot.direction.y = 1;

                let cur = els[0];
                if (cur.direction.x === 1) cur.direction.x = -1;
                else if (cur.direction.x === -1) cur.direction.x = 1;

                if (cur.direction.y === 1) cur.direction.y = -1;
                else if (cur.direction.y === -1) cur.direction.y = 1; 

                cur.position.x += (cur.direction.x * settings.gridSize);
                cur.position.y += (cur.direction.y * settings.gridSize );
            }
            // END: HELP

            dot.position.x += (dot.direction.x * settings.gridSize);
            dot.position.y += (dot.direction.y * settings.gridSize);
        }
    }

    #draw() {
        let halfGridSize = settings.gridSize / 2;
        for (let dot of this.dots) {
            context.fillStyle = dot.color;
            context.beginPath();
            context.arc(dot.position.x + halfGridSize, dot.position.y + halfGridSize, halfGridSize, 0, 2 * Math.PI);
            context.fill();
        }
    }

    #generateDots()  {
        this.dots = [];
        for (let i = 0; i < settings.dotCount; i++) {
            let newDot = new Dot;
            if (this.dots.filter(dot => dot.position.x === newDot.position.x && dot.position.y === newDot.position.y).length === 0) this.dots.push(newDot);
        }
    }
}

new Game;
* { 
  margin: 0; 
  padding: 0; 
}

body { 
  display: flex; 
  justify-content: center; 
  align-items: center; 
  height: 100vh; 
}
    <html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
    <canvas></canvas>
</body>
</html>

javascript algorithm canvas
1个回答
0
投票

有几种优化方法,例如更改为 requestAnimationFrame、降低更清晰位置的速度、提高 fps...

© www.soinside.com 2019 - 2024. All rights reserved.