我是JavaScript的新手,所以我在寻求帮助。我正在尝试创建一个简单的太阳系模拟,它表示为围绕一个大圆(太阳)移动的几个小圆圈(行星)。我使用Paper.js来创建动画。
我创建了两个类:Star和Planet。 Star类有draw()方法绘制星星,Planet类有motion()方法使行星移动。
问题在于,当我创建多个对象并调用它们的draw()/ motion()方法,然后尝试运行脚本时,我创建的最后一个对象是唯一要绘制/动画的对象。
例如,在此代码中:
var sun = new Star("Sun", 400, 400, 50, '#fff250');
sun.draw();
var earth = new Planet("Earth", sun, 100, 10, 1.5, '#b6f7ff');
earth.motion();
var mars = new Planet("Mars", sun, 200, 10, 0.5, '#ff9485');
mars.motion();
mars.motion()会正常工作,但其他两种方法都会被忽略。如果我删除此方法,将出现地球等等。
以下是完整代码:
function Star(name, xCoordinate, yCoordinate, radius, color) {
this.name = name;
this.xCoordinate = xCoordinate;
this.yCoordinate = yCoordinate;
this.radius = radius;
this.color = color;
var canvas = document.getElementById("canvas1");
paper.setup(canvas);
this.draw = function () {
var circle = new paper.Path.Circle(new paper.Point(xCoordinate, yCoordinate), radius);
circle.fillColor = color;
}
}
function Planet(name, parentStar, distanceFromStar, radius, period, color) {
this.name = name;
this.parentStar = parentStar;
this.distanceFromStar = distanceFromStar;
this.radius = radius;
this.period = period;
this.color = color;
var xCoordinate = parentStar.xCoordinate + distanceFromStar;
var yCoordinate = parentStar.yCoordinate + distanceFromStar;
var canvas = document.getElementById("canvas1");
paper.setup(canvas);
this.motion = function () {
var circle = new paper.Path.Circle(new paper.Point(xCoordinate, yCoordinate), radius);
circle.fillColor = color;
paper.view.onFrame = function (event) {
circle.position.x = parentStar.xCoordinate - distanceFromStar * Math.cos(period * event.time);
circle.position.y = parentStar.yCoordinate - distanceFromStar * Math.sin(period * event.time);
}
}
}
window.onload = function() {
var sun = new Star("Sun", 400, 400, 50, '#fff250');
sun.draw();
var earth = new Planet("Earth", sun, 100, 10, 1.5, '#b6f7ff');
earth.motion();
var mars = new Planet("Mars", sun, 200, 10, 0.5, '#ff9485');
mars.motion();
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="paper-core.js"></script>
<script src="solar-system.js"></script>
</head>
<body>
<canvas id="canvas1" resize="" style="user-select: none; touch-action: none; -webkit-user-drag: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);" width="800" height="800" ></canvas>
</body>
</html>
我认为可能的原因是我这样做了
var canvas = document.getElementById("canvas1");
paper.setup(canvas);
每次我创建一个新对象,但我不确定。请帮忙。提前谢谢。
答案 0 :(得分:0)
你对这个问题的假设是正确的。
每次绘制元素时都要设置整个画布。
您只需要设置一次(刚刚从绘制方法中删除了设置并将其添加到window.onload
)。
另一个问题是您将每个行星更新代码分配为paper.view.onFrame
。但它只能包含一个功能。为此我创建了一个列表,其中每个行星的更新函数去,然后在paper.view.onFrame
i迭代数组并执行每个行星函数。
以下是包含更改的代码
var planetList = [];
function Star(name, xCoordinate, yCoordinate, radius, color, canvas) {
this.name = name;
this.xCoordinate = xCoordinate;
this.yCoordinate = yCoordinate;
this.radius = radius;
this.color = color;
this.draw = function() {
var circle = new paper.Path.Circle(new paper.Point(xCoordinate, yCoordinate), radius);
circle.fillColor = color;
}
}
function Planet(name, parentStar, distanceFromStar, radius, period, color, canvas) {
this.name = name;
this.parentStar = parentStar;
this.distanceFromStar = distanceFromStar;
this.radius = radius;
this.period = period;
this.color = color;
var xCoordinate = parentStar.xCoordinate + distanceFromStar;
var yCoordinate = parentStar.yCoordinate + distanceFromStar;
this.motion = function() {
var circle = new paper.Path.Circle(new paper.Point(xCoordinate, yCoordinate), radius);
circle.fillColor = color;
planetList.push( function(event) {
circle.position.x = parentStar.xCoordinate - distanceFromStar * Math.cos(period * event.time);
circle.position.y = parentStar.yCoordinate - distanceFromStar * Math.sin(period * event.time);
});
}
}
window.onload = function() {
var canvas = document.getElementById("canvas1");
paper.setup(canvas);
var sun = new Star("Sun", 400, 400, 50, '#fff250', );
sun.draw();
var earth = new Planet("Earth", sun, 100, 10, 1.5, '#b6f7ff');
earth.motion();
var mars = new Planet("Mars", sun, 200, 10, 0.5, '#ff9485');
mars.motion();
paper.view.onFrame = function(event){
var pLen = planetList.length,
p;
for (p=0;p<pLen;p++){
planetList[p](event);
}
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.10.3/paper-full.min.js"></script>
</head>
<body>
<canvas id="canvas1" resize="" style="user-select: none; touch-action: none; -webkit-user-drag: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);" width="800" height="800"></canvas>
</body>
</html>