为正在运行的物体创建一个“尾巴”

问题描述

修改

这是一个JSFiddle,其中注释了“ tail”函数的代码。Solar System JSFiddle

我有一个正在处理的物体,其中一个物体绕着中心质量运行。那很好。

small red planet orbiting sun

我现在正在尝试在该行星后面添加一条拖尾线或“尾巴”。 我的尾巴对象看起来像这样:

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;
  }
}

addPoint函数采用一个看起来像'{x:currentX,y:currentY}的对象 当调用对象时,currentX和currentY是对象的x和y点。

我不知道如何将点添加到点数组,然后根据这些坐标进行绘制。

解决方法

如果您用低不透明度的背景填充框架而不是清除它,则可以可视化对象的轨迹:

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,height);

        // All magic here:
        ctx.fillStyle = `rgba(0,.05)`;
        ctx.shadowBlur = 0;
        ctx.fillRect(0,canvas.width,canvas.height);

        drawBodies();
    },10);
}

function createBodies(){
    bodies.push(new Body((this.width / 2) - 250,(this.height / 2) - 300,200,1,10,"#14c71d",true));
    bodies.push(new Body((this.width / 2) + 100,(this.height / 2) + 100,350,5,"#de2d16",true));
    bodies.push(new Body(this.width / 2,this.height / 2,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;

    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;
    }

    this.draw = function(ctx){
        ctx.beginPath();
        ctx.arc(this.x,this.y,this.radius,6.28);
        ctx.strokeStyle = this.color;
        ctx.fillStyle = this.color;
        ctx.shadowColor = this.color;
        ctx.shadowBlur = 5;
        ctx.fill();
    }
}
#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>

,

我已将您的版本修改为工作状态

var canvas,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,height);
        drawBodies();
    },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,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>

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...