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 MAX_STEP_LENGTH = 200;
const planets = [
{
position: [180, 140],
radius: 10,
},
{
position: [300, 300],
radius: 10,
},
];
const emitters = [
{
position: [101, 101],
angle: -80,
velocity: 40,
},
];
let bullets = [];
const calcForceVector = (bullet, lastX, lastY, planets) => {
let totalForceVector = new Vector(0, 0);
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));
totalForceVector.add(forceVector);
});
return totalForceVector;
};
const step = (frame, ctx) => {
bullets.filter((b) => b.alive).forEach((bullet) => {
const { path, vector } = bullet;
const [lastX, lastY] = path[path.length - 1];
const forceVector = calcForceVector(bullet, lastX, lastY, planets);
let newBulletVector = bullet.vector.clone().add(forceVector);
const length = newBulletVector.length();
if (length < MAX_STEP_LENGTH) {
bullet.vector = newBulletVector;
ctx.save();
ctx.beginPath();
ctx.moveTo(lastX, lastY);
ctx.lineTo(lastX + (forceVector.x * 100), lastY + (forceVector.y * 100));
ctx.strokeStyle = "rgba(0, 0, 255, 0.2)";
ctx.stroke();
ctx.restore();
path.push([lastX + bullet.vector.x, lastY + bullet.vector.y]);
} else {
newBulletVector = new Vector(0, 0);
const numSubSteps = Math.ceil(length / MAX_STEP_LENGTH);
const subStepLength = length / numSubSteps;
let subLastX = lastX;
let subLastY = lastY;
for (let i = 0; i <...