What I'm trying to do is create a pause button that stops everything in the game at once. All entities are controlled via the gameThread. I have tried putting if(!gamePaused) around update and draw methods and that didn't fix it. This is my GamePanel which has the gameThread in it. Any pointers in the right direction would be a godsend. I've been working on this for hours.
`
package main;
import entity.*;
import entity.Background;
import javax.swing.*;
import java.awt.*;
public class GamePanel extends JPanel implements Runnable {
//Panel Settings
public final int originalTileSize = 16; //16x16 pixels per tile
public final int scale = 1;
public final int tileSize = originalTileSize * scale; //48x48 pixels per tile
public final int screenColums = 16;
public final int screenRows = 16;
public final int screenWidth = tileSize * screenColums; //256 pixels width
public final int screenHeight = tileSize * screenRows; //256 pixels width
public final int FPS = 40;
public boolean gameFinished = false;
public boolean gamePaused = false;
//Initialize Components
KeyHandler keyHandler = new KeyHandler();
MouseHandler mouseHandler = new MouseHandler();
public Thread gameThread;
Player player = new Player(this, this.keyHandler, this.mouseHandler);
CapePowerUp capePowerUp = new CapePowerUp(this);
HelmetPowerUp helmetPowerUp = new HelmetPowerUp(this);
Pipe pipe = new Pipe(this);
Background background = new Background(this);
public GamePanel() {
this.setPreferredSize(new Dimension(screenWidth, screenHeight));
this.setBackground(Color.BLACK);
this.setDoubleBuffered(true);
this.addKeyListener(keyHandler);
this.addMouseListener(mouseHandler);
this.setFocusable(true);
this.setVisible(true);
}
public void startGameThread() {
gameThread = new Thread(this);
gameThread.start();
}
@Override
public void run() {
double drawInterval = 1000000000/FPS;
double nextDrawTime = System.nanoTime() + drawInterval;
while(gameThread != null) {
if(!gamePaused) {
update();
repaint();
try {
double remainingTime = nextDrawTime - System.nanoTime();
remainingTime = remainingTime / 1000000;
if (remainingTime < 0) {
remainingTime = 0;
}
Thread.sleep((long) remainingTime);
nextDrawTime += drawInterval;
} catch(InterruptedException e){
e.printStackTrace();
}
} else {
try {
while(gamePaused) {
Thread.sleep(100);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void update() {
if (gamePaused) {
return;
}
player.update();
pipe.update();
capePowerUp.update();
helmetPowerUp.update();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
if (gamePaused) {
return;
}
if(!gameFinished) {
background.draw(g2);
player.draw(g2);
pipe.draw(g2);
capePowerUp.draw(g2);
helmetPowerUp.draw(g2);
}
if(gameFinished) {
player.drawDeath(g2);
}
g2.dispose();
}
public void initializeGameSettings() {
//Set Variables Back to Default
Entity.powerUpCounter = 0;
Entity.score = 0;
Entity.canSpawnPowerUp = true;
Entity.capePowerUpEnabled = false;
Entity.helmetPowerUpEnabled = false;
Entity.collisionOn = false;
gameFinished = false;
keyHandler.spacePressed = false;
mouseHandler.mouse1Pressed = false;
mouseHandler.mouse3Pressed = false;
keyHandler.canMove = true;
mouseHandler.canMove = true;
//Re-initialize components
player.initializePlayer();
pipe.initializePipe();
capePowerUp.initializePowerUp();
helmetPowerUp.initializePowerUp();
}
}
`
Also this is my MyFrame which has the button that controls the game being paused/not.
`
package main;
import entity.Entity;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
public class MyFrame extends JFrame {
public BufferedImage playerframe0;
GamePanel gamePanel;
JButton resetButton;
JButton pauseButton;
MyFrame() {
//Gets and Sets icon for JFrame
BufferedImage image;
getImage();
image = playerframe0;
this.setIconImage(image);
//JFrame Options/Settings
this.setTitle("Flappy Leet");
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.setSize(270,270);
this.setResizable(false);
//FlowLayout for Buttons
FlowLayout experimentLayout = new FlowLayout(FlowLayout.TRAILING,0,0);
this.setLayout(experimentLayout);
//Reset Button Settings
resetButton = new JButton("Reset");
resetButton.setForeground(Color.white);
resetButton.setBackground(Color.BLACK);
resetButton.setSize(10, 10);
resetButton.setLocation(25,25);
resetButton.addActionListener(e -> gamePanel.initializeGameSettings());
resetButton.setFocusable(false);
//Reset Button Settings
pauseButton = new JButton("Pause");
pauseButton.setForeground(Color.white);
pauseButton.setBackground(Color.BLACK);
pauseButton.setSize(10, 10);
pauseButton.setLocation(25,25);
pauseButton.addActionListener(e -> gamePanel.gamePaused = !gamePanel.gamePaused);
pauseButton.setFocusable(false);
gamePanel = new GamePanel();
//Components to JFrame
this.add(pauseButton);
this.add(resetButton);
this.add(gamePanel);
this.setVisible(true);
//Starts game
gamePanel.startGameThread();
}
public void getImage() {
//Gets the image for the JFrame
try {
playerframe0 = ImageIO.read(Entity.class.getResourceAsStream("/playerframe.png"));
} catch(IOException e) {
e.printStackTrace();
}
}
}
`
Thanks for anyone who can help me with this. I'm starting to pull my hair out. If you'd like access to my Git to get a better look at the code feel free to message me with your email and I'll send you access.
I have tried setting booleans that flip each other on/off when game is paused, I have tried doing .wait() and using .notify(), I've tried using chatgpt to help me figure out the issue aswell. I feel like I'm going around in circles now. I just want the game to pause and not have the frames the game was paused to effect the player once the game is unpaused.