0% found this document useful (0 votes)
3 views18 pages

Report Oop

The document outlines a project for a 2D Space Shooter game developed in Java as part of a course at Bahria University. It details the game's mechanics, including player controls, scoring system, and object-oriented programming concepts utilized in the development. The project also includes a UML class diagram and code snippets demonstrating key functionalities such as collision detection and high score management.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views18 pages

Report Oop

The document outlines a project for a 2D Space Shooter game developed in Java as part of a course at Bahria University. It details the game's mechanics, including player controls, scoring system, and object-oriented programming concepts utilized in the development. The project also includes a UML class diagram and code snippets demonstrating key functionalities such as collision detection and high score management.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 18

Bahria University,

Karachi Campus

COURSE: CSL-210 OBJECT ORIENTED PROGRAMMING


TERM: SPRING 2025, CLASS: BSE- 2 (C)
PROJECT NAME

2D Space Shooter with Java JDK

Submitted By:

S.NO Student Name Enrollment #


01 Mishal Rehman 02-131242-034
02 Hamza Mairaj 02-131242-021
03 Hassnain Daud 02-131242-058
04 Mehwish 02-131242-001

Submitted to:

Engr.Muhammad Faisal/ Engr. Saniya Sarim


Signed Remarks: Score:

Table of Contents
INTRODUCTION:............................................................................................................................................................3
OOP CONCEPTS USED IN PROJECT:...............................................................................................................................3
UML CLASS DIAGRAM...................................................................................................................................................4
FEATURES OF YOUR PROJECT:.......................................................................................................................................4
CODE:............................................................................................................................................................................ 4
INTERFACES:................................................................................................................................................................18
CONCLUSION:..............................................................................................................................................................19
INTRODUCTION:
This project is a simple 2D shooting game developed in Java using the Swing framework.
The player controls a plane that can move in all four directions and shoot bullets to
destroy falling enemy rockets. The game combines basic object oriented programming
concepts with graphical rendering and real time interaction, making it an excellent
beginner friendly project for understanding Java game development.

The objective of the game is to score as many points as possible by shooting down enemy
rockets before they reach the bottom of the screen or collide with the player's plane. Each
successful hit increases the player's score. The game also maintains a high score, which is
stored locally using file I/O operations, allowing the player to track their best

This game demonstrates fundamental game programming concepts such as animation


using a game loop, collision detection, keyboard event handling, score tracking, and basic
file operations. It offers an interactive and engaging way to apply core Java skills in a fun
and creative context.
OOP CONCEPTS USED IN PROJECT:

 Encapsulation
 Inheritance
 Polymorphism
 Abstraction
 Object Composition

UML CLASS DIAGRAM


FEATURES OF YOUR PROJECT:

 Player controlled aircraft with rotation and movement.

 Bullet firing system with multiple bullet types (J and K keys).

 Incoming enemy rockets from both sides.

 Collision detection between bullets, rockets, and player.

 Health points (HP) system for player and rockets.

 Explosion effects using particle-style animations.

 Real time score tracking.

 High score saving and loading mechanism.

 Sound effects for shooting, hitting, and destruction.

 Game Over screen with restart option via Enter key.

 Keyboard controls using KeyListener.

 Game loop managed with separate threads for rendering and updates.

CODE: package game.component;


public class Key {
GAME.COMPNENT: public boolean isKey_enter() {
return key_enter;
HIGH SCORE:
}
package game.component;
public void setKey_enter(boolean key_enter) {
import java.io.*;
this.key_enter = key_enter;
class HighScoreManager {
}
private static final String FILE_NAME =
public boolean isKey_right() {
"highscore.txt";
return key_right;
public static void saveHighScore(int score) {
}
try (FileWriter writer = new
public void setKey_right(boolean key_right) {
FileWriter(FILE_NAME)) {
this.key_right = key_right;
writer.write(String.valueOf(score));
}
} catch (IOException e) {
public boolean isKey_left() {
e.printStackTrace();
return key_left;
}}
}
public static int loadHighScore() {
public void setKey_left(boolean key_left) {
try (BufferedReader reader = new
this.key_left = key_left;
BufferedReader(new FileReader(FILE_NAME))) {
}
return Integer.parseInt(reader.readLine());
public boolean isKey_space() {
} catch (IOException | NumberFormatException e) {
return key_space;
return 0; // If file not found or invalid format
}
}}}
public void setKey_space(boolean key_space) {
KEY:
this.key_space = key_space; private boolean start = true;
} private Key key;
public boolean isKey_j() { private int shotTime;
return key_j; private int highScore;
} // Game FPS
public void setKey_j(boolean key_j) { private final int FPS = 60;
this.key_j = key_j; private final int TARGET_TIME = 1000000000 /
} FPS;
public boolean isKey_k() { // Game Object
return key_k; private Sound sound;
} private Player player;
public void setKey_k(boolean key_k) { private List<Bullet> bullets;
this.key_k = key_k; private List<Rocket> rockets;
} private List<Effect> boomEffects;
private boolean key_right; private HighScoreManager highScoreManager;
private boolean key_left; private int score = 0;
private boolean key_space; public void start() {
private boolean key_j; width = getWidth();
private boolean key_k; height = getHeight();
private boolean key_enter; highScore = HighScoreManager.loadHighScore();
} image = new BufferedImage(width, height,
PANELGAME: BufferedImage.TYPE_INT_ARGB);
package game.component; g2 = image.createGraphics();
import game.obj.Bullet;
import game.obj.Effect; g2.setRenderingHint(RenderingHints.KEY_ANTIALIA
import game.obj.Player; SING, RenderingHints.VALUE_ANTIALIAS_ON);
import game.obj.Rocket;
import game.obj.sound.Sound; g2.setRenderingHint(RenderingHints.KEY_INTERPOL
import java.awt.Color; ATION,
import java.awt.Font; RenderingHints.VALUE_INTERPOLATION_BILINE
import java.awt.FontMetrics; AR);
import java.awt.Graphics; thread = new Thread(new Runnable() {
import java.awt.Graphics2D; @Override
import java.awt.RenderingHints; public void run() {
import java.awt.event.KeyAdapter; while (start) {
import java.awt.event.KeyEvent; long startTime = System.nanoTime();
import java.awt.geom.Area; drawBackground();
import java.awt.geom.Rectangle2D; drawGame();
import java.awt.image.BufferedImage; render();
import java.util.ArrayList; long time = System.nanoTime() - startTime;
import java.util.List; if (time < TARGET_TIME) {
import java.util.Random; long sleep = (TARGET_TIME - time) / 1000000;
import javax.swing.JComponent; sleep(sleep);
public class PanelGame extends JComponent { }}} });
private Graphics2D g2; initObjectGame();
private BufferedImage image; initKeyboard();
private int width; initBullets();
private int height; thread.start();
private Thread thread; }
private void addRocket() { key.setKey_j(true);
Random ran = new Random(); } else if (e.getKeyCode() ==
int locationY = ran.nextInt(height - 50) + 25; KeyEvent.VK_K) {
Rocket rocket = new Rocket(); key.setKey_k(true);
rocket.changeLocation(0, locationY); } else if (e.getKeyCode() ==
rocket.changeAngle(0); KeyEvent.VK_ENTER) {
rockets.add(rocket); key.setKey_enter(true);
int locationY2 = ran.nextInt(height - 50) + 25; }
Rocket rocket2 = new Rocket(); }
rocket2.changeLocation(width, locationY2); @Override
rocket2.changeAngle(180); public void keyReleased(KeyEvent e) {
rockets.add(rocket2); if (e.getKeyCode() == KeyEvent.VK_A) {
} key.setKey_left(false);
private void initObjectGame() { } else if (e.getKeyCode() ==
sound=new Sound(); KeyEvent.VK_D) {
player = new Player(); key.setKey_right(false);
player.changeLocation(150, 150); } else if (e.getKeyCode() ==
rockets = new ArrayList<>(); KeyEvent.VK_SPACE) {
boomEffects = new ArrayList<>(); key.setKey_space(false);
new Thread(new Runnable() { } else if (e.getKeyCode() == KeyEvent.VK_J) {
@Override key.setKey_j(false);
public void run() { } else if (e.getKeyCode() ==
while (start) { KeyEvent.VK_K) {
addRocket(); key.setKey_k(false);
sleep(3000); } else if (e.getKeyCode() ==
} } }).start(); } KeyEvent.VK_ENTER) {
private void resetGame() { key.setKey_enter(false);
score = 0; } } });
rockets.clear(); new Thread(new Runnable() {
bullets.clear(); @Override
player.changeLocation(150, 150); public void run() {
player.reset(); float s = 0.5f;
} while (start) {
private void initKeyboard() { if (player.isAlive()) {
key = new Key(); float angle = player.getAngle();
requestFocus(); if (key.isKey_left()) {
addKeyListener(new KeyAdapter() { angle -= s;
@Override }
public void keyPressed(KeyEvent e) { if (key.isKey_right()) {
if (e.getKeyCode() == KeyEvent.VK_A) { angle += s;
key.setKey_left(true); }
} else if (e.getKeyCode() == if (key.isKey_j() || key.isKey_k()) {
KeyEvent.VK_D) { if (shotTime == 0) {
key.setKey_right(true); if (key.isKey_j()) {
} else if (e.getKeyCode() == bullets.add(0, new Bullet(player.getX(),
KeyEvent.VK_SPACE) { player.getY(), player.getAngle(), 5, 3f));
key.setKey_space(true); } else {
} else if (e.getKeyCode() == KeyEvent.VK_J) bullets.add(0, new Bullet(player.getX(),
{ player.getY(), player.getAngle(), 20, 3f));
} for (int i = 0; i < boomEffects.size(); i++) {
sound.soundShoot(); Effect boomEffect = boomEffects.get(i);
} if (boomEffect != null) {
shotTime++; boomEffect.update();
if (shotTime == 15) { if (!boomEffect.check()) {
shotTime = 0; boomEffects.remove(boomEffect);
} }
} else { } else {
shotTime = 0; boomEffects.remove(boomEffect);
} }
if (key.isKey_space()) { }
player.speedUp(); sleep(1); } } }).start(); }
} else { private void checkBullets(Bullet bullet) {
player.speedDown(); for (int i = 0; i < rockets.size(); i++) {
} Rocket rocket = rockets.get(i);
player.update(); if (rocket != null) {
player.changeAngle(angle); Area area = new Area(bullet.getShape());
} else { area.intersect(rocket.getShape());
if (key.isKey_enter()) { if (!area.isEmpty()) {
resetGame(); boomEffects.add(new Effect(bullet.getCenterX(),
} bullet.getCenterY(), 3, 5, 60, 0.5f, new Color(230, 207,
} 105)));
for (int i = 0; i < rockets.size(); i++) { if (!rocket.updateHP(bullet.getSize())) {
Rocket rocket = rockets.get(i); score++;
if (rocket != null) { rockets.remove(rocket);
rocket.update(); sound.soundDestroy();
if (!rocket.check(width, height)) { double x = rocket.getX() +
rockets.remove(rocket); Rocket.ROCKET_SIZE / 2;
} else { double y = rocket.getY() +
if (player.isAlive()) { Rocket.ROCKET_SIZE / 2;
checkPlayer(rocket); boomEffects.add(new Effect(x, y, 5, 5,
} } } } sleep(5); } } }).start();} 75, 0.05f, new Color(32, 178, 169)));
private void initBullets() { boomEffects.add(new Effect(x, y, 5, 5,
bullets = new ArrayList<>(); 75, 0.1f, new Color(32, 178, 169)));
new Thread(new Runnable() { boomEffects.add(new Effect(x, y, 10, 10,
@Override 100, 0.3f, new Color(230, 207, 105)));
public void run() { boomEffects.add(new Effect(x, y, 10, 5,
while (start) { 100, 0.5f, new Color(255, 70, 70)));
for (int i = 0; i < bullets.size(); i++) { boomEffects.add(new Effect(x, y, 10, 5,
Bullet bullet = bullets.get(i); 150, 0.2f, new Color(255, 255, 255)));
if (bullet != null) { } else {
bullet.update(); sound.soundHit();
checkBullets(bullet); }
if (!bullet.check(width, height)) { bullets.remove(bullet);
bullets.remove(bullet); } } }}
} private void checkPlayer(Rocket rocket) {
} else { if (rocket != null) {
bullets.remove(bullet); Area area = new Area(player.getShape());
}} area.intersect(rocket.getShape());
if (!area.isEmpty()) { boomEffects.add(new Effect(x, y, 5, 5, 75,
double rocketHp = rocket.getHP(); 0.05f, new Color(32, 178, 169)));
if (!rocket.updateHP(player.getHP())) { boomEffects.add(new Effect(x, y, 5, 5, 75,
rockets.remove(rocket); 0.1f, new Color(32, 178, 169)));
if (!player.updateHP(rocketHp)) { boomEffects.add(new Effect(x, y, 10, 10,
player.setAlive(false); 100, 0.3f, new Color(230, 207, 105)));
sound.soundDestroy(); boomEffects.add(new Effect(x, y, 10, 5,
if (score > highScore) { 100, 0.5f, new Color(255, 70, 70)));
highScore = score; boomEffects.add(new Effect(x, y, 10, 5,
HighScoreManager.saveHighScore(highScore); 150, 0.2f, new Color(255, 255, 255)));
System.out.println("New High Score: " + } } } }
highScore); private void drawBackground() {
} else { g2.setColor(new Color(30, 30, 30));
System.out.println("Current High Score: " + g2.fillRect(0, 0, width, height);
highScore); }
} private void drawGame() {
} sound.soundDestroy(); if (player.isAlive()) {
double x = rocket.getX() + player.draw(g2);
Rocket.ROCKET_SIZE / 2; }
double y = rocket.getY() + for (int i = 0; i < bullets.size(); i++) {
Rocket.ROCKET_SIZE / 2; Bullet bullet = bullets.get(i);
boomEffects.add(new Effect(x, y, 5, 5, 75, if (bullet != null) {
0.05f, new Color(32, 178, 169))); bullet.draw(g2);
boomEffects.add(new Effect(x, y, 5, 5, 75, }
0.1f, new Color(32, 178, 169))); }
boomEffects.add(new Effect(x, y, 10, 10, for (int i = 0; i < rockets.size(); i++) {
100, 0.3f, new Color(230, 207, 105))); Rocket rocket = rockets.get(i);
boomEffects.add(new Effect(x, y, 10, 5, if (rocket != null) {
100, 0.5f, new Color(255, 70, 70))); rocket.draw(g2);
boomEffects.add(new Effect(x, y, 10, 5, }
150, 0.2f, new Color(255, 255, 255))); }
} for (int i = 0; i < boomEffects.size(); i++) {
if (!player.updateHP(rocketHp)) { Effect boomEffect = boomEffects.get(i);
player.setAlive(false); if (boomEffect != null) {
sound.soundDestroy(); boomEffect.draw(g2);
int currentScore = score int highScore = }
HighScoreManager.loadHighScore(); }
if (currentScore > highScore) { g2.setColor(Color.WHITE);
HighScoreManager.saveHighScore(currentScore); g2.setFont(getFont().deriveFont(Font.BOLD, 15f));
System.out.println("New High Score: " + g2.drawString("Score : " + score, 10, 20);
currentScore); g2.drawString("High Score : " + highScore, 10, 40);
} else { if (!player.isAlive()) {
System.out.println("Current High Score: " + String text = "GAME OVER";
highScore); String textKey = "Press key enter to Continue ...";
} g2.setFont(getFont().deriveFont(Font.BOLD, 50f));
double x = player.getX() + FontMetrics fm = g2.getFontMetrics();
Player.PLAYER_SIZE / 2; Rectangle2D r2 = fm.getStringBounds(text, g2);
double y = player.getY() + double textWidth = r2.getWidth();
Player.PLAYER_SIZE / 2; double textHeight = r2.getHeight();
double x = (width - textWidth) / 2; @SwingContainer(delegate = "getContentPane")
double y = (height - textHeight) / 2; @SuppressWarnings("serial") // Same-version
g2.drawString(text, (int) x, (int) y + serialization only
fm.getAscent()); public class JFrame extends Frame implements
g2.setFont(getFont().deriveFont(Font.BOLD, WindowConstants,
15f)); Accessible,
fm = g2.getFontMetrics(); RootPaneContainer,
r2 = fm.getStringBounds(textKey, g2);
textWidth = r2.getWidth(); TransferHandler.HasGetTransferHandler
textHeight = r2.getHeight(); {
x = (width - textWidth) / 2; private static final Object
y = (height - textHeight) / 2; defaultLookAndFeelDecoratedKey =
g2.drawString(textKey, (int) x, (int) y + new
fm.getAscent() + 50); StringBuffer("JFrame.defaultLookAndFeelDecorated");
} private int defaultCloseOperation =
} HIDE_ON_CLOSE;
private void render() { private TransferHandler transferHandler;
Graphics g = getGraphics(); protected JRootPane rootPane;
g.drawImage(image, 0, 0, null); protected boolean rootPaneCheckingEnabled = false;
g.dispose();
} public JFrame() throws HeadlessException {
private void sleep(long speed) { super();
try { frameInit();
Thread.sleep(speed); }
} catch (InterruptedException ex) { public JFrame(GraphicsConfiguration gc) {
System.err.println(ex); super(gc);
}} } frameInit();
MAIN }
package javax.swing; public JFrame(String title) throws HeadlessException {
import java.awt.AWTEvent; super(title);
import java.awt.BorderLayout; frameInit();
import java.awt.Component; }
import java.awt.Container; public JFrame(String title, GraphicsConfiguration gc) {
import java.awt.Frame; super(title, gc);
import java.awt.Graphics; frameInit();
import java.awt.GraphicsConfiguration; }
import java.awt.HeadlessException; enableEvents(AWTEvent.KEY_EVENT_MASK |
import java.awt.Image; AWTEvent.WINDOW_EVENT_MASK);
import java.awt.LayoutManager; setLocale( JComponent.getDefaultLocale() );
import java.awt.event.WindowEvent; setRootPane(createRootPane());
import java.beans.JavaBean; setBackground(UIManager.getColor("control"));
import java.beans.BeanProperty; setRootPaneCheckingEnabled(true);
import javax.accessibility.Accessible; if (JFrame.isDefaultLookAndFeelDecorated()) {
import javax.accessibility.AccessibleContext; boolean supportsWindowDecorations =
import javax.accessibility.AccessibleState; UIManager.getLookAndFeel().getSupportsWindowDeco
import javax.accessibility.AccessibleStateSet; rations();
@JavaBean(defaultProperty = "JMenuBar", description if (supportsWindowDecorations) {
= "A toplevel window which can be minimized to an setUndecorated(true);
icon.")
getRootPane().setWindowDecorationStyle(JRootPane.F @SuppressWarnings("removal")
RAME); SecurityManager security =
} System.getSecurityManager();
} if (security != null) {
sun.awt.SunToolkit.checkAndSetPolicy(this); } security.checkExit(0);
protected JRootPane createRootPane() { }
JRootPane rp = new JRootPane(); }
rp.setOpaque(true); if (this.defaultCloseOperation != operation) {
return rp; int oldValue = this.defaultCloseOperation;
} this.defaultCloseOperation = operation;
protected void processWindowEvent(final firePropertyChange("defaultCloseOperation",
WindowEvent e) { oldValue, operation);
super.processWindowEvent(e); }
if (e.getID() == WindowEvent.WINDOW_CLOSING) { }
switch (defaultCloseOperation) { public int getDefaultCloseOperation() {
case HIDE_ON_CLOSE: return defaultCloseOperation;
setVisible(false); }
break; @BeanProperty(hidden = true, description
case DISPOSE_ON_CLOSE: = "Mechanism for transfer of data into the
dispose(); component")
break; public void setTransferHandler(TransferHandler
case EXIT_ON_CLOSE: newHandler) {
System.exit(0); TransferHandler oldHandler = transferHandler;
break; transferHandler = newHandler;
case DO_NOTHING_ON_CLOSE:
default: SwingUtilities.installSwingDropTargetAsNecessary(this
}}} , transferHandler);
@BeanProperty(preferred = true, enumerationValues = firePropertyChange("transferHandler", oldHandler,
{ "WindowConstants.DO_NOTHING_ON_CLOS newHandler);
E", }
"WindowConstants.HIDE_ON_CLOSE", public TransferHandler getTransferHandler() {
"WindowConstants.DISPOSE_ON_CLOSE", return transferHandler;
"WindowConstants.EXIT_ON_CLOSE"}, }
description public void update(Graphics g) {
= "The frame's default close operation.") paint(g);
public void setDefaultCloseOperation(int operation) { }
if (operation != DO_NOTHING_ON_CLOSE && @BeanProperty(bound = false, hidden = true,
operation != HIDE_ON_CLOSE && description
operation != DISPOSE_ON_CLOSE && = "The menubar for accessing pulldown menus
operation != EXIT_ON_CLOSE) { from this frame.")
throw new public void setJMenuBar(final JMenuBar menubar) {
IllegalArgumentException("defaultCloseOperation must getRootPane().setJMenuBar(menubar);
be" }
+ " one of: DO_NOTHING_ON_CLOSE, public JMenuBar getJMenuBar() {
HIDE_ON_CLOSE," return getRootPane().getJMenuBar();
+ " DISPOSE_ON_CLOSE, or }
EXIT_ON_CLOSE"); protected boolean isRootPaneCheckingEnabled() {
} return rootPaneCheckingEnabled;
if (operation == EXIT_ON_CLOSE) { }
@BeanProperty(hidden = true, description finally
= "Whether the add and setLayout methods are { setRootPaneCheckingEnabled(checkingEnabl
forwarded") ed);
protected void setRootPaneCheckingEnabled(boolean }}}
enabled) { public void setIconImage(Image image) {
rootPaneCheckingEnabled = enabled; super.setIconImage(image);
} }
protected void addImpl(Component comp, Object public Container getContentPane() {
constraints, int index) { return getRootPane().getContentPane();
if(isRootPaneCheckingEnabled()) { }
getContentPane().add(comp, constraints, index); @BeanProperty(bound = false, hidden = true,
} description
else { = "The client area of the frame where child
super.addImpl(comp, constraints, index); components are normally inserted.")
} public void setContentPane(Container contentPane) {
} getRootPane().setContentPane(contentPane);
public void remove(Component comp) { }
if (comp == rootPane) { public JLayeredPane getLayeredPane() {
super.remove(comp); return getRootPane().getLayeredPane();
} else { }
getContentPane().remove(comp); @BeanProperty(bound = false, hidden = true,
}} description
public void setLayout(LayoutManager manager) { = "The pane that holds the various frame
if(isRootPaneCheckingEnabled()) { layers.")
getContentPane().setLayout(manager); public void setLayeredPane(JLayeredPane
} layeredPane) {
else { getRootPane().setLayeredPane(layeredPane);
super.setLayout(manager); }
} public Component getGlassPane() {
} return getRootPane().getGlassPane();
@BeanProperty(bound = false, hidden = true, }
description @BeanProperty(bound = false, hidden = true,
= "the RootPane object for this frame.") description
public JRootPane getRootPane() { = "A transparent pane used for menu rendering.")
return rootPane; public void setGlassPane(Component glassPane) {
} getRootPane().setGlassPane(glassPane);
protected void setRootPane(JRootPane root) { }
if(rootPane != null) {
remove(rootPane); @BeanProperty(bound = false)
} public Graphics getGraphics() {
rootPane = root; JComponent.getGraphicsInvoked(this);
if(rootPane != null) { return super.getGraphics();
boolean checkingEnabled = }
isRootPaneCheckingEnabled(); public void repaint(long time, int x, int y, int width, int
try { height) {
setRootPaneCheckingEnabled(false); if
add(rootPane, BorderLayout.CENTER); (RepaintManager.HANDLE_TOP_LEVEL_PAINT) {
}
RepaintManager.currentManager(this).addDirtyRegion(
this, x, y, width, height); return super.paramString() +
} ",defaultCloseOperation=" +
else { defaultCloseOperationString +
super.repaint(time, x, y, width, height); } } ",rootPane=" + rootPaneString +
public static void ",rootPaneCheckingEnabled=" +
setDefaultLookAndFeelDecorated(boolean rootPaneCheckingEnabledString;
defaultLookAndFeelDecorated) { }
if (defaultLookAndFeelDecorated) { protected AccessibleContext accessibleContext = null;
SwingUtilities.appContextPut(defaultLookAndFeelDeco public AccessibleContext getAccessibleContext() {
ratedKey, Boolean.TRUE); if (accessibleContext == null) {
} else { accessibleContext = new AccessibleJFrame();
SwingUtilities.appContextPut(defaultLookAndFeelDeco }
ratedKey, Boolean.FALSE); return accessibleContext;
} }
} protected class AccessibleJFrame extends
public static boolean AccessibleAWTFrame {
isDefaultLookAndFeelDecorated() { protected AccessibleJFrame() {}
Boolean defaultLookAndFeelDecorated = public String getAccessibleName() {
(Boolean) if (accessibleName != null) {
SwingUtilities.appContextGet(defaultLookAndFeelDeco return accessibleName;
ratedKey); } else {
if (defaultLookAndFeelDecorated == null) { if (getTitle() == null) {
defaultLookAndFeelDecorated = return super.getAccessibleName();
Boolean.FALSE; } else {
} return return getTitle();
defaultLookAndFeelDecorated.booleanValue(); } }}}
protected String paramString() { public AccessibleStateSet getAccessibleStateSet()
String defaultCloseOperationString; {
if (defaultCloseOperation == HIDE_ON_CLOSE) { AccessibleStateSet states =
defaultCloseOperationString = super.getAccessibleStateSet();
"HIDE_ON_CLOSE"; if (isResizable()) {
} else if (defaultCloseOperation == states.add(AccessibleState.RESIZABLE);
DISPOSE_ON_CLOSE) { }
defaultCloseOperationString = if (getFocusOwner() != null) {
"DISPOSE_ON_CLOSE"; states.add(AccessibleState.ACTIVE);
} else if (defaultCloseOperation == }
DO_NOTHING_ON_CLOSE) { return states; }}
defaultCloseOperationString = BULLET:
"DO_NOTHING_ON_CLOSE"; package game.obj;
} else if (defaultCloseOperation == import java.awt.Color;
EXIT_ON_CLOSE) { import java.awt.Graphics2D;
defaultCloseOperationString = import java.awt.Shape;
"EXIT_ON_CLOSE"; import java.awt.geom.AffineTransform;
} else defaultCloseOperationString = ""; import java.awt.geom.Area;
String rootPaneString = (rootPane != null ? import java.awt.geom.Ellipse2D;
rootPane.toString() : ""); public class Bullet {
String rootPaneCheckingEnabledString = private double x;
(rootPaneCheckingEnabled ? private double y;
"true" : "false"); private final Shape shape;
private final Color color = new Color(255, 255, 255); public double getCenterY() {
private final float angle; return y + size / 2;
private double size; }}
private float speed = 1f; EFFECT:
public Bullet(double x, double y, float angle, double package game.obj;
size, float speed) { import java.awt.AlphaComposite;
x += Player.PLAYER_SIZE / 2 - (size / 2); import java.awt.Color;
y += Player.PLAYER_SIZE / 2 - (size / 2); import java.awt.Composite;
this.x = x; import java.awt.Graphics2D;
this.y = y; import java.awt.geom.AffineTransform;
this.angle = angle; import java.awt.geom.Rectangle2D;
this.size = size; import java.util.Random;
this.speed = speed; public class Effect {
shape = new Ellipse2D.Double(0, 0, size, size);} private final double x;
public void update() { private final double y;
x += Math.cos(Math.toRadians(angle)) * speed; private final double max_distance;
y += Math.sin(Math.toRadians(angle)) * speed; private final int max_size;
} private final Color color;
public boolean check(int width, int height) { private final int totalEffect;
if (x <= -size || y < -size || x > width || y > height) { private final float speed;
return false; private double current_distance;
} else { private ModelBoom booms[];
return true; private float alpha = 1f;
} public Effect(double x, double y, int totalEffect, int
} max_size, double max_distance, float speed, Color
public void draw(Graphics2D g2) { color) {
AffineTransform oldTransform = this.x = x;
g2.getTransform(); this.y = y;
g2.setColor(color); this.totalEffect = totalEffect;
g2.translate(x, y); this.max_size = max_size;
g2.fill(shape); this.max_distance = max_distance;
g2.setTransform(oldTransform); this.speed = speed;
} this.color = color;
public Shape getShape() { createRandom();
return new Area(new Ellipse2D.Double(x, y, size, }
size)); private void createRandom() {
} booms = new ModelBoom[totalEffect];
public double getX() { float per = 360f / totalEffect;
return x; Random ran = new Random();
} for (int i = 1; i <= totalEffect; i++) {
public double getY() { int r = ran.nextInt((int) per) + 1;
return y; int boomSize = ran.nextInt(max_size) + 1;
} float angle = i * per + r;
public double getSize() { booms[i - 1] = new ModelBoom(boomSize, angle);
return size; }
} }
public double getCenterX() { public void draw(Graphics2D g2) {
return x + size / 2; AffineTransform oldTransform =
} g2.getTransform();
Composite oldComposite = g2.getComposite(); this.currentHp = currentHp;
g2.setColor(color); }
g2.translate(x, y);
for (ModelBoom b : booms) { public HP(double MAX_HP, double currentHp) {
double bx = this.MAX_HP = MAX_HP;
Math.cos(Math.toRadians(b.getAngle())) * this.currentHp = currentHp;
current_distance; }
double by = public HP() {
Math.sin(Math.toRadians(b.getAngle())) * }
current_distance; private double MAX_HP;
double boomSize = b.getSize(); private double currentHp;
double space = boomSize / 2; }
if (current_distance >= max_distance - HPRender:
(max_distance * 0.7f)) { package game.obj;
alpha = (float) ((max_distance - import java.awt.Color;
current_distance) / (max_distance * 0.7f)); import java.awt.Graphics2D;
} import java.awt.Shape;
if (alpha > 1) { import java.awt.geom.Rectangle2D;
alpha = 1; public class HpRender {
} else if (alpha < 0) { private final HP hp;
alpha = 0; public HpRender(HP hp) {
} this.hp = hp;
g2.setComposite(AlphaComposite.getInstance(AlphaCo }
mposite.SRC_OVER, alpha)); protected void hpRender(Graphics2D g2, Shape
g2.fill(new Rectangle2D.Double(bx - space, by - shape, double y) {
space, boomSize, boomSize)); if (hp.getCurrentHp() != hp.getMAX_HP()) {
} double hpY = shape.getBounds().getY() - y - 10;
g2.setComposite(oldComposite); g2.setColor(new Color(70, 70, 70));
g2.setTransform(oldTransform); g2.fill(new Rectangle2D.Double(0, hpY,
} Player.PLAYER_SIZE, 2));
public void update() { g2.setColor(new Color(253, 91, 91));
current_distance += speed; double hpSize = hp.getCurrentHp() /
} hp.getMAX_HP() * Player.PLAYER_SIZE;
public boolean check() { g2.fill(new Rectangle2D.Double(0, hpY, hpSize, 2));
return current_distance < max_distance; }}
}} public boolean updateHP(double cutHP) {
HP: hp.setCurrentHp(hp.getCurrentHp() - cutHP);
package game.obj; return hp.getCurrentHp() > 0;
public class HP { }
public double getMAX_HP() { public double getHP() {
return MAX_HP; return hp.getCurrentHp();
} }
public void setMAX_HP(double MAX_HP) { public void resetHP() {
this.MAX_HP = MAX_HP; hp.setCurrentHp(hp.getMAX_HP());
} }}
public double getCurrentHp() { MODELBOOM:
return currentHp; package game.obj;
} public class ModelBoom{
public void setCurrentHp(double currentHp) { public double getSize() {
return size; private float speed = 0f;
} private float angle = 0f;
public void setSize(double size) { private final Area playerShap;
this.size = size; private final Image image;
} private final Image image_speed;
public float getAngle() { private boolean speedUp;
return angle; private boolean alive = true;
} public void changeLocation(double x, double y) {
public void setAngle(float angle) { this.x = x;
this.angle = angle; this.y = y;
} }
public ModelBoom(double size, float angle) { public void update() {
this.size = size; x += Math.cos(Math.toRadians(angle)) * speed;
this.angle = angle; y += Math.sin(Math.toRadians(angle)) * speed;
} }
public ModelBoom() { public void changeAngle(float angle) {
} if (angle < 0) {
private double size; angle = 359;
private float angle; } else if (angle > 359) {
} angle = 0;
PLAYER|: }
package game.obj; this.angle = angle; }
import java.awt.Graphics2D; public void draw(Graphics2D g2) {
import java.awt.Image; AffineTransform oldTransform =
import java.awt.geom.AffineTransform; g2.getTransform();
import java.awt.geom.Area; g2.translate(x, y);
import java.awt.geom.Path2D; AffineTransform tran = new
import javax.swing.ImageIcon; AffineTransform();
public class Player extends HpRender { tran.rotate(Math.toRadians(angle + 45),
public Player() { PLAYER_SIZE / 2, PLAYER_SIZE / 2);
super(new HP(50, 50)); g2.drawImage(speedUp ? image_speed : image,
this.image = new tran, null);
ImageIcon(getClass().getResource("/game/image/pla hpRender(g2, getShape(), y);
ne.png")).getImage(); g2.setTransform(oldTransform); }
this.image_speed = new public Area getShape() {
ImageIcon(getClass().getResource("/game/image/pla AffineTransform afx = new AffineTransform();
ne_speed.png")).getImage(); afx.translate(x, y);
Path2D p = new Path2D.Double(); afx.rotate(Math.toRadians(angle),
p.moveTo(0, 15); PLAYER_SIZE / 2, PLAYER_SIZE / 2);
p.lineTo(20, 5); return new
p.lineTo(PLAYER_SIZE + 15, PLAYER_SIZE / 2); Area(afx.createTransformedShape(playerShap));
p.lineTo(20, PLAYER_SIZE - 5); }
p.lineTo(0, PLAYER_SIZE - 15); public double getX() {
playerShap = new Area(p); return x;
} }
public static final double PLAYER_SIZE = 64; public double getY() {
private double x; return y;
private double y; }
private final float MAX_SPEED = 1f; public float getAngle() {
return angle; p.lineTo(ROCKET_SIZE + 10,
} ROCKET_SIZE / 2);
public void speedUp() { p.lineTo(ROCKET_SIZE - 5, ROCKET_SIZE - 13);
speedUp = true; p.lineTo(15, ROCKET_SIZE - 10);
if (speed > MAX_SPEED) { rocketShap = new Area(p);
speed = MAX_SPEED; }
} else { public static final double ROCKET_SIZE = 50;
speed += 0.01f; private double x;
}} private double y;
public void speedDown() { private final float speed = 0.3f;
speedUp = false; private float angle = 0;
if (speed <= 0) { private final Image image;
speed = 0; private final Area rocketShap;
} else { public void changeLocation(double x, double y) {
speed -= 0.003f; this.x = x;
} this.y = y;
} }
public boolean isAlive() { public void update() {
return alive; x += Math.cos(Math.toRadians(angle)) * speed;
} y += Math.sin(Math.toRadians(angle)) * speed;
public void setAlive(boolean alive) { }
this.alive = alive; public void changeAngle(float angle) {
} if (angle < 0) {
public void reset() { angle = 359;
alive = true; } else if (angle > 359) {
resetHP(); angle = 0;
angle = 0; }
speed = 0; } } this.angle = angle;
ROCKET: }
package game.obj; public void draw(Graphics2D g2) {
import java.awt.Graphics2D; AffineTransform oldTransform =
import java.awt.Image; g2.getTransform();
import java.awt.Rectangle; g2.translate(x, y);
import java.awt.Shape; AffineTransform tran = new
import java.awt.geom.AffineTransform; AffineTransform();
import java.awt.geom.Area; tran.rotate(Math.toRadians(angle + 45),
import java.awt.geom.Path2D; ROCKET_SIZE / 2, ROCKET_SIZE / 2);
import javax.swing.ImageIcon; g2.drawImage(image, tran, null);
public class Rocket extends HpRender { Shape shap = getShape();
public Rocket() { hpRender(g2, shap, y);
super(new HP(20, 20)); g2.setTransform(oldTransform);
this.image = new }
ImageIcon(getClass().getResource("/game/image/ro public double getX() {
cket.png")).getImage(); return x; }
Path2D p = new Path2D.Double(); public double getY() {
p.moveTo(0, ROCKET_SIZE / 2); return y; }
p.lineTo(15, 10); public float getAngle() {
p.lineTo(ROCKET_SIZE - 5, 13); return angle; }
public Area getShape() {
AffineTransform afx = new AffineTransform(); this.destroy=this.getClass().getClassLoader().getRes
afx.translate(x, y); ource("game/obj/sound/destroy.wav");
afx.rotate(Math.toRadians(angle), }
ROCKET_SIZE / 2, ROCKET_SIZE / 2); public void soundShoot(){
return new play(shoot);
Area(afx.createTransformedShape(rocketShap)); }
} public void soundHit(){
public boolean check(int width, int height) { play(hit);
Rectangle size = getShape().getBounds(); }
if (x <= -size.getWidth() || y < -size.getHeight() public void soundDestroy(){
|| x > width || y > height) { play(destroy);
return false; }
} else { private void play(URL url) {
return true; } } } try {
SOUND: AudioInputStream audioIn =
package game.obj.sound; AudioSystem.getAudioInputStream(url);
Clip clip = AudioSystem.getClip();
import java.io.IOException; clip.open(audioIn);
import java.net.URL;
import javax.sound.sampled.AudioInputStream; // Add a listener to close the clip when done
import javax.sound.sampled.AudioSystem; playing
import javax.sound.sampled.Clip; clip.addLineListener(new LineListener() {
import javax.sound.sampled.LineEvent; @Override
import javax.sound.sampled.LineListener; public void update(LineEvent event) {
import if (event.getType() ==
javax.sound.sampled.LineUnavailableException; LineEvent.Type.STOP) {
import clip.close();
javax.sound.sampled.UnsupportedAudioFileExcepti }
on; }
public class Sound { });
private final URL shoot; clip.start();
private final URL hit;
private final URL destroy; } catch (IOException |
public Sound(){ LineUnavailableException |
this.shoot=this.getClass().getClassLoader().getReso UnsupportedAudioFileException e) {
urce("game/obj/sound/shoot.wav"); System.err.println("Error playing sound: " +
this.hit=this.getClass().getClassLoader().getResourc e.getMessage());
e("game/obj/sound/hit.wav"); }
}}

INTERFACES:
CONCLUSION:

In conclusion, this 2D shooting game effectively demonstrates the application of core objectoriented
programming concepts to build an engaging and interactive experience. With features like real time scoring,
animated effects, collision detection, and high score tracking, the game offers a solid foundation for learning
Java and game development. It provides a practical example of how object oriented design can structure a
complex system into manageable and reusable components.

You might also like