JSFiddle - React, Tailwind, and code Playground
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas Application</title>
<style>
/* Ensuring the canvas fills the entire window */
body, html {
margin: 0;
padding: 0;
overflow: hidden;
}
canvas {
display: block;
background-color: #f0f0f0;
}
</style>
</head>
<body>
<canvas id="render_canvas"></canvas>
<script src="index.js"></script>
</body>
</html>
JavaScript
const canvas = document.getElementById('render_canvas');
const ctx = canvas.getContext('2d');
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
resizeCanvas();
window.addEventListener('resize', resizeCanvas);
class Broadphase {
constructor(grid_size, cell_size) {
this.grid_size = grid_size;
this.cell_size = cell_size;
this.max_cell = [
Math.floor(grid_size[0] / cell_size[0]),
Math.floor(grid_size[1] / cell_size[1]),
];
// use hash map with string key instead
this.cells = Array.from({ length: this.max_cell[0] + 1 }, () =>
Array.from({ length: this.max_cell[1] + 1 }, () => new Set()),
);
// keep track of bodies that were moved
this.move_set = new Set();
}
insert(body) {
const [top_index, bottom_index] = this.toIndices(body.pos, [body.radius, body.radius]);
body.broadphase = [top_index, bottom_index];
// insert body into all cells from top_index to bottom_index
for (let i = top_index[0]; i <= bottom_index[0]; ++i) {
for (let j = top_index[1]; j <= bottom_index[1]; ++j) {
if (this.cells[i][j]) {
this.cells[i][j].add(body);
} else {
this.cells[i][j] = new Set([body]);
}
}
}
this.move_set.add(body);
}
remove(body) {
if (body.broadphase.length) {
const top_index = body.broadphase[0];
const bottom_index = body.broadphase[1];
// remove body from top_index to bottom_index
for (let i = top_index[0]; i <= bottom_index[0]; ++i) {
for (let j = top_index[1]; j <= bottom_index[1]; ++j) {
this.cells[i][j].delete(body);
}
}
body.broadphase = [];
}
}
update(body) {
this.remove(body);
this.insert(body);
}
// generate a set of possibly colliding bodies
computePairs() {
const pairs = new Set();
const bodies = Array.from(this.move_set);
for (let a = 0; a < bodies.length; a++) {
...