Skip to content
Snippets Groups Projects
Commit 8802ebfb authored by mkandel2's avatar mkandel2
Browse files

Merge branch 'gameGraphics' into 'master'

Game graphics

Closes #11

See merge request !1
parents 80adfca5 fd9e8956
No related branches found
No related tags found
1 merge request!1Game graphics
/*
* 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) {
this.position = new Vector(posX, posY);
this.direction = new Vector(dirX, dirY);
this.radius = radius;
this.color = color;
}
public void setPosition(int posX, int posY) {
this.position = new Vector(posX, posY);
}
public void setDirection(int dirX, int dirY) {
this.direction = new Vector(dirX, dirY);
}
public Vector getPosition() {
return this.position;
}
public Vector getDirection() {
return this.direction;
}
public void move(){
position.x += direction.x;
position.y += direction.y;
}
public void checkForWallCollisions() {
if (position.x <= 0) { // Left wall collision
position.x = 0; // Set the ball at the left edge
direction.x = Math.abs(direction.x); // Reverse the x direction
}
if (position.x + radius >= 680) { // Right wall collision
position.x = 680 - radius; // Set the ball at the right edge
direction.x = -Math.abs(direction.x); // Reverse the x direction
}
if (position.y <= 0) { // Top wall collision
position.y = 0; // Set the ball at the top edge
direction.y = Math.abs(direction.y); // Reverse the y direction
}
}
public void draw(Graphics graphics) {
graphics.setColor(this.color); // ball color
graphics.fillOval(position.x, position.y, radius, radius);
}
}
/*
* 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 Brick(int x, int y, int width, int height, Color color, Boolean hasPowerUp) {
this.position = new Vector(x, y);
this.width = width;
this.height = height;
this.color = color;
this.hasPowerUp = hasPowerUp;
}
public void draw(Graphics2D g) {
g.setColor(this.color); // brick color
g.fillRect(this.position.x, this.position.y, width, height);
g.setColor(Color.BLACK);
g.drawRect(this.position.x, this.position.y, width, height);
}
}
/*
* 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");
return new Brick(x, y, width, height, color, hasPowerUp);
}
}
\ No newline at end of file
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
*/ */
package brickbreaker; package brickbreaker;
import brickbreaker.GameComponents.Brick;
import brickbreaker.Interfaces.BrickFactory;
import java.awt.BasicStroke; import java.awt.BasicStroke;
import java.awt.Color; import java.awt.Color;
import java.awt.Graphics2D; import java.awt.Graphics2D;
...@@ -12,39 +14,43 @@ import java.awt.Graphics2D; ...@@ -12,39 +14,43 @@ import java.awt.Graphics2D;
* *
* @author Suman * @author Suman
*/ */
class GameMapBuilder { public class GameMapBuilder {
public int map [][]; public int map [][];
public int brickWidth; public int brickWidth;
public int brickHeight; public int brickHeight;
private BrickFactory brickfactory;
private final int maxNoOfPowerUps = 5;
// this creates the brick of size 4x8 // this creates the brick of size 4x8
public GameMapBuilder(int row, int col) { public GameMapBuilder(int row, int col, BrickFactory brickFactory) {
map = new int [row][col]; map = new int [row][col];
for (int i = 0; i < map.length; i++) { for (int i = 0; i < map.length; i++) {
for (int j=0; j< map[0].length;j++) { for (int j=0; j< map[0].length;j++) {
map[i][j] = 1; map[i][j] = 1;
} }
} }
brickWidth = 50;
brickWidth = 540/col; brickHeight = 20;
brickHeight = 150/row; this.brickfactory = brickFactory;
} }
// this draws the bricks // this draws the bricks
public void draw(Graphics2D g) { public void draw(Graphics2D g) {
int numberOfPowerUps = (int) (Math.random() * maxNoOfPowerUps );
for (int i = 0; i < map.length; i++) { for (int i = 0; i < map.length; i++) {
for (int j=0; j< map[0].length;j++) { for (int j=0; j< map[0].length;j++) {
if(map[i][j] > 0) { if(map[i][j] > 0) {
g.setColor(new Color(0XFF8787)); // brick color
g.fillRect(j*brickWidth + 80, i*brickHeight + 50, brickWidth, brickHeight);
g.setStroke(new BasicStroke(4)); boolean hasPowerUp = false;
g.setColor(Color.BLACK); if(numberOfPowerUps > 0) {
g.drawRect(j*brickWidth + 80, i*brickHeight + 50, brickWidth, brickHeight); hasPowerUp = Math.random() < 0.5;
}
if(hasPowerUp) numberOfPowerUps--;
Brick brick = brickfactory.createBrick(j*brickWidth, i*brickHeight, brickWidth, brickHeight, hasPowerUp);
brick.draw(g);
} }
} }
} }
} }
......
package brickbreaker; package brickbreaker;
import brickbreaker.Interfaces.BrickFactory;
import brickbreaker.Interfaces.GameObserver;
import brickbreaker.GameComponents.DefaultBrickFactory;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.KeyListener; 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 { public class GamePanel extends JPanel implements KeyListener, ActionListener {
private boolean play = true; private boolean play = true;
private int score = 0; private int score = 0;
private int totalBricks = 21; private int totalBricks;
private int rows = 10;
private int columns = 14;
private Timer timer; private Timer timer;
private int delay = 8; private int delay = 8;
private int playerX = 310; private int paddle = 310;
private List<Ball> balls = new ArrayList<>(); // Use List interface instead of ArrayList
private Vector ballPosition;
private Vector ballDirection;
private String font = "MV Boli"; private String font = "MV Boli";
private GameMapBuilder map; private GameMapBuilder map;
public GamePanel() { public GamePanel() {
this.ballPosition = new Vector(120, 350); Color color = Color.decode("#8B4513");
this.ballDirection = new Vector(-1, -2); this.balls.add(new Ball(350, 450, 2, -2, 20, color)); // Adjust the initial ball position and direction
color = Color.decode("#008080");
map = new GameMapBuilder(4, 8); 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); addKeyListener(this);
setFocusable(true); setFocusable(true);
setFocusTraversalKeysEnabled(false); setFocusTraversalKeysEnabled(false);
...@@ -36,45 +48,64 @@ public class GamePanel extends JPanel implements KeyListener, ActionListener { ...@@ -36,45 +48,64 @@ public class GamePanel extends JPanel implements KeyListener, ActionListener {
timer.start(); 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) { protected void paintComponent(Graphics graphics) {
super.paintComponent(graphics); super.paintComponent(graphics);
if (balls.isEmpty()) {
gameOver(graphics, "Game Over", Color.BLACK);
}
// background color // background color
graphics.setColor(Color.green); graphics.setColor(Color.green);
graphics.fillRect(1, 1, 692, 592); graphics.fillRect(1, 1, 692, 592);
map.draw((Graphics2D) graphics); map.draw((Graphics2D) graphics);
graphics.fillRect(0, 0, 3, 592);
graphics.fillRect(0, 0, 692, 3);
graphics.fillRect(691, 0, 3, 592);
graphics.setColor(Color.blue); graphics.setColor(Color.blue);
graphics.fillRect(playerX, 550, 100, 12); graphics.fillRect(paddle, 550, 100, 20);
graphics.setColor(Color.RED); // ball color Iterator<Ball> ballsIterator = balls.iterator();
graphics.fillOval(ballPosition.x, ballPosition.y, 20, 20);
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.setColor(Color.black);
graphics.setFont(new Font("MV Boli", Font.BOLD, 25)); graphics.setFont(new Font("MV Boli", Font.BOLD, 25));
graphics.drawString("Score: " + score, 520, 30); graphics.drawString("Score: " + score, 520, 30);
if (totalBricks <= 0) { // if all bricks are destroyed then you win if (totalBricks <= 0) {
Color color = new Color(0XFF6464); Color color = new Color(0XFF6464);
gameOver(graphics, "You Won", color); gameOver(graphics, "You Won", color);
} }
if (ballPosition.y > 570) { // if ball goes below the paddle then you lose if (balls.isEmpty()) {
gameOver(graphics, "Game Over", Color.BLACK); gameOver(graphics, "Game Over", Color.BLACK);
} }
} }
public void gameOver(Graphics graphics, String gameOverText, Color color) { public void gameOver(Graphics graphics, String gameOverText, Color color) {
play = false; play = false;
ballDirection.x = 0;
ballDirection.y = 0;
graphics.setColor(color); graphics.setColor(color);
graphics.setFont(new Font(font, Font.BOLD, 30)); graphics.setFont(new Font(font, Font.BOLD, 30));
graphics.drawString(gameOverText + ", Your Score: " + score, 190, 300); graphics.drawString(gameOverText + ", Your Score: " + score, 190, 300);
...@@ -86,51 +117,44 @@ public class GamePanel extends JPanel implements KeyListener, ActionListener { ...@@ -86,51 +117,44 @@ public class GamePanel extends JPanel implements KeyListener, ActionListener {
@Override @Override
public void actionPerformed(ActionEvent arg0) { public void actionPerformed(ActionEvent arg0) {
if (play) { if (play) {
// Ball - Pedal interaction for (Ball ball : balls) {
if (new Rectangle(ballPosition.x, ballPosition.y, 20, 20).intersects(new Rectangle(playerX, 550, 100, 8))) { 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; ballDirection.y = -ballDirection.y;
ball.setDirection(ballDirection.x, ballDirection.y);
} }
for (int i = 0; i < map.map.length; i++) { // Ball - Brick interaction
for (int j = 0; j < map.map[0].length; j++) { // map.map[0].length is the number of columns 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) { if (map.map[i][j] > 0) {
int brickX = j * map.brickWidth + 80; int brickX = j * map.brickWidth;
int brickY = i * map.brickHeight + 50; int brickY = i * map.brickHeight;
int brickWidth = map.brickWidth; int brickWidth = map.brickWidth;
int brickHeight = map.brickHeight; int brickHeight = map.brickHeight;
Rectangle rect = new Rectangle(brickX, brickY, brickWidth, brickHeight); Rectangle brickRect = new Rectangle(brickX, brickY, brickWidth, brickHeight);
Rectangle ballRect = new Rectangle(ballPosition.x, ballPosition.y, 20, 20); Rectangle ballRect = new Rectangle(ballPosition.x, ballPosition.y, ball.radius, ball.radius);
Rectangle brickRect = rect;
if (ballRect.intersects(brickRect)) { if (ballRect.intersects(brickRect)) {
map.setBrickValue(0, i, j); map.setBrickValue(0, i, j);
totalBricks--; totalBricks--;
score += 5; score += 5;
if (ballPosition.x + 19 <= brickRect.x || ballPosition.x + 1 >= brickRect.x + brickRect.width) if (ballPosition.x + 19 <= brickRect.x || ballPosition.x + 1 >= brickRect.x + brickRect.width) {
ballDirection.x = -ballDirection.x; ballDirection.x = -ballDirection.x;
else { } else {
ballDirection.y = -ballDirection.y; ballDirection.y = -ballDirection.y;
} }
} }
} }
}
}
ballPosition.x += ballDirection.x;
ballPosition.y += ballDirection.y;
if (ballPosition.x < 0) { // if ball hits the left wall then it bounces back
ballDirection.x = -ballDirection.x;
} }
if (ballPosition.y < 0) { // if ball hits the top wall then it bounces back
ballDirection.y = -ballDirection.y;
} }
if (ballPosition.x > 670) { // if ball hits the right wall then it bounces back ball.setDirection(ballDirection.x, ballDirection.y);
ballDirection.x = -ballDirection.x; ball.move(); // Call the move() method to update the ball's position
} }
} }
repaint(); repaint();
...@@ -138,57 +162,51 @@ public class GamePanel extends JPanel implements KeyListener, ActionListener { ...@@ -138,57 +162,51 @@ public class GamePanel extends JPanel implements KeyListener, ActionListener {
@Override @Override
public void keyTyped(KeyEvent arg0) { public void keyTyped(KeyEvent arg0) {
} }
@Override @Override
public void keyPressed(KeyEvent arg0) { public void keyPressed(KeyEvent arg0) {
if (arg0.getKeyCode() == KeyEvent.VK_RIGHT) { // if right arrow key is pressed then paddle moves right if (arg0.getKeyCode() == KeyEvent.VK_RIGHT) {
if (playerX >= 600) { if (paddle >= 600) {
playerX = 600; paddle = 600;
} else { } else {
moveRight(); moveRight();
} }
} }
if (arg0.getKeyCode() == KeyEvent.VK_LEFT) { // if left arrow key is pressed then paddle moves left if (arg0.getKeyCode() == KeyEvent.VK_LEFT) {
if (playerX < 10) { if (paddle < 10) {
playerX = 10; paddle = 10;
} else { } else {
moveLeft(); moveLeft();
} }
} }
if (arg0.getKeyCode() == KeyEvent.VK_ENTER) { // if enter key is pressed then game restarts if (arg0.getKeyCode() == KeyEvent.VK_ENTER) {
if (!play) { if (!play) {
play = true; play = true;
ballPosition.x = 120; Color color = Color.decode("#8B4513");
ballPosition.y = 350; this.balls.add(new Ball(350, 450, 1, -1, 20, color)); // Adjust the initial ball position and direction
ballDirection.x = -1;
ballDirection.y = -2;
score = 0; score = 0;
totalBricks = 21; totalBricks = rows * columns;
map = new GameMapBuilder(7, 8); BrickFactory brickfactory = new DefaultBrickFactory();
map = new GameMapBuilder(rows, columns, brickfactory);
repaint(); repaint();
} }
} }
} }
public void moveRight() { // paddle moves right by 50 pixels public void moveRight() {
play = true; play = true;
playerX += 50; paddle += 50;
} }
public void moveLeft() { // paddle moves left by 50 pixels public void moveLeft() {
play = true; play = true;
playerX -= 50; paddle -= 50;
} }
@Override @Override
public void keyReleased(KeyEvent arg0) { public void keyReleased(KeyEvent arg0) {
} }
} }
/*
* 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);
}
/*
* 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);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment