我正在创建一个正在处理的太阳系模型,删除背景后,我发现行星正向其留下一道影像。回到背景时,程序可以正常运行,但是我想添加更多内容,并且我肯定这效率不高,并且会使事情陷入困境。
我对处理非常陌生,我真的不确定如何解决这个问题。也许在延迟创建短径后删除以前的图像?
这些只是我认为是从代码中挑选出来的重要樱桃的部分,这只是一个行星的示例。抱歉,如果代码很笨拙,任何建议都会很高兴地接受。
Planet p1;
void setup() {
mercury = loadImage("mercury.png")
p1 = new Planet(40, random(TWO_PI), 0.05);
}
void draw() {
//background(0)
translate(width / 2, height / 2);
p1.display1();
p1.orbit();
}
class Planet {
float radius;
float angle;
float distance;
float orbitSpeed;
Planet(float r, float d, float o) {
radius = r;
distance = d;
orbitSpeed = o;
angle = random(TWO_PI);
}
void orbit() {
angle = angle + orbitSpeed;
}
void display1() {
pushMatrix();
rotate(angle);
translate(distance, 0);
imageMode(CENTER);
image(mercury, radius, radius, 10, 10);
popMatrix();
}
}
我意识到这可能会发生,而且我不确定如何阻止它。
答案 0 :(得分:0)
您描述的行为仅仅是计算机图形的本质;这就是游戏,操作系统和硬件显示所有工作的方式–它们清除并重新绘制每一帧的所有内容。
在处理中,被推到缓冲区的图形对象会无限期地保留在那里,直到缓冲区被清除或在其上方推入某些东西为止(这就是为什么行星在不调用{ {1}} –先前的帧保留在缓冲区中。
您担心background()
效率低下。不能,因为它是最快的操作之一(只需设置每个像素的值,由用户指定)。
处理过程确实提供了background()
函数,但这等效于clear()
。
如果您仍然担心效率和速度,加快处理速度的一种方法是使用background(0)
渲染器而不是默认的FX2D
渲染器。另一种方法是将绘制的对象缓存到AWT
对象中,以防止连续进行栅格化(由于您的行星是图像文件,并且未进行处理绘制,因此您不必担心)。
答案 1 :(得分:0)
您的代码非常简单,因此在此阶段不需要优化。 正如micycle所说,您正在以平移的位置绘制图像,与blitting非常相似。
就路径而言,您可以使用的一种常见技巧不是完全清除屏幕,而是绘制一个透明矩形作为背景。透明度越高,足迹越长。
这是您代码的经过调整的版本:
// planet object
Planet p1;
// planet texture
PImage mercury;
void setup() {
size(300, 300);
// draw image from center
imageMode(CENTER);
// clear to black one
background(0);
// remove strokes (we'll use rect() later)
noStroke();
// set the fill to black but with 9/255 transparency (~3.5% transparent)
fill(0,9);
// init texture
mercury = loadImage("mercury.png");
// init planet
p1 = new Planet(40, random(TWO_PI), 0.05);
}
void draw() {
// draw a transparent rectangle instead of completely clearing the screen
rect(0,0,width,height);
// render planet
translate(width / 2, height / 2);
p1.display1();
p1.orbit();
}
class Planet {
float radius;
float angle;
float distance;
float orbitSpeed;
Planet(float r, float d, float o) {
radius = r;
distance = d;
orbitSpeed = o;
angle = random(TWO_PI);
}
void orbit() {
angle = angle + orbitSpeed;
}
void display1() {
pushMatrix();
rotate(angle);
translate(distance, 0);
image(mercury, radius, radius, 10, 10);
popMatrix();
}
}
这是一种高效的快速“肮脏”技巧,因为您无需存储先前的位置并重画多次,但是它在步道的灵活性方面具有局限性。希望通过调整fill()
alpha参数可以达到理想的效果。
稍后,如果您要绘制许多许多行星,那么事情开始缓慢运行时会在VisualVM达到峰值。对CPU进行概要分析,并查看花费最长时间完成的方法,并集中精力研究这些方法。无需优化所有操作,只需最慢的调用即可。请记住,“处理”具有多个渲染器:JAVA2D
是默认渲染器,但是还有FX2D
和P2D
/ P3D
,它们的行为会有所不同。我强烈建议您在最后一刻进行优化(否则代码的灵活性和可读性可能会降低,从而减慢开发/迭代速度。)