package me.hammerle.supersnuvi.javafx; import javafx.animation.AnimationTimer; import javafx.application.Application; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.paint.Color; import javafx.stage.Stage; import me.hammerle.text.SnuviTextPainter; public class JavaRenderer extends Application implements IJavaRenderer { // ------------------------------------------------------------------------- // start up // ------------------------------------------------------------------------- public static void main(String[] args) { Application.launch(args); } // ------------------------------------------------------------------------- // javafx stuff // ------------------------------------------------------------------------- private Group root; private Scene scene; private Canvas canvas; private GraphicsContext context; @Override public void init() throws Exception { root = new Group(); } @Override public void start(Stage stage) throws Exception { // setup stage.setTitle("Super Snuvi"); scene = new Scene(root); stage.setScene(scene); canvas = new Canvas(800, 600); root.getChildren().add(canvas); context = canvas.getGraphicsContext2D(); textPainter = new SnuviTextPainter(canvas); // scene rescaling event scene.widthProperty().addListener((observable, oldValue, newValue) -> { if(oldValue.intValue() != 0) { canvas.setWidth(scene.getWidth()); } }); scene.heightProperty().addListener((observable, oldValue, newValue) -> { if(oldValue.intValue() != 0) { canvas.setHeight(scene.getHeight()); } }); // init key listener / register key events initKeyListener(); // start game loop startLoop(); // stage is shown after first game loop, the first frame can be seen stage.show(); } @Override public void stop() throws Exception { if(timer != null) { timer.stop(); } } // ------------------------------------------------------------------------- // game tick // ------------------------------------------------------------------------- private AnimationTimer timer = null; private void startLoop() { if(timer == null) { timer = new AnimationTimer() { private long last = System.nanoTime(); private long lag = 0; @Override public void handle(long now) { lag += now - last; last = now; while(lag >= 12_500_000) { lag -= 12_500_000; } } }; timer.start(); } } // ------------------------------------------------------------------------- // key input // ------------------------------------------------------------------------- private void initKeyListener() { } // ------------------------------------------------------------------------- // image rendering // ------------------------------------------------------------------------- @Override public void drawImage(Image image, double x, double y) { context.drawImage(image.getImageSlot(), x, y); } @Override public void drawImage(Image image, double x, double y, double w, double h) { context.drawImage(image.getImageSlot(), x, y, w, h); } @Override public void drawImage(Image image, double sx, double sy, double sw, double sh, double dx, double dy, double dw, double dh) { context.drawImage(image.getImageSlot(), sx, sy, sw, sh, dx, dy, dw, dh); } // ------------------------------------------------------------------------- // primitive rendering // ------------------------------------------------------------------------- @Override public double getWidth() { return canvas.getWidth(); } @Override public double getHeight() { return canvas.getHeight(); } @Override public void prepareRendering() { context.setFill(Color.BLACK); context.fillRect(0, 0, getWidth(), getHeight()); } @Override public void save() { context.save(); } @Override public void restore() { context.restore(); } @Override public void setFillColor(int r, int g, int b, double alpha) { context.setFill(Color.rgb(r, g, b, alpha)); } @Override public void setStrokeColor(int r, int g, int b, double alpha) { context.setStroke(Color.rgb(r, g, b, alpha)); } @Override public void fillRectangle(double x, double y, double w, double h) { context.fillRect(x, y, w, h); } @Override public void setGlobalAlpha(double alpha) { context.setGlobalAlpha(alpha); } @Override public void setScale(double scale) { context.scale(scale, scale); } // ------------------------------------------------------------------------- // text rendering // ------------------------------------------------------------------------- public static final int CHARS_PER_LINE = 50; private SnuviTextPainter textPainter; @Override public void prepareTextDrawing(int r, int g, int b, double alpha, int width) { textPainter.setScale(1); double scale = getWidth() / textPainter.getWidth(width); if(scale >= 1) { scale = (int) scale; } textPainter.prepareStringDrawing(Color.rgb(r, g, b, alpha), scale); } @Override public void stopTextDrawing() { textPainter.stopStringDrawing(); } @Override public void drawText(double x, double y, char[] text, int max) { textPainter.paintString(text, x, y, max); } @Override public double getTextWidth(int chars) { return textPainter.getWidth(chars); } @Override public double getTextHeight(int lines) { return textPainter.getHeight(lines); } }