import javafx.animation.Animation; import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.application.Application; import javafx.event.ActionEvent; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.Slider; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.BorderPane; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; import javafx.stage.Stage; import javafx.util.Duration; public class WhackAMouse extends Application { // constants private static final int BN_SIZE = 75; private static final int N_ROWS = 5; private static final int N_COLS = 7; private static final int SPACING = 4; private static final int APP_WIDTH = N_COLS * BN_SIZE; private static final int APP_HEIGHT = N_ROWS * BN_SIZE; private static final String IMG_NAME = "file:Mouse.gif"; // imgName private static final int INTERVAL = 1000; // msec private static final int DURATION = 10; // seconds // GUI variables private BorderPane mainPane; private GridPane grid; private Button[][] buttons; private ImageView ivMouse; private Timeline timerMain; private Timeline timerCountDown; // GUI: control panel private HBox controlPanel; private Label lbScore, lbCountDown; private Slider slSpeed; // functional variables private int score; // gain if user clicks on the mouse button private int timeLeft; private Button bnCurrent; // points to the button with the mouse public void start(Stage stage) { mainPane = new BorderPane(); // setup calls setupControlPanel(); setupImage(); setupBoard(); setupTimers(); assignMouse(); Scene scene = new Scene(mainPane, APP_WIDTH, APP_HEIGHT); stage.setTitle("CS112 F24 Whack-A-Mouse"); stage.setScene(scene); stage.show(); // TEMPORARY timerMain.play(); timerCountDown.play(); } private void setupControlPanel() { controlPanel = new HBox(SPACING); mainPane.setTop(controlPanel); // create buttons // create slider for game speed/level control slSpeed = new Slider(0.5, 2, 1); // create labels // TEMPORARY timeLeft = DURATION; lbCountDown = new Label("" + DURATION); lbScore = new Label("" + score); controlPanel.getChildren().addAll( // buttons new Label("Time left: "), lbCountDown, new Label("Score: "), lbScore); } private void setupImage() { ivMouse = new ImageView( new Image(IMG_NAME) ); } private void setupBoard() { grid = new GridPane(); mainPane.setCenter(grid); buttons = new Button[N_ROWS][N_COLS]; for (int r = 0; r < N_ROWS; ++r) { for (int c = 0; c < N_COLS; ++c) { Button bn = new Button(); bn.setPrefSize(BN_SIZE, BN_SIZE); // add to array buttons[r][c] = bn; bn.setOnAction( e -> { onClick(e); }); // add to board (grid pane) grid.add(bn, c, r); } } } private void onClick(ActionEvent e) { Object src = e.getSource(); Button bnClicked = (Button) src; // if the clicked button has the graphics, user scores // attempt 1: doesn't work, because all the previous buttons where // the mouse was on still have the pointer (not null) //if (bnClicked.getGraphic() != null) { // attempt 2: using global variable, bnCurrent if (bnClicked == bnCurrent) { ++score; } else { --score; } System.out.println("Current score = " + score); lbScore.setText("" + score); } private void setupTimers() { // timer for speed & mouse jumpting to a random location // setup key frame KeyFrame keyFrame1 = new KeyFrame(Duration.millis(INTERVAL), e -> { assignMouse(); }); // setup timerMain timerMain = new Timeline(keyFrame1); timerMain.setCycleCount(Animation.INDEFINITE); // timer for count down KeyFrame keyFrame2 = new KeyFrame(Duration.seconds(1), e -> { updateTime(); }); timerCountDown = new Timeline(keyFrame2); timerCountDown.setCycleCount(DURATION); } private void updateTime() { // update count down --timeLeft; // update lbCountDown lbCountDown.setText("" + timeLeft); // check if time is up, perform gameOver routine if yes if (timeLeft <= 0) { gameOver(); } } private void gameOver() { // disable all buttons disableButtons(); timerCountDown.stop(); timerMain.stop(); } private void disableButtons() { for (Node bn : grid.getChildren()) { bn.setDisable(true); } } private void assignMouse() { // generate two random integers (row, column) int row = (int) (Math.random() * N_ROWS); int col = (int) (Math.random() * N_COLS); // assign ivMouse to the button at (row, column) bnCurrent = buttons[row][col]; bnCurrent.setGraphic(ivMouse); } public static void main(String[] args) { launch(args); } }