我的
#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>
有几种优化方法,例如更改为 requestAnimationFrame、降低更清晰位置的速度、提高 fps...