package brickbreaker; import brickbreaker.Interfaces.BrickFactory; import brickbreaker.Interfaces.GameObserver; import brickbreaker.GameComponents.DefaultBrickFactory; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class GamePanel extends JPanel implements KeyListener, ActionListener { private boolean play = true; private int score = 0; private int totalBricks; private int rows = 10; private int columns = 14; private Timer timer; private int delay = 8; private int paddle = 310; private List<Ball> balls = new ArrayList<>(); // Use List interface instead of ArrayList private String font = "MV Boli"; private GameMapBuilder map; public GamePanel() { Color color = Color.decode("#8B4513"); this.balls.add(new Ball(350, 450, 2, -2, 20, color)); // Adjust the initial ball position and direction color = Color.decode("#008080"); this.balls.add(new Ball(380, 420, -2, 2, 50, color)); this.totalBricks = rows * columns; BrickFactory brickfactory = new DefaultBrickFactory(); map = new GameMapBuilder(rows, columns, brickfactory); addKeyListener(this); setFocusable(true); setFocusTraversalKeysEnabled(false); timer = new Timer(delay, this); timer.start(); } private List<GameObserver> observers = new ArrayList<>(); public void addObserver(GameObserver observer) { observers.add(observer); } public void removeObserver(GameObserver observer) { observers.remove(observer); } protected void paintComponent(Graphics graphics) { super.paintComponent(graphics); if (balls.isEmpty()) { gameOver(graphics, "Game Over", Color.BLACK); } // background color graphics.setColor(Color.green); graphics.fillRect(1, 1, 692, 592); map.draw((Graphics2D) graphics); graphics.setColor(Color.blue); graphics.fillRect(paddle, 550, 100, 20); Iterator<Ball> ballsIterator = balls.iterator(); while (ballsIterator.hasNext()) { Ball ball = ballsIterator.next(); Vector ballPosition = ball.getPosition(); if (ballPosition.y > 560) { ballsIterator.remove(); continue; } else { ball.checkForWallCollisions(); } ball.draw(graphics); } graphics.setColor(Color.black); graphics.setFont(new Font("MV Boli", Font.BOLD, 25)); graphics.drawString("Score: " + score, 520, 30); if (totalBricks <= 0) { Color color = new Color(0XFF6464); gameOver(graphics, "You Won", color); } if (balls.isEmpty()) { gameOver(graphics, "Game Over", Color.BLACK); } } public void gameOver(Graphics graphics, String gameOverText, Color color) { play = false; graphics.setColor(color); graphics.setFont(new Font(font, Font.BOLD, 30)); graphics.drawString(gameOverText + ", Your Score: " + score, 190, 300); graphics.setFont(new Font(font, Font.BOLD, 20)); graphics.drawString("Press Enter to Restart", 230, 350); } @Override public void actionPerformed(ActionEvent arg0) { if (play) { for (Ball ball : balls) { Vector ballPosition = ball.getPosition(); Vector ballDirection = ball.getDirection(); if (new Rectangle(ballPosition.x, ballPosition.y, ball.radius, ball.radius).intersects(new Rectangle(paddle, 550, 100, 8))) { ballDirection.y = -ballDirection.y; ball.setDirection(ballDirection.x, ballDirection.y); } for (int i = 0; i < map.map.length; i++) { for (int j = 0; j < map.map[0].length; j++) { if (map.map[i][j] > 0) { int brickX = j * map.brickWidth; int brickY = i * map.brickHeight; int brickWidth = map.brickWidth; int brickHeight = map.brickHeight; Rectangle brickRect = new Rectangle(brickX, brickY, brickWidth, brickHeight); Rectangle ballRect = new Rectangle(ballPosition.x, ballPosition.y, ball.radius, ball.radius); if (ballRect.intersects(brickRect)) { map.setBrickValue(0, i, j); totalBricks--; score += 5; if (ballPosition.x + 19 <= brickRect.x || ballPosition.x + 1 >= brickRect.x + brickRect.width) { ballDirection.x = -ballDirection.x; } else { ballDirection.y = -ballDirection.y; } } } } } ball.setDirection(ballDirection.x, ballDirection.y); ball.move(); // Call the move() method to update the ball's position } } repaint(); } @Override public void keyTyped(KeyEvent arg0) { } @Override public void keyPressed(KeyEvent arg0) { if (arg0.getKeyCode() == KeyEvent.VK_RIGHT) { if (paddle >= 600) { paddle = 600; } else { moveRight(); } } if (arg0.getKeyCode() == KeyEvent.VK_LEFT) { if (paddle < 10) { paddle = 10; } else { moveLeft(); } } if (arg0.getKeyCode() == KeyEvent.VK_ENTER) { if (!play) { play = true; Color color = Color.decode("#8B4513"); this.balls.add(new Ball(350, 450, 1, -1, 20, color)); // Adjust the initial ball position and direction score = 0; totalBricks = rows * columns; BrickFactory brickfactory = new DefaultBrickFactory(); map = new GameMapBuilder(rows, columns, brickfactory); repaint(); } } } public void moveRight() { play = true; paddle += 50; } public void moveLeft() { play = true; paddle -= 50; } @Override public void keyReleased(KeyEvent arg0) { } }