我大约一周前就开始学习JavaScript了,我想要一些关于我的代码的意见和建议。这个程序只是创建了一个画布,实例化了围绕太阳运行的5个行星,每个行星都有不同的速度、颜色和大小。
它使用p5.js库,代码可以在p5.js网络编辑器中运行。(在运行脚本之前,您可能希望在粘贴代码之后展开右侧的预览面板。)
代码位于不同的文件中(类Orbiter
、额外的数学函数和主代码),但我将把它放在这里一次:
// Converts from degrees to radians.
Math.radians = function(degrees) {
return degrees * Math.PI / 180;
};
// Converts from radians to degrees.
Math.degrees = function(radians) {
return radians * 180 / Math.PI;
};
class Orbiter {
constructor(rad, orbitAlt, x = 0, y = 0, orbitAngle = 0, orbitAngleMod = 1, colorR=255, colorG=255, colorB=255, colorA=255){
this.orbitAngle = orbitAngle; // Angle formed by the radius of the orbit and the x plane.
this.orbitAngleMod = orbitAngleMod; // Increment/decrement of orbitAngle
this.rad = rad; // Radius
this.orbitAlt = orbitAlt; // Distance to the orbited object's position (Alt for altitude)
// Position
this.x = x;
this.y = y;
// Color variables
this.colorR = colorR;
this.colorG = colorG;
this.colorB = colorB;
this.colorA = colorA;
}
orbit(object){
this.x = object.x + this.orbitAlt * cos(Math.radians(this.orbitAngle));
this.y = object.y + this.orbitAlt * sin(Math.radians(this.orbitAngle));
this.orbitAngle = this.orbitAngle + this.orbitAngleMod;
// Reset the angle to 0 after a complete revolution to avoid an ever increasing value.
if(this.orbitAngle >= 360){
this.orbitAngle = 0;
}
}
display(){
noStroke();
fill(this.colorR, this.colorG, this.colorB, this.colorA);
return ellipse(this.x, this.y, this.rad, this.rad);
}
}
let planets = [];
let sun = new Orbiter(100, 0);
function setup(){
createCanvas(windowWidth-3, windowHeight-3);
frameRate(144);
// Set up the Sun's colors and coordinates
sun.colorR = 255;
sun.colorG = 200;
sun.colorB = 0;
sun.x = windowWidth/2;
sun.y = windowHeight/2;
// Instantiate 5 planets
for(i = 0; i < 5; i++){
planets[i] = new Orbiter(5 + i * 15, 110 + i*70);
planets[i].orbitAngleMod= 1.4 - i/7;
planets[i].orbitAngle= i*5;
planets[i].colorR = i * 50 + 5;
planets[i].colorG = 255 - planets[i].colorR;
planets[i].colorB = 255 - planets[i].colorR;
}
}
function draw(){
background(0, 10, 40);
for(planet of planets){
planet.orbit(sun);
planet.display();
sun.display()
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.js"></script>
如果您能给我一些关于我的代码结构的反馈,无论它是否符合JavaScript最佳实践,或者如果您在代码中看到任何您认为是错误的或者应该以不同的方式编写的话,我将非常感激。
发布于 2019-02-22 22:03:35
Math
是标准JavaScript库的一部分。您不应该用自己的代码来污染它的命名空间,因为它可能会干扰页面上的其他JavaScript代码。在本例中,Math.degrees()
从未被使用过,您可以只使用p5.js的radians()
函数而不是编写Math.radians()
。
Orbiter
的构造函数非常笨重,最多有10个参数。你可以把他们中的大部分消灭掉。此外,您应该将颜色指定为单个p5.Color对象,而不是指定四个单独的参数。
应该有一个windowResized()
处理程序,以便可以优雅地调整窗口(或堆栈片段)的大小。
卫星绕其轨道被称为主要的的物体。我建议您将参数命名为orbit()
方法。
你的行星的角速度是由planets[i].orbitAngleMod= 1.4 - i/7
给出的,这不符合物理定律。根据开普勒第三定律,T^2 \propto r^3 (其中T和r是轨道周期和半径),所以\omega \propto r^{-\frac{3}{2}}。因此,你们的内行星并不像他们应该的那样快,你们的外部行星也没有像他们应该的那样慢。
用if(this.orbitAngle >= 360){ this.orbitAngle = 0; }
处理革命的完成可能会导致一些小故障.模块操作将更合适。
我看不出初始化行星初始角到i * 5
的意义--相对于x轴,最多4°的偏移量几乎是不可见的。
class Orbiter {
constructor(sizeRadius, orbitRadius, orbitAngle=0) {
this.sizeRadius = sizeRadius;
this.orbitRadius = orbitRadius;
this.orbitAngle = 0; // degrees relative to x axis
// 2000 is an arbitrary animation speed (which also depends on the frame rate)
// The -1.5 exponent is due to Kepler's 3rd Law
this.orbitAngleDelta = 2000 * Math.pow(orbitRadius, -1.5);
this.x = this.y = 0;
this.color = 'white';
}
orbit(primary) {
this.x = primary.x + this.orbitRadius * cos(radians(this.orbitAngle));
this.y = primary.y + this.orbitRadius * sin(radians(this.orbitAngle));
this.orbitAngle = (this.orbitAngle + this.orbitAngleDelta) % 360;
}
display() {
noStroke();
fill(this.color);
return ellipse(this.x, this.y, this.sizeRadius, this.sizeRadius);
}
}
let planets = [];
let sun = new Orbiter(100, 0);
function setup() {
createCanvas(windowWidth - 3, windowHeight - 3);
frameRate(144);
sun.x = windowWidth / 2;
sun.y = windowHeight / 2;
sun.color = color(255, 200, 0);
// Instantiate 5 planets
for (i = 0; i < 5; i++) {
planets[i] = new Orbiter(5 + 15 * i, 110 + 70 * i);
let red = i * 50 + 5;
planets[i].color = color(red, 255 - red, 255 - red);
}
}
function windowResized() {
resizeCanvas(windowWidth - 3, windowHeight - 3);
sun.x = windowWidth / 2;
sun.y = windowHeight / 2;
}
function draw() {
background(0, 10, 40);
sun.display()
for (planet of planets) {
planet.orbit(sun);
planet.display();
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.js"></script>
发布于 2019-01-23 02:54:24
对我来说很好。但我不是JS专家。;)
有一件事“跳”了我:
if(this.orbitAngle >= 360){
this.orbitAngle = 0;
}
相反,我会做:
while (this.orbitAngle>360) this.orbitAngle-=360;
while (this.orbitAngle<0) this.orbitAngle+=360;
如果你能提供一个像小提琴这样的游乐场,那就太好了。
@Jamal让我编辑:
这就是为什么我建议了一个版本,您可以通过添加/减法360来更正这个值。
如果有人滥用代码并输入非常高的值来改变角度,您最终可能会得到orbitAngle>720,所以只减320是不够的。
另一个建议可能是使用模块化--现在我已经考虑过了。;)
https://codereview.stackexchange.com/questions/211796
复制相似问题