import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.JFrame; import javax.swing.JPanel; /** * A GUI runner for your solution to the 2025 Lab * Unit 4: 2048 * * @author Chris Thiel, OFMCap * @version July 15, 2025 * * Make sure to write a getScore() method in your Game2048 class * as well as a getGameBoard() method. Alternatively, * you can write your own draw(Graphics g) method, and call it * from this class's paintComponent method. */ public class GUI2048 extends JPanel implements KeyListener { private static int WIDTH = 800, HEIGHT = 800; private static int LEFT_ARROW = 37, UP_ARROW = 38, RIGHT_ARROW = 39, DOWN_ARROW = 40; private Font titleFont, regularFont; private int keyCode, boardSize; private int[][] board; private char c; String message; private Game2048 myGame; public GUI2048() { myGame = new Game2048(); board = myGame.getBoard(); boardSize = board.length; message = "Use arrow keys (or l, r, u, d for left, right, up, down)"; titleFont = new Font("Roman", Font.BOLD, 18); regularFont = new Font("Helvetica", Font.PLAIN, 12); keyCode=0; c='-'; } public static void main(String[] args) { GUI2048 app= new GUI2048(); JFrame window = new JFrame("2048 Game"); window.setSize(WIDTH, HEIGHT); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.getContentPane().add(app); window.addKeyListener(app); window.setVisible(true); } public void paintComponent(Graphics g){ super.paintComponent(g); g.setColor(Color.WHITE); g.fillRect(0, 0, getWidth(),getHeight()); g.setColor(Color.BLUE); g.setFont(new Font("Arial", Font.PLAIN, 48)); g.drawString("2048 Game", WIDTH/3, 40); g.setFont(titleFont); g.setColor(Color.BLACK); g.drawString("Score: " + myGame.getScore(), 4*WIDTH/5, 40); g.drawString( message , 20, WIDTH - 50); g.setFont(regularFont); g.drawString("Version 1.0", 20, 50); g.setFont(new Font("Arial", Font.PLAIN, 48)); g.setColor(Color.red); drawBoard(g); } public void drawBoard(Graphics g) { int size = HEIGHT/(boardSize +1); int top = 60; int left = WIDTH/2 - 2 * size; g.setFont(new Font("Arial", Font.BOLD, 48)); for(int r = 0; r < boardSize; r++) for(int c = 0; c < boardSize; c++) { if (board[r][c] != 0) g.drawString (""+board[r][c], left+c*size + size/3, top + r*size + 3*size/4); } g.setColor(Color.BLACK); for(int r = 0; r <= boardSize; r++) { g.drawLine(left, top + size*r, left + boardSize*size, top +size*r); } for(int c = 0; c <= boardSize; c++){ g.drawLine(left+c*size, top ,left+c*size, top + boardSize* size); } } // These 3 methods need to be declared to implement the KeyListener Interface @Override public void keyTyped(KeyEvent e) {} @Override public void keyPressed(KeyEvent e) { keyCode=e.getKeyCode(); c=e.getKeyChar(); if (keyCode == LEFT_ARROW || c == 'l') { myGame.moveLeft(); myGame.mergeLeft(); myGame.moveLeft(); message = "left"; } else if (keyCode == RIGHT_ARROW || c == 'r') { myGame.moveRight(); myGame.mergeRight(); myGame.moveRight(); message = "right"; } else if (keyCode == UP_ARROW || c == 'u') { myGame.moveUp(); myGame.mergeUp(); myGame.moveUp(); message = "up"; } else if (keyCode == DOWN_ARROW || c == 'd' ) { myGame.moveDown(); myGame.mergeDown(); myGame.moveDown(); message = "down"; } else { message = c+ " is an invalid choice!"; } if (message.length() < 6 && !myGame.gameOver()) myGame.add2ToBoard(); if (myGame.gameOver()) message = "Game Over - You reached "+ myGame.max(); repaint(); } @Override public void keyReleased(KeyEvent e) {} }