import javafx.application.Application; import javafx.stage.Stage; import javafx.scene.Scene; import javafx.scene.layout.StackPane; import javafx.scene.canvas.*; import javafx.scene.paint.Color; import javafx.animation.AnimationTimer; import javafx.scene.input.KeyCode; import java.util.*; public class Primes extends Application{ private static final int WIDTH = 800; private static final int HEIGHT = 600; private static final int FPS = 40; private int squareSize = 5; private int cameraX, cameraY; private HashMap keys = new HashMap<>(); private int frames, fps; @Override public void start(Stage stage){ StackPane pane = new StackPane(); Canvas canvas = new Canvas(WIDTH, HEIGHT); pane.getChildren().add(canvas); GraphicsContext gc = canvas.getGraphicsContext2D(); canvas.setOnScroll(e -> { if (e.getDeltaY() > 0){ this.squareSize += 1; } else if (e.getDeltaY() < 0){ this.squareSize -= 1; } this.squareSize = Math.min(150, Math.max(this.squareSize, 1)); }); canvas.setFocusTraversable(true); canvas.setOnKeyPressed(e -> this.keys.put(e.getCode(), true)); canvas.setOnKeyReleased(e -> this.keys.put(e.getCode(), false)); AnimationTimer timer = new AnimationTimer(){ @Override public void handle(long time){ update(gc); Primes.this.frames++; stage.setTitle("Prime numbers - FPS:"+Primes.this.fps); // Set FPS title } }; timer.start(); Thread fpsCounter = new Thread(() -> { while (true){ try { this.fps = this.frames; this.frames = 0; Thread.sleep(1000); } catch (InterruptedException ex){ ex.printStackTrace(); } } }); fpsCounter.setDaemon(true); fpsCounter.start(); Scene scene = new Scene(pane, WIDTH, HEIGHT); stage.setScene(scene); stage.setResizable(false); stage.show(); } private void update(GraphicsContext gc){ gc.clearRect(0, 0, WIDTH, HEIGHT); gc.setFill(Color.BLACK); gc.fillRect(0, 0, WIDTH, HEIGHT); final int cameraSpeed = 4; if (this.keys.getOrDefault(KeyCode.W, false)){ this.cameraY -= cameraSpeed; this.keys.put(KeyCode.W, false); } else if (this.keys.getOrDefault(KeyCode.A, false)){ this.cameraX -= cameraSpeed; this.keys.put(KeyCode.A, false); } else if (this.keys.getOrDefault(KeyCode.S, false)){ this.cameraY += cameraSpeed; this.keys.put(KeyCode.S, false); } else if (this.keys.getOrDefault(KeyCode.D, false)){ this.cameraX += cameraSpeed; this.keys.put(KeyCode.D, false); } else if (this.keys.getOrDefault(KeyCode.ESCAPE, false)){ System.exit(0); } for (int i = 0; i < WIDTH; i += squareSize){ for (int j = 0; j < HEIGHT; j += squareSize){ int xpos = i/squareSize+this.cameraX; int ypos = j/squareSize+this.cameraY; if (xpos < 0 || ypos < 0) continue; int id = xpos ^ ypos; //xpos+ypos*WIDTH; if (isPrime(id)){ for (int x = 0; x < squareSize; x++){ for (int y = 0; y < squareSize; y++){ gc.getPixelWriter().setColor(i+x, j+y, getColor(id)); } } } } } } private static Color getColor(int prime){ Random random = new Random(prime); return Color.color(random.nextDouble(), random.nextDouble(), random.nextDouble()); } private static boolean isPrime(int num){ for (int i = 2; i <= Math.sqrt(num); i++){ if (num % i == 0){ return false; } } return true; } public static void main(String[] args){ launch(args); } }