package game2048;
import javafx.application.Application;
import javafx.application.ConditionalFeature;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Bounds;
import javafx.geometry.Rectangle2D;
import javafx.scene.Cursor;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Font;
import javafx.stage.Screen;
import javafx.stage.Stage;
/**
* @author bruno.borges@oracle.com
*/
public class Game2048 extends Application {
private GameManager gameManager;
private Bounds gameBounds;
private final static int MARGIN = 36;
@Override
public void init() {
// Downloaded from https://01.org/clear-sans/blogs
// The font may be used and redistributed under the terms of the Apache License, Version 2.0.
Font.loadFont(Game2048.class.getResource("ClearSans-Bold.ttf").toExternalForm(), 10.0);
}
@Override
public void start(Stage primaryStage) {
gameManager = new GameManager();
gameBounds = gameManager.getLayoutBounds();
StackPane root = new StackPane(gameManager);
root.getStyleClass().addAll("game-root");
ChangeListener<Number> resize = (ov, v, v1) -> {
double scale = Math.min((root.getWidth() - MARGIN) / gameBounds.getWidth(), (root.getHeight() - MARGIN) / gameBounds.getHeight());
gameManager.setScale(scale);
gameManager.setLayoutX((root.getWidth() - gameBounds.getWidth()) / 2d);
gameManager.setLayoutY((root.getHeight() - gameBounds.getHeight()) / 2d);
};
root.widthProperty().addListener(resize);
root.heightProperty().addListener(resize);
Scene scene = new Scene(root);
scene.getStylesheets().add("game2048/game.css");
addKeyHandler(scene);
addSwipeHandlers(scene);
if (isARMDevice()) {
primaryStage.setFullScreen(true);
primaryStage.setFullScreenExitHint("");
}
if (Platform.isSupported(ConditionalFeature.INPUT_TOUCH)) {
scene.setCursor(Cursor.NONE);
}
Rectangle2D visualBounds = Screen.getPrimary().getVisualBounds();
double factor = Math.min(visualBounds.getWidth() / (gameBounds.getWidth() + MARGIN),
visualBounds.getHeight() / (gameBounds.getHeight() + MARGIN));
primaryStage.setTitle("2048FX");
primaryStage.setScene(scene);
primaryStage.setMinWidth(gameBounds.getWidth() / 2d);
primaryStage.setMinHeight(gameBounds.getHeight() / 2d);
primaryStage.setWidth((gameBounds.getWidth() + MARGIN) * factor);
primaryStage.setHeight((gameBounds.getHeight() + MARGIN) * factor);
primaryStage.show();
}
private boolean isARMDevice() {
return System.getProperty("os.arch").toUpperCase().contains("ARM");
}
private void addKeyHandler(Scene scene) {
scene.setOnKeyPressed(ke -> {
KeyCode keyCode = ke.getCode();
if (keyCode.equals(KeyCode.S)) {
gameManager.saveSession();
return;
}
if (keyCode.equals(KeyCode.R)) {
gameManager.restoreSession();
return;
}
if (keyCode.equals(KeyCode.P)) {
gameManager.pauseGame();
return;
}
if (keyCode.equals(KeyCode.Q) || keyCode.equals(KeyCode.ESCAPE)) {
gameManager.quitGame();
return;
}
if (keyCode.isArrowKey()) {
Direction direction = Direction.valueFor(keyCode);
gameManager.move(direction);
}
});
}
private void addSwipeHandlers(Scene scene) {
scene.setOnSwipeUp(e -> gameManager.move(Direction.UP));
scene.setOnSwipeRight(e -> gameManager.move(Direction.RIGHT));
scene.setOnSwipeLeft(e -> gameManager.move(Direction.LEFT));
scene.setOnSwipeDown(e -> gameManager.move(Direction.DOWN));
}
@Override
public void stop() {
gameManager.saveRecord();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}