package me.hammerle.supersnuvi.rendering; import me.hammerle.supersnuvi.gamelogic.StateRenderer; import javafx.animation.AnimationTimer; import javafx.scene.Scene; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.image.Image; import javafx.scene.input.KeyEvent; import javafx.scene.paint.Color; import javafx.scene.paint.Paint; import me.hammerle.supersnuvi.input.KeyHandler; import me.hammerle.text.SnuviTextPainter; public class GameRenderer extends AnimationTimer implements IGameRenderer { // constants public final static int TILE_SIZE = 32; // basic graphic stuff private final Scene scene; private final Canvas canvas; // input handler private final KeyHandler keys; // timing private long lastHandle; private long timingSum; // rendering private double cameraX; private double cameraY; private double offsetX; private double offsetY; private GraphicsContext context; // text rendering private final SnuviTextPainter textPainter; // world rendering private final StateRenderer state; public GameRenderer(Scene scene, Canvas canvas) { // basic graphic stuff this.scene = scene; this.canvas = canvas; // input handler this.keys = new KeyHandler(); //timing this.lastHandle = 0; this.timingSum = 0; // rendering this.cameraX = 0; this.cameraY = 0; this.offsetX = 0; this.offsetY = 0; this.context = null; this.textPainter = new SnuviTextPainter(canvas); // events registerEvents(); this.state = new StateRenderer(this); } private void registerEvents() { // basic input handling scene.setOnKeyPressed((KeyEvent e) -> { keys.pressKey(e.getCode()); }); scene.setOnKeyReleased((KeyEvent e) -> { keys.releaseKey(e.getCode()); }); // 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()); } }); } @Override public void handle(long now) { timingSum += now - lastHandle; lastHandle = now; if(timingSum >= 15900000) { timingSum = 0; keys.tick(); prepareRendering(); state.tick(keys); } } private void prepareRendering() { offsetX = -cameraX; offsetY = canvas.getHeight() + cameraY; context = canvas.getGraphicsContext2D(); context.setFill(Color.BLACK); context.fillRect(0, 0, canvas.getWidth(), canvas.getHeight()); } @Override public void prepareStringDrawing(Color c) { textPainter.prepareStringDrawing(c, Math.min ( canvas.getHeight() / (textPainter.getBaseHeight() * LINES), canvas.getWidth() / (textPainter.getBaseWidth() * CHARS_PER_LINE)) ); } @Override public void stopStringDrawing() { textPainter.stopStringDrawing(); } @Override public double getStringOffsetX(int x) { double width = canvas.getWidth(); width -= textPainter.getWidth(CHARS_PER_LINE); width /= 2; return width + textPainter.getWidth(x); } @Override public double getStringOffsetY(int y) { double height = canvas.getHeight(); height -= textPainter.getHeight() * LINES; height /= 2; return height + textPainter.getHeight() * y; } @Override public double getLineHeight() { return textPainter.getHeight(); } @Override public double getStringWidth(int length) { return textPainter.getWidth(length); } @Override public double getStringWidth(String s) { return textPainter.getWidth(s); } @Override public double getCharsWidth(char[] chars) { return textPainter.getWidth(chars); } @Override public void drawString(String s, double x, double y) { textPainter.paintString(s, x, y); } @Override public void drawChars(char[] chars, double x, double y) { textPainter.paintString(chars, x, y); } @Override public void drawImage(Image image, double x, double y) { context.drawImage(image, offsetX + x, offsetY - y); } @Override public void drawBlockImage(Image image, int x, int y) { context.drawImage(image, offsetX + x * TILE_SIZE, offsetY - (y + 1) * TILE_SIZE); } @Override public void setStrokeColor(Color c) { context.setStroke(c); } @Override public void setFillColor(Color c) { context.setFill(c); } @Override public void fillRec(double x, double y, double width, double height, Color c) { Paint paint = context.getFill(); context.setFill(c); context.fillRect(x, y, width, height); context.setFill(paint); } @Override public int getFirstVisibleBlockX() { return Math.max(0, (int) (cameraX / TILE_SIZE)); } @Override public int getFirstVisibleBlockY() { return Math.max(0, (int) (cameraY / TILE_SIZE)); } @Override public int getLastVisibleBlockX() { return getFirstVisibleBlockX() + (int) (canvas.getWidth() / TILE_SIZE); } @Override public int getLastVisibleBlockY() { return getFirstVisibleBlockY() + (int) (canvas.getHeight()/ TILE_SIZE); } @Override public int toBlock(double c) { return (int) (c / TILE_SIZE); } @Override public double toCoord(int b) { return b * TILE_SIZE; } }