Close FileManager after use, add atomic saves and saves every tick, fixed BIW flipping, add dialogue array and delayed dialogue print

master
John 2022-06-16 13:31:44 -04:00
parent 53145345a9
commit 7cbd8f780d
5 changed files with 66 additions and 13 deletions

View File

@ -61,8 +61,14 @@ public class BufferedImageWrapper implements Serializable {
flipImage = (Boolean)in.readObject(); flipImage = (Boolean)in.readObject();
o = in.readObject(); o = in.readObject();
if (o instanceof String) { if (o instanceof String) {
image = GamePanel.getImage((String)o); BufferedImage temporaryImage;
this.imageString = (String)o; this.imageString = (String)o;
temporaryImage = GamePanel.getImage(imageString);
if (flipImage) {
image = GamePanel.flipImageHorizontally(temporaryImage);
} else {
image = temporaryImage;
}
} else { } else {
image = ImageIO.read(in); image = ImageIO.read(in);
} }

View File

@ -9,7 +9,10 @@ public class DialogueMenu extends TextBox implements Serializable {
public static final int PADDING = 20; public static final int PADDING = 20;
public static final int TOP_PADDING = 10; public static final int TOP_PADDING = 10;
public static final double LINE_SPACING = 1.5; public static final double LINE_SPACING = 1.5;
public static final int FREQUENCY = 2;
public BufferedImageWrapper PORTRAIT; public BufferedImageWrapper PORTRAIT;
public int currentFrame = 0;
public int frameCounter = 0;
public DialogueMenu(int y, int yHeight, Font font, BufferedImageWrapper portrait) { public DialogueMenu(int y, int yHeight, Font font, BufferedImageWrapper portrait) {
super(y, GamePanel.GAME_WIDTH - PORTRAIT_WIDTH - PADDING*3, yHeight, 0, font, null, null); super(y, GamePanel.GAME_WIDTH - PORTRAIT_WIDTH - PADDING*3, yHeight, 0, font, null, null);
@ -18,6 +21,7 @@ public class DialogueMenu extends TextBox implements Serializable {
} }
public void drawCenteredTextBox(Graphics g, String text, Color backgroundColor, Color textColor) { public void drawCenteredTextBox(Graphics g, String text, Color backgroundColor, Color textColor) {
text = text.substring(0, currentFrame);
if (backgroundColor != null) { if (backgroundColor != null) {
g.setColor(textColor); g.setColor(textColor);
// TODO: make drawn line widths consistent // TODO: make drawn line widths consistent
@ -59,8 +63,19 @@ public class DialogueMenu extends TextBox implements Serializable {
} }
} }
public void draw(Graphics g, String text, Color backgroundColor, Color textColor) { public boolean draw(Graphics g, String text, Color backgroundColor, Color textColor) {
if (frameCounter >= FREQUENCY) {
frameCounter -= FREQUENCY;
currentFrame += 1;
}
g.setFont(font); g.setFont(font);
drawCenteredTextBox(g, text, backgroundColor, textColor); drawCenteredTextBox(g, text, backgroundColor, textColor);
frameCounter++;
if (currentFrame >= text.length()) {
currentFrame = 0;
return true;
} else {
return false;
}
} }
} }

View File

@ -34,6 +34,8 @@ public class FileManager {
} else { } else {
objectStream = new ObjectInputStream(fileStream); objectStream = new ObjectInputStream(fileStream);
} }
objectStream.close();
fileStream.close();
return objectStream.readObject(); return objectStream.readObject();
} }
@ -41,6 +43,7 @@ public class FileManager {
FileOutputStream fileStream = new FileOutputStream(fileLocation); FileOutputStream fileStream = new FileOutputStream(fileLocation);
ObjectOutputStream objectStream = new ObjectOutputStream(fileStream); ObjectOutputStream objectStream = new ObjectOutputStream(fileStream);
objectStream.writeObject(o); objectStream.writeObject(o);
System.out.println(o + " " + fileLocation); objectStream.close();
fileStream.close();
} }
} }

View File

@ -26,7 +26,7 @@ public class GameFrame extends JFrame{
main.setLayout(new CardLayout()); main.setLayout(new CardLayout());
menu = new MenuPanel(main); menu = new MenuPanel(main);
try { try {
game = (GamePanel)FileManager.readObjectFromFile("local/game_state", Arrays.asList("Any")); game = (GamePanel)FileManager.readObjectFromFile("local/game_state.dat", Arrays.asList("Any"));
game.gameFrame = main; game.gameFrame = main;
game.addUserInterface(); game.addUserInterface();
game.startThread(); game.startThread();

View File

@ -14,16 +14,21 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import java.io.Serializable; import java.io.Serializable;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException; import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.*; import javax.swing.*;
import static java.nio.file.StandardCopyOption.ATOMIC_MOVE;
public class GamePanel extends JPanel implements Runnable, KeyListener, Serializable { public class GamePanel extends JPanel implements Runnable, KeyListener, Serializable {
//dimensions of window //dimensions of window
public static final int GAME_WIDTH = 1225; public static final int GAME_WIDTH = 1225;
public static final int GAME_HEIGHT = 630; public static final int GAME_HEIGHT = 630;
public int bombCount;
public transient JPanel gameFrame; public transient JPanel gameFrame;
@ -37,9 +42,10 @@ public class GamePanel extends JPanel implements Runnable, KeyListener, Serializ
// keeps track of how many ticks has elapsed since last frame change // keeps track of how many ticks has elapsed since last frame change
public int playerFrameCounter = 0; public int playerFrameCounter = 0;
public int enemyFrameCounter = 0; public int enemyFrameCounter = 0;
public boolean isPaused, isDialogue; public boolean isPaused, isDialogue, waitForDialogue;
public PauseMenu pauseMenu; public PauseMenu pauseMenu;
public DialogueMenu dialogueMenu; public DialogueMenu dialogueMenu;
public ArrayList<String> dialogueArray = new ArrayList<String>();
public BufferedImageWrapper[][][] playerSpriteArray = new BufferedImageWrapper[2][2][11]; public BufferedImageWrapper[][][] playerSpriteArray = new BufferedImageWrapper[2][2][11];
@ -67,6 +73,7 @@ public class GamePanel extends JPanel implements Runnable, KeyListener, Serializ
public BufferedImageWrapper cloud3 = new BufferedImageWrapper(("img/backgrounds/cloud3.png")); public BufferedImageWrapper cloud3 = new BufferedImageWrapper(("img/backgrounds/cloud3.png"));
public BufferedImageWrapper bomb; public BufferedImageWrapper bomb;
public BufferedImageWrapper onePortrait = new BufferedImageWrapper(("img/dialogue/Gunther.png")); public BufferedImageWrapper onePortrait = new BufferedImageWrapper(("img/dialogue/Gunther.png"));
public String lastText;
public GamePanel(JPanel gameFrame) throws IOException, SpriteException, UnsupportedAudioFileException, LineUnavailableException { public GamePanel(JPanel gameFrame) throws IOException, SpriteException, UnsupportedAudioFileException, LineUnavailableException {
@ -78,6 +85,8 @@ public class GamePanel extends JPanel implements Runnable, KeyListener, Serializ
cloudThreeBackground = new BackgroundImage(1000, 200, cloud3, cloud2.image.getWidth(), cloud3.image.getHeight(), 5, camera); cloudThreeBackground = new BackgroundImage(1000, 200, cloud3, cloud2.image.getWidth(), cloud3.image.getHeight(), 5, camera);
pauseMenu = new PauseMenu(GAME_HEIGHT/2, 100, 400, 400, GAME_WIDTH, new Font(Font.MONOSPACED, Font.BOLD, 60), "Paused"); pauseMenu = new PauseMenu(GAME_HEIGHT/2, 100, 400, 400, GAME_WIDTH, new Font(Font.MONOSPACED, Font.BOLD, 60), "Paused");
dialogueMenu = new DialogueMenu(GAME_HEIGHT-100, 200, new Font(Font.MONOSPACED, Font.BOLD, 20), onePortrait); dialogueMenu = new DialogueMenu(GAME_HEIGHT-100, 200, new Font(Font.MONOSPACED, Font.BOLD, 20), onePortrait);
dialogueArray.add("Lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum");
dialogueArray.add("I told you so");
try { try {
// load player sprites from disk here // load player sprites from disk here
for (int i = 0; i < 11; i++) { for (int i = 0; i < 11; i++) {
@ -254,7 +263,19 @@ public class GamePanel extends JPanel implements Runnable, KeyListener, Serializ
} else if (isDialogue) { } else if (isDialogue) {
g.setColor(new Color(255, 255, 255, 100)); g.setColor(new Color(255, 255, 255, 100));
g.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT); g.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT);
dialogueMenu.draw(g, "Lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum", Color.white, Color.black); try {
if (waitForDialogue) {
System.out.println(dialogueArray);
dialogueMenu.currentFrame = dialogueArray.get(0).length();
dialogueMenu.frameCounter = 0;
dialogueMenu.draw(g, dialogueArray.get(0), Color.white, Color.black);
} else if (dialogueMenu.draw(g, dialogueArray.get(0), Color.white, Color.black)) {
waitForDialogue = true;
}
} catch (IndexOutOfBoundsException e) {
isDialogue = false;
throw new RuntimeException(e);
}
} }
} }
@ -321,6 +342,8 @@ public class GamePanel extends JPanel implements Runnable, KeyListener, Serializ
if (isNewStart) { if (isNewStart) {
LevelManager.setLevel(1); LevelManager.setLevel(1);
isDialogue = true; isDialogue = true;
} else {
LevelManager.bombs = bombCount;
} }
//the CPU runs our game code too quickly - we need to slow it down! The following lines of code "force" the computer to get stuck in a loop for short intervals between calling other methods to update the screen. //the CPU runs our game code too quickly - we need to slow it down! The following lines of code "force" the computer to get stuck in a loop for short intervals between calling other methods to update the screen.
long lastTime = System.nanoTime(); long lastTime = System.nanoTime();
@ -354,14 +377,17 @@ public class GamePanel extends JPanel implements Runnable, KeyListener, Serializ
// increment sprite image to be used and keeps it below 12 // increment sprite image to be used and keeps it below 12
playerFrame = (playerFrame + 1) % 11; playerFrame = (playerFrame + 1) % 11;
playerFrameCounter -= 5; playerFrameCounter -= 5;
// if the player has moved enough to justify a frame change, a new save will also be made
try {
FileManager.writeObjectToFile("local/game_state", this); // this is placeholder, replace with this
} catch (IOException e) {
e.printStackTrace();
}
} }
} }
// a new save is made every tick
bombCount = LevelManager.bombs;
try {
// atomic save to prevent EOF errors
FileManager.writeObjectToFile("local\\temp_state.dat", this);
Files.move(Path.of("local", "temp_state.dat"), Path.of("local", "game_state.dat"), ATOMIC_MOVE);
} catch (IOException e) {
e.printStackTrace();
}
repaint(); repaint();
delta--; delta--;
} }
@ -395,7 +421,10 @@ public class GamePanel extends JPanel implements Runnable, KeyListener, Serializ
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
isPaused = !isPaused; isPaused = !isPaused;
} else if (e.getKeyCode() == KeyEvent.VK_ENTER) { } else if (e.getKeyCode() == KeyEvent.VK_ENTER) {
isDialogue = false; dialogueMenu.currentFrame = 0;
dialogueMenu.frameCounter = 0;
dialogueArray.remove(0);
waitForDialogue = false;
} else { } else {
player.keyPressed(e); player.keyPressed(e);
} }