为什么这不画轨道而只画椭圆呢?

时间:2020-02-15 22:35:58

标签: javascript p5.js

Daniel Shiffman 的视频的启发下,我开始使用 p5.js 创建一个非常粗略的太阳系模拟。

我试图通过保存行星在阵列中的位置来绘制每个行星的轨道,然后使用for循环遍历它们,并在每个保存的位置绘制一个圆。

除非它不起作用!

它应该起作用,因为要确保这是我搜索并获得 Daniel Shiffman 的另一个视频的最佳方法,显然它对他有用,但不幸的是,它不适合我!

有人可以告诉我我在做什么问题。 (对不起,我英语不好)

下面是代码段!

class Planet
{
    constructor(orbitCenter, color, mass, velocityLimit)
    {
        this.orbitCenter = orbitCenter;
        this.color = color;
        this.mass = mass;
        this.velocityLimit = velocityLimit;

        this.position = createVector(width/2, 50);
        this.radius = 15;
        this.velocity = createVector(30, 10);
        this.acceleration = createVector(0.0, 0.0);
        this.pathPoints = [];
    }

    render() 
    {
        const diameter = this.radius * 2;
        ellipseMode(CENTER);
        noStroke();
        fill(this.color);
        ellipse(this.position.x, this.position.y, diameter);

        if(this.pathPoints.length > 1000) 
        {
            this.pathPoints.splice(0, 1);
        }

        for(let i = 0; i < this.pathPoints.length; i++)
        {
            let pos = this.pathPoints[i];
            fill(255);
            ellipse(pos.x, pos.y, 5, 5);
        }
    }

    update() 
    {     
        this.position.add(this.velocity);
        this.velocity.add(this.acceleration);
        this.acceleration = createVector(this.orbitCenter.x, this.orbitCenter.y)
            .sub(this.position)
            .mult(this.mass);
        this.velocity.limit(this.velocityLimit);
        this.pathPoints.push(this.position);
    }
}

class Star
{
    constructor(color, position, diameter) 
    {
        this.color = color;
        this.position = position;
        this.diameter = diameter;
    }

    render()
    {
        fill(this.color);
        noStroke();
        ellipse(this.position.x, this.position.y, this.diameter);
    }
}

let sun;
let earth, mars;
let sunDiameter = 40;

function setup()
{
    createCanvas(windowWidth, windowHeight);
    frameRate(60);

    let sunPos = createVector(width/2, height/2);
    sun = new Star(color(255, 255, 0), sunPos, sunDiameter);

    earth = new Planet(sunPos, color(0, 100, 255), 0.0008, 4.5);
    mars = new Planet(sunPos, color(255, 100, 0), 0.0004, 5);
}

let toggleOrbit = true;
function draw()
{
    background(0);
    sun.render();

    earth.render();
    mars.render();

    if(toggleOrbit)
    {
        earth.update();
        mars.update();
    }
    
}

function windowResized()
{
    resizeCanvas(windowWidth, windowHeight);
    setup();
}

function keyPressed(e)
{
    if(e.key == ' ')
    {
        toggleOrbit = !toggleOrbit;
    }
    
    if(e.key == 'c')
    {
        console.log(earth.getPathPoints());
    }
}
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Gravity Simulation</title>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/addons/p5.dom.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/addons/p5.sound.min.js"></script>

        <style>
            *
            {
                margin: 0;
                padding: 0;
                box-sizing: border-box;
            }

            body
            {
                width: 100vw;
                height: 100vh;
                display: flex;
                align-items: center;
                justify-content: center;
            }
        </style>
    </head>
    <body>
        <script src="main.js"></script>
    </body>
</html>

1 个答案:

答案 0 :(得分:3)

编写this.pathPoints.push(this.position)时,最终会存储对对象this.position的引用,而不是其X和Y值,因此在绘制轨道时,它会使用{的当前值每次{1}}。相反,如果存储X和Y值,则会得到所需的结果;替换

this.position

this.pathPoints.push(this.position);

,您将看到正在绘制的轨道。

this.pathPoints.push({
    x: this.position.x,
    y: this.position.y
})
class Planet
{
    constructor(orbitCenter, color, mass, velocityLimit)
    {
        this.orbitCenter = orbitCenter;
        this.color = color;
        this.mass = mass;
        this.velocityLimit = velocityLimit;

        this.position = createVector(width/2, 50);
        this.radius = 15;
        this.velocity = createVector(30, 10);
        this.acceleration = createVector(0.0, 0.0);
        this.pathPoints = [];
    }

    render() 
    {
        const diameter = this.radius * 2;
        ellipseMode(CENTER);
        noStroke();
        fill(this.color);
        ellipse(this.position.x, this.position.y, diameter);

        if(this.pathPoints.length > 1000) 
        {
            this.pathPoints.splice(0, 1);
        }

        for(let i = 0; i < this.pathPoints.length; i++)
        {
            let pos = this.pathPoints[i];
            fill(255);
            ellipse(pos.x, pos.y, 5, 5);
        }
    }

    update() 
    {     
        this.position.add(this.velocity);
        this.velocity.add(this.acceleration);
        this.acceleration = createVector(this.orbitCenter.x, this.orbitCenter.y)
            .sub(this.position)
            .mult(this.mass);
        this.velocity.limit(this.velocityLimit);
        this.pathPoints.push({
            x: this.position.x,
            y: this.position.y
        })
    }
}

class Star
{
    constructor(color, position, diameter) 
    {
        this.color = color;
        this.position = position;
        this.diameter = diameter;
    }

    render()
    {
        fill(this.color);
        noStroke();
        ellipse(this.position.x, this.position.y, this.diameter);
    }
}

let sun;
let earth, mars;
let sunDiameter = 40;

function setup()
{
    createCanvas(windowWidth, windowHeight);
    frameRate(60);

    let sunPos = createVector(width/2, height/2);
    sun = new Star(color(255, 255, 0), sunPos, sunDiameter);

    earth = new Planet(sunPos, color(0, 100, 255), 0.0008, 4.5);
    mars = new Planet(sunPos, color(255, 100, 0), 0.0004, 5);
}

let toggleOrbit = true;
function draw()
{
    background(0);
    sun.render();

    earth.render();
    mars.render();

    if(toggleOrbit)
    {
        earth.update();
        mars.update();
    }
    
}

function windowResized()
{
    resizeCanvas(windowWidth, windowHeight);
    setup();
}

function keyPressed(e)
{
    if(e.key == ' ')
    {
        toggleOrbit = !toggleOrbit;
    }
    
    if(e.key == 'c')
    {
        console.log(earth.getPathPoints());
    }
}

相关问题