Ich bin neu in der Verarbeitung. Ich habe den folgenden Code mit springenden Bällen geschrieben, aber die Animation ist nicht glatt. Ich habe die Anwendung auf verschiedenen Computern ausgeführt und kann gelegentlich ein Zittern oder Reißen von Bällen sehen. Ich glaube nicht, dass es sich um die Berechnungszeit handelt, da für jeden Frame nicht viel berechnet wird. Außerdem habe ich gelesen, dass die Verarbeitung bereits doppelt gepuffert ist.Tearing und Jitter in einer einfachen Verarbeitung Animation
Im Folgenden ist der betreffende Code:
final int MAX_BALLS = 50;
final int DISPLAY_WIDTH = 800;
final int DISPLAY_HEIGHT = 600;
final float MIN_SPEED = 1;
final float MAX_SPEED = 5;
final float MIN_SIZE = 30;
final float MAX_SIZE = 50;
Ball[] balls = new Ball[MAX_BALLS];
void setup() {
size(800, 600);
stroke(255);
background(0, 0, 0);
for (int i=0; i<balls.length; i++) {
balls[i] = new Ball(random(MIN_SIZE, MAX_SIZE), random(0, DISPLAY_WIDTH), random(0, DISPLAY_HEIGHT), random(MIN_SPEED, MAX_SPEED), random(MIN_SPEED, MAX_SPEED), 0, DISPLAY_WIDTH, 0, DISPLAY_HEIGHT);
}
}
void draw() {
clear();
for (int i = 0; i<balls.length; i++)
balls[i].draw();
}
class Ball {
private float size;
private float x;
private float y;
private float vx;
private float vy;
private float minx;
private float maxx;
private float miny;
private float maxy;
private float r;
private float g;
private float b;
public Ball(float size,float x, float y, float vx, float vy, float minx, float maxx, float miny, float maxy) {
this.size = size;
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
this.minx = minx;
this.maxx = maxx;
this.miny = miny;
this.maxy = maxy;
r = (int) random(30, 255);
g = (int) random(30, 255);
b = (int) random(30, 255);
}
void draw() {
x = x + vx;
if (x + size/2 > maxx) {
vx = -vx;
x = 2 * maxx - (x + size);
} else if (x - size/2 < minx) {
vx = -vx;
x = 2 * minx - (x - size);
}
y = y + vy;
if (y + size/2 > maxy) {
vy = -vy;
y = 2 * maxy - (y + size);
} else if (y -size/2 < miny) {
vy = -vy;
y = 2 * miny - (y - size);
}
stroke(r,g,b);
fill(r,g,b);
ellipse(x, y, size, size);
}
}
Wie kann ich für den Jitter loszuwerden und reißen? Wie stelle ich sicher, dass der Grafikkartentreiber optimal genutzt wird? Beachten Sie, dass ich Linux Mint 17.3 mit MATE Desktop Manager verwende. Gleiches O.S. auf allen getesteten PCs und gleiches Verhalten.
[EDIT 05/01/2016] Nach dem Erstellen der Kreise Off-Screen und sogar mit einem Offline-Bild die Größe des Bildschirms, bekomme ich immer noch einige Tearing. Dies ist der aktualisierte Code:
final int MAX_BALLS = 50;
final float MIN_SPEED = 1;
final float MAX_SPEED = 5;
final float MIN_SIZE = 30;
final float MAX_SIZE = 50;
Ball[] balls = new Ball[MAX_BALLS];
PGraphics img;
void setup() {
frameRate(60);
fullScreen();
img = createGraphics(width, height);
img.stroke(255);
img.smooth();
for (int i=0; i<balls.length; i++) {
balls[i] = new Ball(random(MIN_SIZE, MAX_SIZE), random(0, width), random(0, height), random(MIN_SPEED, MAX_SPEED), random(MIN_SPEED, MAX_SPEED), 0, width, 0, height);
}
}
void draw() {
img.beginDraw();
img.background(0,0,0);
img.clear();
clear();
for (int i = 0; i<balls.length; i++)
balls[i].draw();
img.text((int)frameRate+"fps",10,15);
img.endDraw();
image(img, 0, 0); // Put the whole image at once on the screen
}
class Ball {
private float size;
private float x;
private float y;
private float vx;
private float vy;
private float minx;
private float maxx;
private float miny;
private float maxy;
private PGraphics circle;
private final int MARGIN = 10; // Margin to avoid circle to be drawn slightly outside the square
public Ball(float size,float x, float y, float vx, float vy, float minx, float maxx, float miny, float maxy) {
this.size = size;
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
this.minx = minx;
this.maxx = maxx;
this.miny = miny;
this.maxy = maxy;
int r = (int) random(30, 255);
int g = (int) random(30, 255);
int b = (int) random(30, 255);
circle = createGraphics((int) this.size + 2*MARGIN, (int) this.size + 2*MARGIN);
circle.beginDraw();
circle.background(0, 0);
circle.fill(r, g, b);
circle.ellipse(MARGIN + this.size/2, MARGIN + this.size/2, this.size, this.size);
circle.endDraw();
}
void draw() {
x = x + vx;
if (x + size/2 > maxx) {
vx = -vx;
x = 2 * maxx - (x + size);
} else if (x - size/2 < minx) {
vx = -vx;
x = 2 * minx - (x - size);
}
y = y + vy;
if (y + size/2 > maxy) {
vy = -vy;
y = 2 * maxy - (y + size);
} else if (y -size/2 < miny) {
vy = -vy;
y = 2 * miny - (y - size);
}
img.image(circle, x - this.size/2 - MARGIN, y - this.size/2 - MARGIN);
}
}
Dieser Code läuft gut für mich auf Windows 10. Können Sie einen Screenshot von genau, was Sie reden? Ändern Sie Ihren Code möglicherweise, um hartcodierte Werte zu verwenden, die das Verhalten verursachen, anstatt die Funktion 'random()' zu verwenden. –
@KevinWorkman Das Verhalten ist unabhängig von der Größe der Bälle konsistent. Ich bekomme das Reißen jedes Mal, wenn ich die App laufen lasse. Ich habe es jedoch nicht unter Windows getestet. Ich konnte es nicht screenen. Videoaufnahmen mit 60 fps mit VLC konnten nicht erfasst werden. Es ist ein horizontales Reißen, wobei der untere Teil des Balls verschoben wird. – Tarik
Das wird ziemlich schwierig zu debuggen, wenn wir das Verhalten nicht wiederholen können. Welcher Ball? Berührt sich die zufällige Bewegung überhaupt, oder kannst du einfach die Bewegungsrichtung fest codieren? Kannst du mit nur einem Ball ein kleineres Beispiel erstellen?Es gibt eine Menge extra Code hier. Ist alles auf dein Problem bezogen? Wenn nicht, können Sie das Beispiel überhaupt vereinfachen? –