问题描述
对于我们的学校作业,我们的任务是
更改教程中的两个 Car 对象程序,以便每次 汽车相互擦身而过,汽车减速到它们速度的 33% 并且在两辆车的中心之间画了一条橙色的垂直线 表示司机在进行眼神交流。
但是,每当我尝试使用 if-else 条件或其他方法更改速度时,速度更改就会变成永久性的。其他时候,速度根本没有变化。我只设法做橙色垂直线。
这是我目前拥有的图片: Screenshot of the program
这是它应该做的: Video
代码如下:
// Example: Two Car objects
Car myCar1;
Car myCar2; // Two objects!
void setup() {
size(200,200);
// Parameters go inside the parentheses when the object is constructed.
myCar1 = new Car(color(255,0),100,2);
myCar2 = new Car(color(0,255),10,1);
}
void draw() {
background(255);
myCar1.drive();
myCar1.display();
myCar2.drive();
myCar2.display();
stroke(255,128,0);
line(myCar1.xpos,myCar1.ypos,myCar2.xpos,myCar2.ypos);
}
// Even though there are multiple objects,we still only need one class.
// No matter how many cookies we make,only one cookie cutter is needed.
class Car {
color c;
float xpos;
float ypos;
float xspeed;
// The Constructor is defined with arguments.
Car(color tempC,float tempXpos,float tempYpos,float tempXspeed) {
c = tempC;
xpos = tempXpos;
ypos = tempYpos;
xspeed = tempXspeed;
}
void display() {
stroke(0);
fill(c);
rectMode(CENTER);
rect(xpos,ypos,20,10);
}
void drive() {
xpos = xpos + xspeed;
if (xpos > width) {
xpos = 0;
}
}
}
非常感谢任何帮助。提前致谢。
[1]: https://i.stack.imgur.com/q0hAX.png
[2]: https://youtu.be/dIGr9RprfoE
解决方法
我会先停止任务:
更改教程中的两个 Car 对象程序,以便每次 汽车相互擦身而过,汽车减速到其速度的 33%,并在两个中心之间绘制一条橙色垂直线 两辆车表示司机有眼神交流。
你如何确定汽车是否相互经过?
幸运的是,在这个简单的例子中,运动是一个维度:在 X 轴上。
您可以简单地比较每辆车的xpos
例如
if(myCar1.xpos == myCar2.xpos){
println("slow down to 33% and draw orange line between cars");
}
您在处理浮点数时确实需要小心,因此与比较整数相比,数字完全匹配的几率要小得多。
例如,您可以使用 dist()
函数计算两对点之间的欧几里得距离,但是汽车不会在 x,y 上移动,而是在 x 上移动,因此您可以节省一点通过简单地计算 abs()
两个 x 位置之间的差异来计算计算能力。:
float absdiff = abs(myCar1.xpos - myCar2.xpos);
您可以使用阈值来代替绝对距离的比较。
假设汽车之间的距离小于 20 像素,那么它们就被认为是相互经过。这将导致模拟不那么刺耳,因为检查单个值 (distance == 0
) 最多会在一瞬间(帧)内发生,而范围(distance < threshold
)将在更长的时间内为真。>
除此之外,绘制线(您已经这样做了)并将速度降低到 33%;
问题是您需要为 Car
类添加一个额外的属性来记住原始速度,以便您可以轻松恢复到,否则值将变得相对并不断减小。否则,每次汽车经过时,都会减速停下。
您可以使用额外变量将当前速度简单地设置为此初始值(当汽车不再相互通过时)或设置为该初始值的 33% 否则:
// Example: Two Car objects
Car myCar1;
Car myCar2; // Two objects!
// anything smaller than this distance means the cars pass each other
float passbyThreshold = 20;
void setup() {
size(600,200);
strokeWeight(3);
// Parameters go inside the parentheses when the object is constructed.
// speed up car 1 for testing to increase the odds of passing by
myCar1 = new Car(color(255,0),100,4);
myCar2 = new Car(color(0,255),10,1);
}
void draw() {
background(255);
myCar1.drive();
myCar1.display();
myCar2.drive();
myCar2.display();
// compute 1D distance between cars (abs() means it doesn't matter which one's faster)
float absdiff = abs(myCar1.xpos - myCar2.xpos);
text("distance:" + absdiff,height-15);
// if the cars are close enough to be passing by
if(absdiff < passbyThreshold){
// slow down the cars to 33% of their speed
myCar1.slowDown();
myCar2.slowDown();
// draw the orange line between the centres
stroke(255,128,0);
line(myCar1.xpos,myCar1.ypos,myCar2.xpos,myCar2.ypos);
}else{
myCar1.revertSpeed();
myCar2.revertSpeed();
}
}
// Even though there are multiple objects,we still only need one class.
// No matter how many cookies we make,only one cookie cutter is needed.
class Car {
color c;
float xpos;
float ypos;
// original speed
float ospeed;
float xspeed;
// The Constructor is defined with arguments.
Car(color tempC,float tempXpos,float tempYpos,float tempXspeed) {
c = tempC;
xpos = tempXpos;
ypos = tempYpos;
xspeed = tempXspeed;
// store original speed so xspeed can be restored to it
ospeed = tempXspeed;
}
void display() {
stroke(0);
fill(c);
rectMode(CENTER);
rect(xpos,ypos,20,10);
text(xspeed,xpos - 10,ypos + 20);
}
void drive() {
xpos = xpos + xspeed;
if (xpos > width) {
xpos = 0;
}
}
void slowDown(){
// set speed to 33% of the original speed
xspeed = ospeed * .33;
}
void revertSpeed(){
// revert speed to the original value
xspeed = ospeed;
}
}