在 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>
答案 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());
}
}