refactoring III

This commit is contained in:
Jan-Niclas Loosen 2024-11-28 15:25:38 +01:00
parent 7af9624252
commit a7d68e5ef6
8 changed files with 223 additions and 226 deletions

View File

@ -11,6 +11,7 @@ import com.example.flappybird.states.GameState;
import java.awt.*; import java.awt.*;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.util.Random;
public class Bird extends HasPosition { public class Bird extends HasPosition {
@ -34,11 +35,24 @@ public class Bird extends HasPosition {
private static double currentFrame = 0; private static double currentFrame = 0;
public Bird (int x, int y) {
public Bird (String color, int x, int y, BufferedImage[] s) {
super(x, y); super(x, y);
this.color = color;
this.sprites = s; Random rand = new Random();
String[] birds = new String[] {
"yellow",
"blue",
"red"
};
// Random bird color
String randomBird = birds[rand.nextInt(3)];
this.color = randomBird;
this.sprites = new BufferedImage[] {
FlappyBird.textures.get(randomBird + "Bird1").getImage(),
FlappyBird.textures.get(randomBird + "Bird2").getImage(),
FlappyBird.textures.get(randomBird + "Bird3").getImage()
};
} }
/** /**
@ -105,7 +119,7 @@ public class Bird extends HasPosition {
y += (int) velocity; y += (int) velocity;
} else { } else {
// Play audio and set state to dead // Play audio and set state to dead
GameState.audio.hit(); FlappyBird.audio.hit();
isAlive = false; isAlive = false;
} }
@ -140,7 +154,6 @@ public class Bird extends HasPosition {
} }
private void animateBird(Graphics g, double angle) { private void animateBird(Graphics g, double angle) {
Graphics2D g2d = (Graphics2D) g; Graphics2D g2d = (Graphics2D) g;
AffineTransform trans = g2d.getTransform(); AffineTransform trans = g2d.getTransform();
AffineTransform at = new AffineTransform(); AffineTransform at = new AffineTransform();

View File

@ -8,10 +8,14 @@
package com.example.flappybird; package com.example.flappybird;
import javax.swing.*; import javax.swing.*;
import java.awt.*;
import java.awt.event.*; import java.awt.event.*;
import java.awt.Toolkit; import java.io.BufferedInputStream;
import java.io.InputStream;
import java.util.Calendar;
import java.util.HashMap;
public class FlappyBird extends JFrame implements ActionListener { public class FlappyBird implements ActionListener {
GamePanel game; GamePanel game;
Timer gameTimer; Timer gameTimer;
@ -21,24 +25,63 @@ public class FlappyBird extends JFrame implements ActionListener {
public static final int HEIGHT = 667; public static final int HEIGHT = 667;
private static final int DELAY = 12; private static final int DELAY = 12;
// Fonts
public static Font flappyFontBase;
public static Font flappyFontReal;
public static Font flappyScoreFont;
public static Font flappyMiniFont;
// Audios
public static Audio audio = new Audio();
// Textures
public static HashMap<String, Texture> textures = new Sprites().getGameTextures();
// Boolean to show dark or light screen
public static boolean darkTheme;
public FlappyBird () { public FlappyBird () {
super("Flappy Bird"); JFrame frame = new JFrame("Flappy Bird");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(WIDTH, HEIGHT); frame.setSize(WIDTH, HEIGHT);
// Try to load ttf file
try {
InputStream is = new BufferedInputStream(this.getClass().getResourceAsStream("/res/fonts/flappy-font.ttf"));
flappyFontBase = Font.createFont(Font.TRUETYPE_FONT, is);
// Header and sub-header fonts
flappyScoreFont = flappyFontBase.deriveFont(Font.PLAIN, 50);
flappyFontReal = flappyFontBase.deriveFont(Font.PLAIN, 20);
flappyMiniFont = flappyFontBase.deriveFont(Font.PLAIN, 15);
} catch (Exception ex) {
// Exit is font cannot be loaded
ex.printStackTrace();
System.err.println("Could not load Flappy Font!");
System.exit(-1);
}
// Game timer // Game timer
gameTimer = new Timer(DELAY, this); gameTimer = new Timer(DELAY, this);
gameTimer.start(); gameTimer.start();
// Get current hour with Calendar
// If it is past noon, use the dark theme
Calendar cal = Calendar.getInstance();
int currentHour = cal.get(Calendar.HOUR_OF_DAY);
darkTheme = currentHour > 20 || currentHour < 6;
// Add Panel to Frame // Add Panel to Frame
game = new GamePanel(); game = new GamePanel();
add(game); frame.add(game);
// Set game icon // Set game icon
setIconImage(Toolkit.getDefaultToolkit().getImage("res/img/icons.png")); frame.setIconImage(Toolkit.getDefaultToolkit().getImage("res/img/icons.png"));
setResizable(false); frame.setResizable(false);
setVisible(true); frame.setVisible(true);
} }
public void actionPerformed (ActionEvent e) { public void actionPerformed (ActionEvent e) {

View File

@ -20,6 +20,9 @@ public class GamePanel extends JPanel implements KeyListener, MouseListener {
// If game has loaded // If game has loaded
public boolean ready = false; public boolean ready = false;
// Store point when player clicks
protected Point clickedPoint = new Point(-1, -1);
public GamePanel () { public GamePanel () {
setGameState(new MenuState(this)); setGameState(new MenuState(this));
@ -75,12 +78,27 @@ public class GamePanel extends JPanel implements KeyListener, MouseListener {
// Mouse actions // // Mouse actions //
/////////////////// ///////////////////
public Point getClickedPoint() {
return clickedPoint;
}
/**
* Checks if point is in rectangle
*
* @param r Rectangle
* @return Boolean if point collides with rectangle
*/
public boolean isTouching (Rectangle r) {
return r.contains(clickedPoint);
}
public void mouseExited (MouseEvent e) {} public void mouseExited (MouseEvent e) {}
public void mouseEntered (MouseEvent e) {} public void mouseEntered (MouseEvent e) {}
public void mouseReleased (MouseEvent e) {} public void mouseReleased (MouseEvent e) {}
public void mouseClicked (MouseEvent e) {} public void mouseClicked (MouseEvent e) {}
public void mousePressed(MouseEvent e) { public void mousePressed(MouseEvent e) {
clickedPoint = e.getPoint();
System.out.println("Mouse clicked at: " + e.getPoint()); System.out.println("Mouse clicked at: " + e.getPoint());
gameState.handleMouseEvent(e); gameState.handleMouseEvent(e);
} }

View File

@ -25,6 +25,9 @@ public class Highscore {
// Highscore // Highscore
private int bestScore; private int bestScore;
// Scanner
private static Scanner dataScanner = null;
static { static {
try { try {
assert dataURL != null; assert dataURL != null;
@ -34,8 +37,6 @@ public class Highscore {
} }
} }
private static Scanner dataScanner = null;
public Highscore () { public Highscore () {
// Load scanner with data file // Load scanner with data file

View File

@ -16,15 +16,14 @@ import java.util.HashMap;
public class Sprites { public class Sprites {
// Resize factor to match frame size
private static final double RESIZE_FACTOR = 2.605;
// HashMap of texture objects // HashMap of texture objects
private static final HashMap<String, Texture> textures = new HashMap<String, Texture>(); private static final HashMap<String, Texture> textures = new HashMap<String, Texture>();
public Sprites () { // Sprite sheet
protected BufferedImage spriteSheet;
public Sprites() {
// Try to load sprite sheet, exit program if cannot // Try to load sprite sheet, exit program if cannot
BufferedImage spriteSheet = null;
try { try {
String fontPath = "/res/img/spriteSheet.png"; String fontPath = "/res/img/spriteSheet.png";
URL fontUrl = this.getClass().getResource(fontPath); URL fontUrl = this.getClass().getResource(fontPath);
@ -39,69 +38,74 @@ public class Sprites {
} }
// Backgrounds // Backgrounds
textures.put("background1", new Texture(resize(spriteSheet.getSubimage(0, 0, 144, 256)), 0, 0)); putTexture("background1", 0, 0, 0, 0, 144, 256);
textures.put("background2", new Texture(resize(spriteSheet.getSubimage(146, 0, 144, 256)), 0, 0)); putTexture("background2", 146, 0, 0, 0, 144, 256);
// Pipes // Pipes
textures.put("pipe-top", new Texture(resize(spriteSheet.getSubimage(56, 323, 26, 160)), 0, 0)); putTexture("pipe-top", 56, 323, 0, 0, 26, 160);
textures.put("pipe-bottom", new Texture(resize(spriteSheet.getSubimage(84, 323, 26, 160)), 0, 0)); putTexture("pipe-bottom", 84, 323, 0, 0, 26, 160);
// Birds // Birds
textures.put("yellowBird1", new Texture(resize(spriteSheet.getSubimage(31, 491, 17, 12)), 172, 250)); putTexture("yellowBird1", 31, 491, 172, 250, 17, 12);
textures.put("yellowBird2", new Texture(resize(spriteSheet.getSubimage(59, 491, 17, 12)), 172, 250)); putTexture("yellowBird2", 59, 491, 172, 250, 17, 12);
textures.put("yellowBird3", new Texture(resize(spriteSheet.getSubimage(3, 491, 17, 12)), 172, 250)); putTexture("yellowBird3", 3, 491, 172, 250, 17, 12);
textures.put("blueBird1", new Texture(resize(spriteSheet.getSubimage(115, 329, 17, 12)), 172, 250)); putTexture("blueBird1", 115, 329, 172, 250, 17, 12);
textures.put("blueBird2", new Texture(resize(spriteSheet.getSubimage(115, 355, 17, 12)), 172, 250)); putTexture("blueBird2", 115, 355, 172, 250, 17, 12);
textures.put("blueBird3", new Texture(resize(spriteSheet.getSubimage(87, 491, 17, 12)), 172, 250)); putTexture("blueBird3", 87, 491, 172, 250, 17, 12);
textures.put("redBird1", new Texture(resize(spriteSheet.getSubimage(115, 407, 17, 12)), 172, 250)); putTexture("redBird1", 115, 407, 172, 250, 17, 12);
textures.put("redBird2", new Texture(resize(spriteSheet.getSubimage(115, 433, 17, 12)), 172, 250)); putTexture("redBird2", 115, 433, 172, 250, 17, 12);
textures.put("redBird3", new Texture(resize(spriteSheet.getSubimage(115, 381, 17, 12)), 172, 250)); putTexture("redBird3", 115, 381, 172, 250, 17, 12);
// Buttons // Buttons
textures.put("playButton", new Texture(resize(spriteSheet.getSubimage(354, 118, 52, 29)), 34, 448)); putTexture("playButton", 354, 118, 34, 448, 52, 29);
textures.put("leaderboard", new Texture(resize(spriteSheet.getSubimage(414, 118, 52, 29)), 203, 448)); putTexture("leaderboard", 414, 118, 203, 448, 52, 29);
textures.put("rateButton", new Texture(resize(spriteSheet.getSubimage(465, 1, 31, 18)), 147, 355)); putTexture("rateButton", 465, 1, 147, 355, 31, 18);
// Helpful / Text // Helpful / Text
textures.put("newHighscore", new Texture(resize(spriteSheet.getSubimage(112, 501, 16, 7)), 210, 305)); putTexture("newHighscore", 112, 501, 210, 305, 16, 7);
textures.put("titleText", new Texture(resize(spriteSheet.getSubimage(351, 91, 89, 24)), 72, 100)); putTexture("titleText", 351, 91, 72, 100, 89, 24);
textures.put("getReadyText", new Texture(resize(spriteSheet.getSubimage(295, 59, 92, 25)), 68, 180)); putTexture("getReadyText", 295, 59, 68, 180, 92, 25);
textures.put("gameOverText", new Texture(resize(spriteSheet.getSubimage(395, 59, 96, 21)), 62, 100)); putTexture("gameOverText", 395, 59, 62, 100, 96, 21);
textures.put("instructions", new Texture(resize(spriteSheet.getSubimage(292, 91, 57, 49)), 113, 300)); putTexture("instructions", 292, 91, 113, 300, 57, 49);
// SCORE IMAGES // SCORE IMAGES
putTexture("score-0", 496, 60, 0, 0, 12, 18);
// Large numbers putTexture("score-1", 136, 455, 0, 0, 8, 18);
textures.put("score-0", new Texture(resize(spriteSheet.getSubimage(496, 60, 12, 18)), 0, 0));
textures.put("score-1", new Texture(resize(spriteSheet.getSubimage(136, 455, 8, 18)), 0, 0));
int score = 2; int score = 2;
for (int i = 292; i < 335; i += 14) { for (int i = 292; i < 335; i += 14) {
textures.put("score-" + score, new Texture(resize(spriteSheet.getSubimage(i, 160, 12, 18)), 0, 0)); putTexture("score-" + score, i, 160, 0, 0, 12, 18);
textures.put("score-" + (score + 4), new Texture(resize(spriteSheet.getSubimage(i, 184, 12, 18)), 0, 0)); putTexture("score-" + (score + 4), i, 184, 0, 0, 12, 18);
score++; score++;
} }
// Mini numbers // Mini numbers
score = 0; score = 0;
for (int i = 323; score < 10; i += 9) { for (int i = 323; score < 10; i += 9) {
textures.put("mini-score-" + score, new Texture(resize(spriteSheet.getSubimage(138, i, 10, 7)), 0, 0)); putTexture("mini-score-" + score, 138, i, 0, 0, 10, 7);
score ++; score++;
if (score % 2 == 0) { i += 8; } if (score % 2 == 0) {
i += 8;
}
} }
// Medals // Medals
textures.put("bronze", new Texture(resize(spriteSheet.getSubimage(112, 477, 22, 22)), 73, 285)); putTexture("bronze", 112, 477, 73, 285, 22, 22);
textures.put("silver", new Texture(resize(spriteSheet.getSubimage(112, 453, 22, 22)), 73, 285)); putTexture("silver", 112, 453, 73, 285, 22, 22);
textures.put("gold", new Texture(resize(spriteSheet.getSubimage(121, 282, 22, 22)), 73, 285)); putTexture("gold", 121, 282, 73, 285, 22, 22);
textures.put("platinum", new Texture(resize(spriteSheet.getSubimage(121, 258, 22, 22)), 73, 285)); putTexture("platinum", 121, 258, 73, 285, 22, 22);
// Other assets // Other assets
textures.put("base", new Texture(resize(spriteSheet.getSubimage(292, 0, 168, 56)), 0, 521)); putTexture("base", 292, 0, 0, 521, 168, 56);
textures.put("scoreCard", new Texture(resize(spriteSheet.getSubimage(3, 259, 113, 57)), 40, 230)); putTexture("scoreCard", 3, 259, 40, 230, 113, 57);
}
private void putTexture(String name, int texX, int texY, int panX, int panY, int width, int height) {
BufferedImage subimage = spriteSheet.getSubimage(texX, texY, width, height);
Texture texture = new Texture(resize(subimage), panX, panY);
textures.put(name, texture);
} }
/** /**
@ -111,8 +115,9 @@ public class Sprites {
* @return New resized image * @return New resized image
*/ */
private static BufferedImage resize (BufferedImage image) { private static BufferedImage resize (BufferedImage image) {
// New width and height // New width and height
// Resize factor to match frame size
double RESIZE_FACTOR = 2.605;
int newWidth = (int) (image.getWidth() * RESIZE_FACTOR); int newWidth = (int) (image.getWidth() * RESIZE_FACTOR);
int newHeight = (int) (image.getHeight() * RESIZE_FACTOR); int newHeight = (int) (image.getHeight() * RESIZE_FACTOR);

View File

@ -10,71 +10,33 @@ import com.example.flappybird.*;
import java.awt.*; import java.awt.*;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Random;
public abstract class GameState { public abstract class GameState {
private final Random rand;
//////////////////// ////////////////////
// Game variables // // Game variables //
//////////////////// ////////////////////
// Fonts
public static Font flappyFontBase;
public static Font flappyFontReal;
public static Font flappyScoreFont;
public static Font flappyMiniFont = null;
public static Audio audio = new Audio();
// Textures
public static HashMap<String, Texture> textures = new Sprites().getGameTextures();
protected static final int[] baseCoords = { 0, 435 }; protected static final int[] baseCoords = { 0, 435 };
protected int score; // Player score // Player score
protected int pipeDistTracker; // Distance between pipes protected int score;
protected boolean scoreWasGreater; // If score was greater than previous highscore // Distance between pipes
protected int pipeDistTracker;
protected Point clickedPoint = new Point(-1, -1); // Store point when player clicks // If score was greater than previous highscore
public static ArrayList<Pipe> pipes; // Arraylist of Pipe objects protected boolean scoreWasGreater;
protected static boolean darkTheme; // Boolean to show dark or light screen // Arraylist of Pipe objects
public static ArrayList<Pipe> pipes;
protected static Bird gameBird; protected static Bird gameBird;
public GamePanel gamePanel; public GamePanel gamePanel;
public GameState(GamePanel panel) { public GameState(GamePanel panel) {
this.gamePanel = panel; this.gamePanel = panel;
rand = new Random();
// Try to load ttf file
try {
InputStream is = new BufferedInputStream(this.getClass().getResourceAsStream("/res/fonts/flappy-font.ttf"));
flappyFontBase = Font.createFont(Font.TRUETYPE_FONT, is);
// Header and sub-header fonts
flappyScoreFont = flappyFontBase.deriveFont(Font.PLAIN, 50);
flappyFontReal = flappyFontBase.deriveFont(Font.PLAIN, 20);
flappyMiniFont = flappyFontBase.deriveFont(Font.PLAIN, 15);
} catch (Exception ex) {
// Exit is font cannot be loaded
ex.printStackTrace();
System.err.println("Could not load Flappy Font!");
System.exit(-1);
}
} }
/** /**
@ -87,47 +49,16 @@ public abstract class GameState {
pipeDistTracker = 0; pipeDistTracker = 0;
scoreWasGreater = false; scoreWasGreater = false;
// Get current hour with Calendar
// If it is past noon, use the dark theme
Calendar cal = Calendar.getInstance();
int currentHour = cal.get(Calendar.HOUR_OF_DAY);
// Array of bird colors
String[] birds = new String[] {
"yellow",
"blue",
"red"
};
// Set random scene assets
darkTheme = currentHour > 12; // If we should use the dark theme
// Random bird color
String randomBird = birds[rand.nextInt(3)]; // Random bird color
// Game bird // Game bird
gameBird = new Bird(randomBird, 172, 250, new BufferedImage[] { gameBird = new Bird(172, 250);
textures.get(randomBird + "Bird1").getImage(),
textures.get(randomBird + "Bird2").getImage(),
textures.get(randomBird + "Bird3").getImage()
});
// Remove old pipes // Remove old pipes
pipes = new ArrayList<Pipe>(); pipes = new ArrayList<Pipe>();
} }
/**
* Checks if point is in rectangle
*
* @param r Rectangle
* @return Boolean if point collides with rectangle
*/
protected boolean isTouching (Rectangle r) {
return r.contains(clickedPoint);
}
public void prepareScreen(Graphics g) { public void prepareScreen(Graphics g) {
// Set font and color // Set font and color
g.setFont(flappyFontReal); g.setFont(FlappyBird.flappyFontReal);
g.setColor(Color.white); g.setColor(Color.white);
// Only move screen if bird is alive // Only move screen if bird is alive
@ -142,8 +73,8 @@ public abstract class GameState {
} }
// Background // Background
g.drawImage(darkTheme ? textures.get("background2").getImage() : g.drawImage(FlappyBird.darkTheme ? FlappyBird.textures.get("background2").getImage() :
textures.get("background1").getImage(), 0, 0, null); FlappyBird.textures.get("background1").getImage(), 0, 0, null);
// Draw bird // Draw bird
gameBird.renderBird(g); gameBird.renderBird(g);
@ -157,8 +88,8 @@ public abstract class GameState {
public void drawBase (Graphics g) { public void drawBase (Graphics g) {
// Moving base effect // Moving base effect
g.drawImage(textures.get("base").getImage(), baseCoords[0], textures.get("base").getY(), null); g.drawImage(FlappyBird.textures.get("base").getImage(), baseCoords[0], FlappyBird.textures.get("base").getY(), null);
g.drawImage(textures.get("base").getImage(), baseCoords[1], textures.get("base").getY(), null); g.drawImage(FlappyBird.textures.get("base").getImage(), baseCoords[1], FlappyBird.textures.get("base").getY(), null);
} }

View File

@ -2,7 +2,6 @@ package com.example.flappybird.states;
import com.example.flappybird.FlappyBird; import com.example.flappybird.FlappyBird;
import com.example.flappybird.GamePanel; import com.example.flappybird.GamePanel;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
@ -30,7 +29,7 @@ public class MenuState extends GameState {
* @param s String to be drawn * @param s String to be drawn
* @param w Constraining width * @param w Constraining width
* @param h Constraining height * @param h Constraining height
* @param y Fixed y-coordiate * @param y Fixed y-coordinate
*/ */
public void drawCentered (String s, int w, int h, int y, Graphics g) { public void drawCentered (String s, int w, int h, int y, Graphics g) {
FontMetrics fm = g.getFontMetrics(); FontMetrics fm = g.getFontMetrics();
@ -42,24 +41,24 @@ public class MenuState extends GameState {
protected void drawMenu (Graphics g) { protected void drawMenu (Graphics g) {
// Title // Title
g.drawImage(textures.get("titleText").getImage(), g.drawImage(FlappyBird.textures.get("titleText").getImage(),
textures.get("titleText").getX(), FlappyBird.textures.get("titleText").getX(),
textures.get("titleText").getY(), null); FlappyBird.textures.get("titleText").getY(), null);
// Buttons // Buttons
g.drawImage(textures.get("playButton").getImage(), g.drawImage(FlappyBird.textures.get("playButton").getImage(),
textures.get("playButton").getX(), FlappyBird.textures.get("playButton").getX(),
textures.get("playButton").getY(), null); FlappyBird.textures.get("playButton").getY(), null);
g.drawImage(textures.get("leaderboard").getImage(), g.drawImage(FlappyBird.textures.get("leaderboard").getImage(),
textures.get("leaderboard").getX(), FlappyBird.textures.get("leaderboard").getX(),
textures.get("leaderboard").getY(), null); FlappyBird.textures.get("leaderboard").getY(), null);
g.drawImage(textures.get("rateButton").getImage(), g.drawImage(FlappyBird.textures.get("rateButton").getImage(),
textures.get("rateButton").getX(), FlappyBird.textures.get("rateButton").getX(),
textures.get("rateButton").getY(), null); FlappyBird.textures.get("rateButton").getY(), null);
// Credits :p // Credits :p
drawCentered("Created by Paul Krishnamurthy", FlappyBird.WIDTH, FlappyBird.HEIGHT, 600, g); drawCentered("Created by Paul Krishnamurthy", FlappyBird.WIDTH, FlappyBird.HEIGHT, 600, g);
g.setFont(flappyMiniFont); // Change font g.setFont(FlappyBird.flappyMiniFont); // Change font
drawCentered("www.PaulKr.com", FlappyBird.WIDTH, FlappyBird.HEIGHT, 630, g); drawCentered("www.PaulKr.com", FlappyBird.WIDTH, FlappyBird.HEIGHT, 630, g);
} }
@ -67,7 +66,6 @@ public class MenuState extends GameState {
* Tries to open the review url in default web browser * Tries to open the review url in default web browser
*/ */
public void openReviewUrl() { public void openReviewUrl() {
try { try {
if (Desktop.isDesktopSupported()) { if (Desktop.isDesktopSupported()) {
Desktop.getDesktop().browse(new URI("http://paulkr.com")); Desktop.getDesktop().browse(new URI("http://paulkr.com"));
@ -90,13 +88,10 @@ public class MenuState extends GameState {
@Override @Override
public void handleMouseEvent(MouseEvent e) { public void handleMouseEvent(MouseEvent e) {
// Save clicked point if (gamePanel.isTouching(FlappyBird.textures.get("playButton").getRect())) {
clickedPoint = e.getPoint();
if (isTouching(GameState.textures.get("playButton").getRect())) {
gamePanel.setGameState(new PlayState(gamePanel)); gamePanel.setGameState(new PlayState(gamePanel));
} else if (isTouching(GameState.textures.get("leaderboard").getRect())) { } else if (gamePanel.isTouching(FlappyBird.textures.get("leaderboard").getRect())) {
// Dummy message // Dummy message
JOptionPane.showMessageDialog(gamePanel, JOptionPane.showMessageDialog(gamePanel,
"We can't access the leaderboard right now!", "We can't access the leaderboard right now!",
@ -104,14 +99,13 @@ public class MenuState extends GameState {
JOptionPane.ERROR_MESSAGE); JOptionPane.ERROR_MESSAGE);
} }
Rectangle rect = GameState.textures.get("playButton").getRect(); Rectangle rect = FlappyBird.textures.get("playButton").getRect();
System.out.println("Texture Rect: x=" + rect.getX() + ", y=" + rect.getY() + System.out.println("Texture Rect: x=" + rect.getX() + ", y=" + rect.getY() +
", width=" + rect.getWidth() + ", height=" + rect.getHeight()); ", width=" + rect.getWidth() + ", height=" + rect.getHeight());
if (gameBird.isAlive()) { if (gamePanel.isTouching(FlappyBird.textures.get("rateButton").getRect())) {
if (isTouching(textures.get("rateButton").getRect())) { // Open website
openReviewUrl(); // Open website openReviewUrl();
}
} }
} }
} }

View File

@ -11,8 +11,11 @@ import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
public class PlayState extends GameState { public class PlayState extends GameState {
protected boolean inStartGameState = false; // To show instructions screen // To show instructions screen
protected String medal; // Medal to be awarded after each game protected boolean inStartGameState = false;
// Medal to be awarded after each game
protected String medal;
protected final Highscore highscore = new Highscore(); protected final Highscore highscore = new Highscore();
@ -25,14 +28,14 @@ public class PlayState extends GameState {
gameBird.setGameStartPos(); gameBird.setGameStartPos();
// Get ready text // Get ready text
g.drawImage(textures.get("getReadyText").getImage(), g.drawImage(FlappyBird.textures.get("getReadyText").getImage(),
textures.get("getReadyText").getX(), FlappyBird.textures.get("getReadyText").getX(),
textures.get("getReadyText").getY(), null); FlappyBird.textures.get("getReadyText").getY(), null);
// Instructions image // Instructions image
g.drawImage(textures.get("instructions").getImage(), g.drawImage(FlappyBird.textures.get("instructions").getImage(),
textures.get("instructions").getX(), FlappyBird.textures.get("instructions").getX(),
textures.get("instructions").getY(), null); FlappyBird.textures.get("instructions").getY(), null);
} }
/** /**
@ -42,12 +45,9 @@ public class PlayState extends GameState {
* @param x X-coordinate to draw for mini numbers * @param x X-coordinate to draw for mini numbers
*/ */
public void drawScore (Graphics g, int drawNum, boolean mini, int x, int y) { public void drawScore (Graphics g, int drawNum, boolean mini, int x, int y) {
// Char array of digits // Char array of digits
char[] digits = ("" + drawNum).toCharArray(); char[] digits = ("" + drawNum).toCharArray();
int digitCount = digits.length;
// Calculate width for numeric textures // Calculate width for numeric textures
int takeUp = 0; int takeUp = 0;
for (char digit : digits) { for (char digit : digits) {
@ -64,17 +64,16 @@ public class PlayState extends GameState {
int drawScoreX = mini ? (x - takeUp) : (FlappyBird.WIDTH / 2 - takeUp / 2); int drawScoreX = mini ? (x - takeUp) : (FlappyBird.WIDTH / 2 - takeUp / 2);
// Draw every digit // Draw every digit
for (int i = 0; i < digitCount; i++) { for (char digit : digits) {
g.drawImage(textures.get((mini ? "mini-score-" : "score-") + digits[i]).getImage(), drawScoreX, (mini ? y : 60), null); g.drawImage(FlappyBird.textures.get((mini ? "mini-score-" : "score-") + digit).getImage(), drawScoreX, (mini ? y : 60), null);
// Size to add varies based on texture // Size to add varies based on texture
if (mini) { if (mini) {
drawScoreX += 18; drawScoreX += 18;
} else { } else {
drawScoreX += digits[i] == '1' ? 25 : 35; drawScoreX += digit == '1' ? 25 : 35;
} }
} }
} }
/** /**
@ -153,9 +152,9 @@ public class PlayState extends GameState {
// Draw the top and bottom pipes // Draw the top and bottom pipes
if (p.getY() <= 0) { if (p.getY() <= 0) {
g.drawImage(textures.get("pipe-top").getImage(), p.getX(), p.getY(), null); g.drawImage(FlappyBird.textures.get("pipe-top").getImage(), p.getX(), p.getY(), null);
} else { } else {
g.drawImage(textures.get("pipe-bottom").getImage(), p.getX(), p.getY(), null); g.drawImage(FlappyBird.textures.get("pipe-bottom").getImage(), p.getX(), p.getY(), null);
} }
// Check if bird hits pipes // Check if bird hits pipes
@ -163,15 +162,15 @@ public class PlayState extends GameState {
if (p.collide(gameBird)) { if (p.collide(gameBird)) {
// Kill bird and play sound // Kill bird and play sound
gameBird.killBird(); gameBird.killBird();
audio.hit(); FlappyBird.audio.hit();
} else { } else {
// Checks if bird passes a pipe // Checks if bird passes a pipe
if (gameBird.getX() >= p.getX() + p.WIDTH / 2) { if (gameBird.getX() >= p.getX() + Pipe.WIDTH / 2) {
// Increase score and play sound // Increase score and play sound
if (p.canAwardPoint) { if (p.canAwardPoint) {
audio.point(); FlappyBird.audio.point();
score ++; score ++;
p.canAwardPoint = false; p.canAwardPoint = false;
} }
@ -182,22 +181,21 @@ public class PlayState extends GameState {
} }
public void gameOver (Graphics g) { public void gameOver (Graphics g) {
// Game over text // Game over text
g.drawImage(textures.get("gameOverText").getImage(), g.drawImage(FlappyBird.textures.get("gameOverText").getImage(),
textures.get("gameOverText").getX(), FlappyBird.textures.get("gameOverText").getX(),
textures.get("gameOverText").getY(), null); FlappyBird.textures.get("gameOverText").getY(), null);
// Scorecard // Scorecard
g.drawImage(textures.get("scoreCard").getImage(), g.drawImage(FlappyBird.textures.get("scoreCard").getImage(),
textures.get("scoreCard").getX(), FlappyBird.textures.get("scoreCard").getX(),
textures.get("scoreCard").getY(), null); FlappyBird.textures.get("scoreCard").getY(), null);
// New highscore image // New highscore image
if (scoreWasGreater) { if (scoreWasGreater) {
g.drawImage(textures.get("newHighscore").getImage(), g.drawImage(FlappyBird.textures.get("newHighscore").getImage(),
textures.get("newHighscore").getX(), FlappyBird.textures.get("newHighscore").getX(),
textures.get("newHighscore").getY(), null); FlappyBird.textures.get("newHighscore").getY(), null);
} }
// Draw mini fonts for current and best scores // Draw mini fonts for current and best scores
@ -220,19 +218,18 @@ public class PlayState extends GameState {
// Only award a medal if they deserve it // Only award a medal if they deserve it
if (score > 9) { if (score > 9) {
g.drawImage(textures.get(medal).getImage(), g.drawImage(FlappyBird.textures.get(medal).getImage(),
textures.get(medal).getX(), FlappyBird.textures.get(medal).getX(),
textures.get(medal).getY(), null); FlappyBird.textures.get(medal).getY(), null);
} }
// Buttons // Buttons
g.drawImage(textures.get("playButton").getImage(), g.drawImage(FlappyBird.textures.get("playButton").getImage(),
textures.get("playButton").getX(), FlappyBird.textures.get("playButton").getX(),
textures.get("playButton").getY(), null); FlappyBird.textures.get("playButton").getY(), null);
g.drawImage(textures.get("leaderboard").getImage(), g.drawImage(FlappyBird.textures.get("leaderboard").getImage(),
textures.get("leaderboard").getX(), FlappyBird.textures.get("leaderboard").getX(),
textures.get("leaderboard").getY(), null); FlappyBird.textures.get("leaderboard").getY(), null);
} }
@Override @Override
@ -277,16 +274,13 @@ public class PlayState extends GameState {
// Jump and play audio even if in instructions state // Jump and play audio even if in instructions state
gameBird.jump(); gameBird.jump();
audio.jump(); FlappyBird.audio.jump();
} }
} }
} }
@Override @Override
public void handleMouseEvent(MouseEvent e) { public void handleMouseEvent(MouseEvent e) {
// Save clicked point
clickedPoint = e.getPoint();
if (gameBird.isAlive()) { if (gameBird.isAlive()) {
// Allow jump with clicks // Allow jump with clicks
@ -296,24 +290,22 @@ public class PlayState extends GameState {
// Jump and play sound // Jump and play sound
gameBird.jump(); gameBird.jump();
audio.jump(); FlappyBird.audio.jump();
}
} else { else {
// On game over screen, allow restart and leaderboard buttons // On game over screen, allow restart and leaderboard buttons
if (isTouching(textures.get("playButton").getRect())) { if (gamePanel.isTouching(FlappyBird.textures.get("playButton").getRect())) {
inStartGameState = true; inStartGameState = true;
gamePanel.setGameState(this); gamePanel.setGameState(this);
gameBird.setGameStartPos(); gameBird.setGameStartPos();
restart(); restart();
} else if (isTouching(textures.get("leaderboard").getRect())) { } else if (gamePanel.isTouching(FlappyBird.textures.get("leaderboard").getRect())) {
// Dummy message // Dummy message
JOptionPane.showMessageDialog(gamePanel, JOptionPane.showMessageDialog(gamePanel,
"We can't access the leaderboard right now!", "We can't access the leaderboard right now!",
"Oops!", "Oops!",
JOptionPane.ERROR_MESSAGE); JOptionPane.ERROR_MESSAGE);
} }
} }
} }
} }