From 3484e309668b974a045b7ef86ec45e6d966fe7f0 Mon Sep 17 00:00:00 2001 From: Muna Kandel <mkandel2@myune.edu.au> Date: Thu, 21 Sep 2023 22:25:36 +0545 Subject: [PATCH] Closes #12 PowerUp implementation --- app/src/main/java/brickbreaker/App.java | 4 +- app/src/main/java/brickbreaker/Ball.java | 10 +-- .../brickbreaker/GameComponents/Brick.java | 38 ++++++++--- .../GameComponents/DefaultBrickFactory.java | 13 ++-- .../java/brickbreaker/GameMapBuilder.java | 58 +++++++--------- app/src/main/java/brickbreaker/GamePanel.java | 66 +++++++++++-------- .../brickbreaker/Interfaces/BrickFactory.java | 9 --- .../brickbreaker/Interfaces/GameObserver.java | 9 +-- .../main/java/brickbreaker/LoginFrame.java | 4 -- app/src/main/java/brickbreaker/Vector.java | 9 +-- 10 files changed, 101 insertions(+), 119 deletions(-) diff --git a/app/src/main/java/brickbreaker/App.java b/app/src/main/java/brickbreaker/App.java index a18c0a5..6282541 100644 --- a/app/src/main/java/brickbreaker/App.java +++ b/app/src/main/java/brickbreaker/App.java @@ -1,6 +1,4 @@ -/* - * This Java source file was generated by the Gradle 'init' task. - */ + package brickbreaker; import javax.swing.JFrame; diff --git a/app/src/main/java/brickbreaker/Ball.java b/app/src/main/java/brickbreaker/Ball.java index 3cc1a80..ca11a7d 100644 --- a/app/src/main/java/brickbreaker/Ball.java +++ b/app/src/main/java/brickbreaker/Ball.java @@ -1,23 +1,15 @@ -/* - * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license - * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template - */ package brickbreaker; import java.awt.Color; import java.awt.Graphics; -/** - * - * @author Suman - */ public class Ball { private Vector position; private Vector direction; public int radius; public Color color; - public Ball(int posX, int posY, int dirX, int dirY, int radius,Color color) { + public Ball(int posX, int posY, int dirX, int dirY, int radius, Color color) { this.position = new Vector(posX, posY); this.direction = new Vector(dirX, dirY); this.radius = radius; diff --git a/app/src/main/java/brickbreaker/GameComponents/Brick.java b/app/src/main/java/brickbreaker/GameComponents/Brick.java index 5c03328..f03fe10 100644 --- a/app/src/main/java/brickbreaker/GameComponents/Brick.java +++ b/app/src/main/java/brickbreaker/GameComponents/Brick.java @@ -1,23 +1,18 @@ -/* - * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license - * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template - */ + package brickbreaker.GameComponents; import brickbreaker.Vector; import java.awt.Color; import java.awt.Graphics2D; -/** - * - * @author Suman - */ public class Brick { private Vector position; private int width; private int height; private Color color; - private Boolean hasPowerUp; + public Boolean hasPowerUp; + private final int value = 5; + private boolean isHit = false; public Brick(int x, int y, int width, int height, Color color, Boolean hasPowerUp) { this.position = new Vector(x, y); @@ -34,4 +29,29 @@ public class Brick { g.setColor(Color.BLACK); g.drawRect(this.position.x, this.position.y, width, height); } + + public void setIsHit(boolean isHit) { + this.isHit = isHit; + } + + public boolean getIsHit() { + return isHit; + } + + + public int getValue() { + return value; + } + + public Vector getPosition() { + return position; + } + + public int getHeight() { + return height; + } + + public int getWidth() { + return width; + } } diff --git a/app/src/main/java/brickbreaker/GameComponents/DefaultBrickFactory.java b/app/src/main/java/brickbreaker/GameComponents/DefaultBrickFactory.java index a086497..d8f5d83 100644 --- a/app/src/main/java/brickbreaker/GameComponents/DefaultBrickFactory.java +++ b/app/src/main/java/brickbreaker/GameComponents/DefaultBrickFactory.java @@ -1,21 +1,16 @@ -/* - * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license - * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template - */ + package brickbreaker.GameComponents; import brickbreaker.GameComponents.Brick; import brickbreaker.Interfaces.BrickFactory; import java.awt.Color; -/** - * - * @author Suman - */ public class DefaultBrickFactory implements BrickFactory { @Override public Brick createBrick(int x, int y, int width, int height, Boolean hasPowerUp) { - Color color = Color.decode("#FF0000"); + Color color = Color.decode("#BC4A3C"); + if(hasPowerUp) + color = Color.decode("#FF0000"); return new Brick(x, y, width, height, color, hasPowerUp); } } \ No newline at end of file diff --git a/app/src/main/java/brickbreaker/GameMapBuilder.java b/app/src/main/java/brickbreaker/GameMapBuilder.java index 3b6562e..8d59cc6 100644 --- a/app/src/main/java/brickbreaker/GameMapBuilder.java +++ b/app/src/main/java/brickbreaker/GameMapBuilder.java @@ -1,62 +1,52 @@ -/* - * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license - * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template - */ + package brickbreaker; import brickbreaker.GameComponents.Brick; import brickbreaker.Interfaces.BrickFactory; -import java.awt.BasicStroke; -import java.awt.Color; import java.awt.Graphics2D; -/** - * - * @author Suman - */ public class GameMapBuilder { - public int map [][]; - public int brickWidth; - public int brickHeight; + public Brick map [][]; + public int brickWidth = 50; + public int brickHeight = 20; private BrickFactory brickfactory; - private final int maxNoOfPowerUps = 5; - // this creates the brick of size 4x8 + private final int maxNoOfPowerUpsPerRow = 5; + public GameMapBuilder(int row, int col, BrickFactory brickFactory) { - map = new int [row][col]; + map = new Brick [row][col]; + this.brickfactory = brickFactory; + for (int i = 0; i < map.length; i++) { + int numberOfPowerUps = (int) (Math.random() * maxNoOfPowerUpsPerRow ); for (int j=0; j< map[0].length;j++) { - map[i][j] = 1; + + boolean hasPowerUp = false; + if(numberOfPowerUps > 0) { + hasPowerUp = Math.random() < 0.5; + } + if(hasPowerUp) { + numberOfPowerUps--; + } + Brick brick = brickfactory.createBrick(j*brickWidth, i*brickHeight, brickWidth, brickHeight, hasPowerUp); + + map[i][j] = brick; } } - brickWidth = 50; - brickHeight = 20; - this.brickfactory = brickFactory; + } // this draws the bricks public void draw(Graphics2D g) { - int numberOfPowerUps = (int) (Math.random() * maxNoOfPowerUps ); for (int i = 0; i < map.length; i++) { for (int j=0; j< map[0].length;j++) { - if(map[i][j] > 0) { - - boolean hasPowerUp = false; - if(numberOfPowerUps > 0) { - hasPowerUp = Math.random() < 0.5; - } - if(hasPowerUp) numberOfPowerUps--; - Brick brick = brickfactory.createBrick(j*brickWidth, i*brickHeight, brickWidth, brickHeight, hasPowerUp); + Brick brick = map[i][j]; + if(!brick.getIsHit()) { brick.draw(g); } } } } - - // this sets the value of brick to 0 if it is hit by the ball - public void setBrickValue(int value, int row, int col) { - map[row][col] = value; - } } \ No newline at end of file diff --git a/app/src/main/java/brickbreaker/GamePanel.java b/app/src/main/java/brickbreaker/GamePanel.java index 9dc12ee..d9dfc07 100644 --- a/app/src/main/java/brickbreaker/GamePanel.java +++ b/app/src/main/java/brickbreaker/GamePanel.java @@ -1,5 +1,6 @@ package brickbreaker; +import brickbreaker.GameComponents.Brick; import brickbreaker.Interfaces.BrickFactory; import brickbreaker.Interfaces.GameObserver; import brickbreaker.GameComponents.DefaultBrickFactory; @@ -26,21 +27,18 @@ public class GamePanel extends JPanel implements KeyListener, ActionListener { private int paddle = 310; - private List<Ball> balls = new ArrayList<>(); // Use List interface instead of ArrayList - + private List<Ball> balls = new ArrayList<>(); private String font = "MV Boli"; - private GameMapBuilder map; + private GameMapBuilder gameMap; 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.balls.add(new Ball(350, 450, 2, -2, 20, color)); this.totalBricks = rows * columns; BrickFactory brickfactory = new DefaultBrickFactory(); - map = new GameMapBuilder(rows, columns, brickfactory); + gameMap = new GameMapBuilder(rows, columns, brickfactory); addKeyListener(this); setFocusable(true); setFocusTraversalKeysEnabled(false); @@ -67,7 +65,7 @@ public class GamePanel extends JPanel implements KeyListener, ActionListener { graphics.setColor(Color.green); graphics.fillRect(1, 1, 692, 592); - map.draw((Graphics2D) graphics); + gameMap.draw((Graphics2D) graphics); graphics.setColor(Color.blue); @@ -117,7 +115,10 @@ public class GamePanel extends JPanel implements KeyListener, ActionListener { @Override public void actionPerformed(ActionEvent arg0) { if (play) { - for (Ball ball : balls) { + Iterator<Ball> iterator = balls.iterator(); + List<Ball> newBallsToAdd = new ArrayList<>(); + while (iterator.hasNext()) { + Ball ball = iterator.next(); Vector ballPosition = ball.getPosition(); Vector ballDirection = ball.getDirection(); @@ -126,23 +127,34 @@ public class GamePanel extends JPanel implements KeyListener, ActionListener { 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); - + for (int i = 0; i < gameMap.map.length; i++) { + for (int j = 0; j < gameMap.map[0].length; j++) { + Brick brick = gameMap.map[i][j]; + if (!brick.getIsHit()) { + Vector brickPosition = brick.getPosition(); + Rectangle brickRect = new Rectangle(brickPosition.x, brickPosition.y, brick.getWidth(), brick.getHeight()); + Rectangle ballRect = new Rectangle(ballPosition.x, ballPosition.y, ball.radius, ball.radius); + if (ballRect.intersects(brickRect)) { - map.setBrickValue(0, i, j); + brick.setIsHit(true); totalBricks--; - score += 5; - + score += brick.getValue(); + + if(brick.hasPowerUp) { + int noOfBallsToSpawn = (int) (Math.random() * 5); + System.out.println(noOfBallsToSpawn); + for (int k=0; k<noOfBallsToSpawn; k++) { + boolean positiveXDirection = Math.random() > 0.5; + boolean positiveYDirection = Math.random() > 0.5; + int dirX = (positiveXDirection)? 1: -1; + int dirY = (positiveYDirection)? 1: -1; + Color color = Color.GRAY; + Ball newBall = new Ball(brickPosition.x, brickPosition.y, dirX, dirY, ball.radius, color); + newBallsToAdd.add(newBall); + } + } + if (ballPosition.x + 19 <= brickRect.x || ballPosition.x + 1 >= brickRect.x + brickRect.width) { ballDirection.x = -ballDirection.x; } else { @@ -153,8 +165,9 @@ public class GamePanel extends JPanel implements KeyListener, ActionListener { } } ball.setDirection(ballDirection.x, ballDirection.y); - ball.move(); // Call the move() method to update the ball's position + ball.move(); } + balls.addAll(newBallsToAdd); } repaint(); @@ -185,11 +198,12 @@ public class GamePanel extends JPanel implements KeyListener, ActionListener { 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 + this.balls.clear(); + this.balls.add(new Ball(350, 450, 2, -2, 20, color)); score = 0; totalBricks = rows * columns; BrickFactory brickfactory = new DefaultBrickFactory(); - map = new GameMapBuilder(rows, columns, brickfactory); + gameMap = new GameMapBuilder(rows, columns, brickfactory); repaint(); } diff --git a/app/src/main/java/brickbreaker/Interfaces/BrickFactory.java b/app/src/main/java/brickbreaker/Interfaces/BrickFactory.java index ba3cedf..bffec1d 100644 --- a/app/src/main/java/brickbreaker/Interfaces/BrickFactory.java +++ b/app/src/main/java/brickbreaker/Interfaces/BrickFactory.java @@ -1,16 +1,7 @@ -/* - * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license - * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Interface.java to edit this template - */ package brickbreaker.Interfaces; import brickbreaker.GameComponents.Brick; -import java.awt.Color; -/** - * - * @author Suman - */ public interface BrickFactory { Brick createBrick(int x, int y, int width, int height, Boolean hasPowerup); } diff --git a/app/src/main/java/brickbreaker/Interfaces/GameObserver.java b/app/src/main/java/brickbreaker/Interfaces/GameObserver.java index e30d97e..6e16d2f 100644 --- a/app/src/main/java/brickbreaker/Interfaces/GameObserver.java +++ b/app/src/main/java/brickbreaker/Interfaces/GameObserver.java @@ -1,13 +1,6 @@ -/* - * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license - * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Interface.java to edit this template - */ + package brickbreaker.Interfaces; -/** - * - * @author Suman - */ public interface GameObserver { void onGameOver(int finalScore); void onGameWin(int finalScore); diff --git a/app/src/main/java/brickbreaker/LoginFrame.java b/app/src/main/java/brickbreaker/LoginFrame.java index 4dd910a..23414da 100644 --- a/app/src/main/java/brickbreaker/LoginFrame.java +++ b/app/src/main/java/brickbreaker/LoginFrame.java @@ -1,9 +1,5 @@ package brickbreaker; -/** - * - * @author Suman - */ import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; diff --git a/app/src/main/java/brickbreaker/Vector.java b/app/src/main/java/brickbreaker/Vector.java index 258cb98..bf8bcda 100644 --- a/app/src/main/java/brickbreaker/Vector.java +++ b/app/src/main/java/brickbreaker/Vector.java @@ -1,13 +1,6 @@ -/* - * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license - * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template - */ + package brickbreaker; -/** - * - * @author Suman - */ public class Vector { public int x; public int y; -- GitLab