Edit
Here is a JSFiddle with the code for the “tail” function commenting out.Solar System JSFiddle
I have this object I am working on that has an object orbiting a center mass. That works perfectly.
I am now trying to add a trailing line or “tail” that follows behind the planet. My tail object looks like this:
function Tail(maxLength){ this.points = []; this.maxLength = maxLength; this.addPoint = function(point){ for(var i = Math.min(maxLength, this.points.length); i < maxLength; i++){ this.points[i] = this.points[i - 1]; } this.points[0] = point; } this.draw = function(ctx){ for(var i = 1; Math.min(maxLength, this.points.length); i++){ if(i < maxLength - 20){ ctx.globalAlpha = 1; } else { ctx.globalAlpha = (this.maxLength - i) / 20; } ctx.beginPath(); ctx.moveTo(this.points[i - 1].x, this.points[i - 1].y); ctx.lineTo(this.points[i].x, this.points[i].y); ctx.stroke(); } ctx.globalAlpha = 1; } }
The addPoint function takes an object that looks like ‘{x: currentX, y: currentY} currentX and currentY are the x and y point of the object when ever it gets called.
I am lost on how I need to add the point to the points array and then draw based on those coordinates.
Advertisement
Answer
I modified your version to working condition
var canvas, width, height, ctx; var bodies = []; function init(){ canvas = document.getElementById("space-time"); width = window.innerWidth; height = window.innerHeight; canvas.width = width; canvas.height = height; ctx = canvas.getContext('2d'); createBodies(); setInterval(function(){ updateSystem(); updateBodies(0.01); ctx.clearRect(0, 0, width, height); drawBodies(); }, 10); } function createBodies(){ bodies.push(new Body((this.width / 2) - 250, (this.height / 2) - 300, 200, 0, 1, 10, "#14c71d", true)); bodies.push(new Body((this.width / 2) + 100, (this.height / 2) + 100, 350, 0, 1, 5, "#de2d16", true)); bodies.push(new Body(this.width / 2, this.height / 2, 0, 0, 1000000, 30, "#FF8501", false)); //sun } function drawBodies(){ for(var i = 0; i < bodies.length; i++){ bodies[i].draw(ctx); } } function updateBodies(dt){ for(var i = 0; i < bodies.length; i++){ bodies[i].update(dt); } } function updateSystem(){ var G = 10; for(var i = 0; i < bodies.length; i++){ for(var j = 0; j < bodies.length; j++){ if(i === j) continue; var b1 = bodies[i]; var b2 = bodies[j]; var dist = Math.sqrt((b1.x - b2.x) * (b1.x - b2.x) + (b1.y - b2.y) * (b1.y - b2.y)); var force = G * (b1.m * b2.m) / dist / dist; var nx = (b2.x - b1.x) / dist; var ny = (b2.y - b1.y) / dist; b1.ax += nx * force / b1.m; b1.ay += ny * force / b1.m; b2.ax -= nx * force / b2.m; b2.ay -= ny * force / b2.m; } } } function Body(x, y, v, angle, mass, radius, color, hasTail){ this.x = x; this.y = y; this.vx = v * Math.cos(angle); this.vy = v * Math.sin(angle); this.m = mass; this.radius = radius; this.color = color; this.ax = 0; this.ay = 0; if (hasTail) { this.tail = new Tail(50); } this.update = function(dt){ this.vx += this.ax * dt; this.vy += this.ay * dt; this.x += this.vx * dt; this.y += this.vy * dt; this.ax = 0; this.ay = 0; if(this.tail){ this.tail.addPoint({x: this.x, y: this.y}); } } this.draw = function(ctx){ ctx.strokeStyle = this.color; ctx.fillStyle = this.color; ctx.shadowColor = this.color; ctx.shadowBlur = 5; if(this.tail){ this.tail.draw(ctx); } ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, 6.28); ctx.fill(); } } function Tail(maxLength){ this.points = []; this.maxLength = maxLength; this.addPoint = point => { this.points = [point].concat(this.points).slice(0, this.maxLength); } this.draw = function(ctx){ for(var i = 1; i < this.points.length; i++){ ctx.beginPath(); if(i < maxLength - 20){ ctx.globalAlpha = 1; } else { ctx.globalAlpha = (this.maxLength - i) / 20; } ctx.moveTo(this.points[i - 1].x, this.points[i - 1].y); ctx.lineTo(this.points[i].x, this.points[i].y); ctx.stroke(); } ctx.globalAlpha = 1; } }
#space-time { background-color: #1a1a1c; }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Solar System AJ</title> </head> <body onload="init();"> <canvas id="space-time"></canvas> </body> </html>