JSFiddle - React, Tailwind, and code Playground
by moritzkobrna
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.5/dat.gui.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/victor/1.1.0/victor.js"></script>
<canvas id="canvas" width="800" height="800"></canvas>
<button onClick={window.doStep()}>Step</button>
JavaScript 1.7
const Vector = Victor;
const gui = new dat.GUI();
const canvas = document.querySelector('#canvas');
const ctx = canvas.getContext('2d');
const planets = [
{
position: [180, 140],
radius: 10,
},
{
position: [300, 300],
radius: 10,
},
];
const emitters = [
{
position: [101, 101],
angle: -90,
velocity: 4,
},
];
let bullets = [];
const step = (frame, ctx) => {
bullets.filter((b) => b.alive).forEach((bullet) => {
const { path, vector } = bullet;
const [lastX, lastY] = path[path.length - 1];
planets.forEach(({ position: [x, y], radius }) => {
const dist = (new Vector(lastX, lastY).distance(new Vector(x, y)));
const force = (1 / Math.pow(dist, 2)) * radius * 100;
if (dist <= radius) return bullet.alive = false;
const forceDirection = new Vector(x, y).subtract(new Vector(lastX, lastY)).normalize();
const forceVector = forceDirection.multiply(new Vector(force, force));
bullet.vector = bullet.vector.add(forceVector);
});
path.push([lastX + bullet.vector.x, lastY + bullet.vector.y]);
});
};
const draw = (ctx) => {
// Clear
ctx.clearRect(0, 0, 800, 800);
// Draw planets
planets.forEach(({ position: [x, y], radius }) => {
ctx.fillStyle = 'red';
ctx.beginPath();
ctx.arc(x, y, radius, 0, 2 * Math.PI);
ctx.fill();
});
// Draw bullets
bullets.forEach(({ path, vector }) => {
ctx.beginPath();
const [firstX, firstY] = path.slice().shift();
ctx.moveTo(path[0][0], path[0][1]);
for (let i = 1; i < path.length - 2; ++i) {
const dx = (path[i][0] + path[i + 1][0]) / 2
const dy = (path[i][1] + path[i + 1][1]) / 2
ctx.quadraticCurveTo(path[i][0], path[i][1], dx, dy)
}
ctx.quadraticCurveTo(path[path.length - 2][0], path[path.length - 2][1], path[path.length - 1][0], path[path.length - 1][1]);
ctx.stroke();
});
};
const simulate = () => {
...