From 2e05895a921de45fb869cb252ba85df6f9252d4d Mon Sep 17 00:00:00 2001 From: Timo Hocker Date: Sat, 27 Jun 2020 16:19:15 +0200 Subject: [PATCH] optimization --- Boid.java | 31 +++++++++++++++++++++++-------- Display.java | 3 +++ Main.java | 6 +++--- PhysicsObject.java | 2 +- 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/Boid.java b/Boid.java index b0a4925..040e6f2 100644 --- a/Boid.java +++ b/Boid.java @@ -3,12 +3,15 @@ import java.util.ArrayList; import java.util.Random; public class Boid extends PhysicsObject implements Drawable { - public Boid(int width, int height) { + private int group; + + public Boid(int width, int height, int group) { super(0, 0, 0, 0); Random r = new Random(); this.x = r.nextInt(width); this.y = r.nextInt(height); this.apply_force(r.nextFloat() * 2 - 1, r.nextFloat() * 2 - 1, 1); + this.group = group; } @Override @@ -16,22 +19,34 @@ public class Boid extends PhysicsObject implements Drawable { g.fillOval((int) x, (int) y, 2, 2); } - @Override - public void simulate() { + public void simulate(int group) { super.simulate(); - ArrayList others = ChunkManager.get_objects((int) x, (int) y); - if (others.size() == 0) + // Gruppen werden zeitversetzt aktualisiert um die Performance zu verbessern + if (this.group != group) return; - for (PhysicsObject o : others) { + ArrayList others = ChunkManager.get_objects((int) x, (int) y); + + int other_count = others.size(); + + if (other_count == 0) + return; + + for (int i = 0; i < other_count; i++) { + // Überprüfung teilweise überspringen, wenn es zu viele objekte in der Nähe gibt + if ((i + group) % Math.max(1, other_count / 16) != 1) + continue; + + PhysicsObject o = others.get(i); double dist = this.get_sqr_distance(o); if (dist < 500 && dist > 20) { - // Rule 1: collect in groups + // Regel 1: Zu anderen hin bewegen this.apply_force(o.x - x, o.y - y, (float) Math.min(0.005 / dist, 1)); + // Regel 3: In die Richtung der anderen fliegen this.apply_force(o.v_x, o.v_y, 0.005f); } else if (dist < 20) { - // Rule 2: keep distance + // Regel 2: Abstand halten this.apply_force(x - o.x, y - o.y, (float) Math.min(0.005 / dist, 1)); } } diff --git a/Display.java b/Display.java index fd403c4..23aef23 100644 --- a/Display.java +++ b/Display.java @@ -20,14 +20,17 @@ public class Display extends JFrame { @Override public void paint(Graphics g) { + // Doppelpuffer um Flackern zu verhindern BufferedImage b = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics bg = b.getGraphics(); + bg.setColor(Color.BLACK); bg.fillRect(0, 0, width, height); bg.setColor(Color.WHITE); for (Drawable d : dc.get_drawables()) { d.draw(bg); } + g.drawImage(b,0, 0, width, height, Color.BLACK, this); } } diff --git a/Main.java b/Main.java index 21794da..17a3314 100644 --- a/Main.java +++ b/Main.java @@ -24,7 +24,7 @@ public class Main implements DrawableCollection { public Main() { boids = new Boid[BOID_COUNT]; for (int i = 0; i < BOID_COUNT; i++) { - boids[i] = new Boid(WIDTH, HEIGHT); + boids[i] = new Boid(WIDTH, HEIGHT, i % 16); } d = new Display(WIDTH, HEIGHT, this); @@ -34,8 +34,8 @@ public class Main implements DrawableCollection { new Timer().scheduleAtFixedRate(new TimerTask() { @Override public void run() { - for (Boid b : boids) { - b.simulate(); + for (int i = 0; i < BOID_COUNT; i++) { + boids[i].simulate(i % 16); } ChunkManager.clear(); for (Boid b : boids) { diff --git a/PhysicsObject.java b/PhysicsObject.java index f912df1..a92eff6 100644 --- a/PhysicsObject.java +++ b/PhysicsObject.java @@ -29,7 +29,7 @@ public class PhysicsObject { } public void apply_force(float x, float y, float factor) { - if (x == 0 && y == 0) + if ((x == 0 && y == 0) || factor == 0) return; double len = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); v_x += (x / len) * factor;