public class BorderRenderTask implements Runnable { private static final int TRANSIENT_POINTS = 16; private static final double POINT_DISTANCE = 8d / TRANSIENT_POINTS; private static final double RENDER_DISTANCE = 8; private final Game game; private final GameBorder border; private int currentPoint = 0; public BorderRenderTask(AbstractPhase phase, GameBorder border) { this.game = phase.getGame(); this.border = border; } @Override public void run() { Cuboid cuboid = border.getCuboid(); ParticleCube cube = ParticleCube.wrap(cuboid, POINT_DISTANCE); World world = game.getMap().getWorld(); currentPoint++; List squares = cube.getSquares(); for (ParticleSquare square : squares) { for (ParticleLine line : square.getLines()) { for (Player player : game.getPlayerTracker().getPlayers()) { List points = line.getPoints(player); currentPoint++; currentPoint %= TRANSIENT_POINTS; for (int index = currentPoint; index < points.size(); index++) { Vector point = points.get(index); sendParticle(player, point.toLocation(world)); } } } } } private void sendParticle(Player player, Location location) { Location playerLocation = player.getEyeLocation(); // Particles are seen from the eyes if (playerLocation.toVector().distanceSquared(location.toVector()) < (RENDER_DISTANCE * RENDER_DISTANCE)) { player.spawnParticle(Particle.REDSTONE, location, 1, 0, 0, 0, 0, new DustOptions(Color.RED, 1f)); } } }