diff --git a/src/BackgroundImage.java b/src/BackgroundImage.java index 6dd1a73..9e64047 100644 --- a/src/BackgroundImage.java +++ b/src/BackgroundImage.java @@ -2,15 +2,16 @@ import javax.swing.*; import java.awt.*; import java.awt.image.BufferedImage; +import java.io.Serializable; -public class BackgroundImage { +public class BackgroundImage implements Serializable { public int x, y; public int width, height; public int parallaxRatio; - public BufferedImage backgroundImage; + public BufferedImageWrapper backgroundImage; public Camera camera; - public BackgroundImage(int x, int y, BufferedImage backgroundImage, int width, int height, int parallaxRatio, Camera camera) { + public BackgroundImage(int x, int y, BufferedImageWrapper backgroundImage, int width, int height, int parallaxRatio, Camera camera) { this.x = x; this.y = y; this.width = width; @@ -22,8 +23,8 @@ public class BackgroundImage { this.camera = camera; } public void draw(Graphics g){ - g.drawImage(backgroundImage, x-camera.x/parallaxRatio % width, y, width, height, null); + g.drawImage(backgroundImage.image, x-camera.x/parallaxRatio % width, y, width, height, null); // added to prevent the background image from disappearing - g.drawImage(backgroundImage, x-camera.x/parallaxRatio % width + width - 1, y, width, height, null); + g.drawImage(backgroundImage.image, x-camera.x/parallaxRatio % width + width - 1, y, width, height, null); } } diff --git a/src/BombDirectionShow.java b/src/BombDirectionShow.java index c243be3..568de43 100644 --- a/src/BombDirectionShow.java +++ b/src/BombDirectionShow.java @@ -1,7 +1,8 @@ import java.awt.*; import java.awt.image.BufferedImage; +import java.io.Serializable; -public class BombDirectionShow extends StickyBomb{ +public class BombDirectionShow extends StickyBomb implements Serializable { public BombDirectionShow(int x, int y, int xVelocity, int yVelocity) { super(x, y, xVelocity, yVelocity, null, null); WIDTH = 25; @@ -15,7 +16,7 @@ public class BombDirectionShow extends StickyBomb{ while(isMove&&loopCounter<10) { super.move(); if(isMove&&canUpdate(0,0)) { - g.drawRect(x - GamePanel.camera.x + Player.PLAYER_WIDTH / 2, y + Player.PLAYER_HEIGHT / 2, 2, 2); + g.drawRect(x - GameFrame.game.camera.x + Player.PLAYER_WIDTH / 2, y + Player.PLAYER_HEIGHT / 2, 2, 2); } loopCounter++; } diff --git a/src/BufferedImage.java b/src/BufferedImage.java deleted file mode 100644 index 7023972..0000000 --- a/src/BufferedImage.java +++ /dev/null @@ -1,40 +0,0 @@ -import javax.imageio.ImageIO; -import java.awt.image.ColorModel; -import java.awt.image.IndexColorModel; -import java.awt.image.WritableRaster; -import java.io.*; -import java.util.Hashtable; - -public class BufferedImage extends java.awt.image.BufferedImage implements Serializable { - - public BufferedImage(int width, int height, int imageType) { - super(width, height, imageType); - } - - public BufferedImage(int width, int height, int imageType, IndexColorModel cm) { - super(width, height, imageType, cm); - } - - public BufferedImage(ColorModel cm, WritableRaster raster, boolean isRasterPremultiplied, Hashtable properties) { - super(cm, raster, isRasterPremultiplied, properties); - } - - @Serial - private void writeObject(ObjectOutputStream out) throws IOException { - ImageIO.write(this, "png", out); // png is lossless - } - - @Serial - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - java.awt.image.BufferedImage temporaryImage = ImageIO.read(in); - ColorModel cm = temporaryImage.getColorModel(); - boolean isAlphaPremultiplied = cm.isAlphaPremultiplied(); - WritableRaster raster = temporaryImage.copyData(null); - // TODO: make work - setState(this, new BufferedImage(cm, raster, isAlphaPremultiplied, null)); - } - - private void setState(BufferedImage currentImage, BufferedImage newImage) { - currentImage = newImage; - } -} diff --git a/src/BufferedImageWrapper.java b/src/BufferedImageWrapper.java new file mode 100644 index 0000000..955e3d6 --- /dev/null +++ b/src/BufferedImageWrapper.java @@ -0,0 +1,38 @@ +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.IndexColorModel; +import java.awt.image.WritableRaster; +import java.io.*; +import java.util.Hashtable; + +public class BufferedImageWrapper implements Serializable { + public BufferedImage image; + public BufferedImageWrapper(int width, int height, int imageType) { + image = new BufferedImage(width, height, imageType); + } + + public BufferedImageWrapper(int width, int height, int imageType, IndexColorModel cm) { + image = new BufferedImage(width, height, imageType, cm); + } + + public BufferedImageWrapper(ColorModel cm, WritableRaster raster, boolean isRasterPremultiplied, Hashtable properties) { + image = new BufferedImage(cm, raster, isRasterPremultiplied, properties); + } + + public BufferedImageWrapper(BufferedImage image) { + this.image = image; + } + + public BufferedImageWrapper() {} + + @Serial + private void writeObject(ObjectOutputStream out) throws IOException { + ImageIO.write(image, "png", out); // png is lossless + } + + @Serial + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + image = ImageIO.read(in); + } +} diff --git a/src/FileManager.java b/src/FileManager.java index 1a72371..36afdd5 100644 --- a/src/FileManager.java +++ b/src/FileManager.java @@ -27,8 +27,13 @@ public class FileManager { } public static Object readObjectFromFile(String fileLocation, List allowedObject) throws IOException, ClassNotFoundException { + ObjectInputStream objectStream; FileInputStream fileStream = new FileInputStream(fileLocation); - SafeObjectInputStream objectStream = new SafeObjectInputStream(fileStream, allowedObject); + if (!allowedObject.contains("Any")) { + objectStream = new SafeObjectInputStream(fileStream, allowedObject); + } else { + objectStream = new ObjectInputStream(fileStream); + } return objectStream.readObject(); } diff --git a/src/GameFrame.java b/src/GameFrame.java index edb1c18..523b1e2 100644 --- a/src/GameFrame.java +++ b/src/GameFrame.java @@ -16,28 +16,34 @@ import javax.swing.*; public class GameFrame extends JFrame{ MenuPanel menu; - GamePanel game; + public static GamePanel game; SettingPanel settings; CameraPanel main; public GameFrame(){ - try { - // read previously saved controls - // SafeObjectInputStream was implemented to prevent arbitrary code execution from occurring if the save files were modified - GamePanel.middlewareArray = (ArrayList)FileManager. - readObjectFromFile("local/controls", Arrays.asList("java.util.ArrayList", "Middleware")); - } catch (IOException | ClassNotFoundException | ClassCastException | SecurityException e) { - GamePanel.middlewareArray = new ArrayList(); - } try { main = new CameraPanel(); main.setLayout(new CardLayout()); menu = new MenuPanel(main); try { - game = (GamePanel)FileManager.readObjectFromFile("local/game_state", Collections.singletonList("GamePanel")); + game = (GamePanel)FileManager.readObjectFromFile("local/game_state", Arrays.asList("Any")); + game.gameFrame = main; + game.startThread(); } catch (IOException | ClassNotFoundException | ClassCastException | SecurityException e) { + System.out.println(e); game = new GamePanel(main); //run GamePanel constructor + game.startThread(); } + /* + try { + // read previously saved controls + // SafeObjectInputStream was implemented to prevent arbitrary code execution from occurring if the save files were modified + game.middlewareArray = (ArrayList)FileManager. + readObjectFromFile("local/controls", Arrays.asList("java.util.ArrayList", "Middleware")); + } catch (IOException | ClassNotFoundException | ClassCastException | SecurityException e) { + game.middlewareArray = new ArrayList(); + } + */ settings = new SettingPanel(main); main.add(menu, "menu"); main.add(settings, "settings"); @@ -45,6 +51,7 @@ public class GameFrame extends JFrame{ } catch (IOException | SpriteException | UnsupportedAudioFileException | LineUnavailableException e) { // TODO: handle IO errors gracefully // exceptions are raised when tiles are not found or are of incorrect dimensions + throw new RuntimeException(e); } this.add(main); this.setTitle("GUI is cool!"); //set title for frame diff --git a/src/GamePanel.java b/src/GamePanel.java index 97855ba..4f8214e 100644 --- a/src/GamePanel.java +++ b/src/GamePanel.java @@ -25,12 +25,12 @@ public class GamePanel extends JPanel implements Runnable, KeyListener, Serializ public static final int GAME_WIDTH = 1225; public static final int GAME_HEIGHT = 630; - public JPanel gameFrame; + public transient JPanel gameFrame; - public Thread gameThread; - public Image image; - public Graphics graphics; - public static Player player; + public transient Thread gameThread; + public transient Image image; + public transient Graphics graphics; + public Player player; public BackgroundImage background; public int playerFrame, enemyFrame; // keeps track of how many ticks has elapsed since last frame change @@ -40,35 +40,27 @@ public class GamePanel extends JPanel implements Runnable, KeyListener, Serializ public PauseMenu pauseMenu; - public static BufferedImage[][][] playerSpriteArray = new BufferedImage[2][2][11]; - public static BufferedImage[][][] slimeSpriteArray = new BufferedImage[2][2][3]; - public static BufferedImage[] explosionArray = new BufferedImage[9]; + public BufferedImageWrapper[][][] playerSpriteArray = new BufferedImageWrapper[2][2][11]; + public BufferedImageWrapper[][][] slimeSpriteArray = new BufferedImageWrapper[2][2][3]; + public BufferedImageWrapper[] explosionArray = new BufferedImageWrapper[9]; //public static ArrayListmap = new ArrayList(); - public static Tile[][]map = new Tile[300][18]; - public static ArrayList middlewareArray = new ArrayList(); + public Tile[][]map = new Tile[300][18]; + public ArrayList middlewareArray = new ArrayList(); - public static ArrayListparticleTiles = new ArrayList(); - public static ArrayListenemy = new ArrayList(); - public static ArrayListbombs = new ArrayList<>(); + public ArrayListparticleTiles = new ArrayList(); + public ArrayListenemy = new ArrayList(); + public ArrayListbombs = new ArrayList<>(); public BombDirectionShow bombDir = null; - public static ArrayListparticles = new ArrayList(); - public static Camera camera; + public ArrayListparticles = new ArrayList(); + public Camera camera; // image imports begin here - public BufferedImage backgroundImage = getImage("img/backgrounds/pointyMountains.png"); - public BufferedImage box = getImage("img/tiles/boxes/box.png"); - public BufferedImage boxCoin = getImage("img/tiles/boxes/boxCoin.png"); - public static BufferedImage bomb; - - static { - try { - bomb = getImage("img/misc/bomb.png"); - } catch (IOException e) { - throw new RuntimeException(e); - } - } + public BufferedImageWrapper backgroundImage = new BufferedImageWrapper(getImage("img/backgrounds/pointyMountains.png")); + public BufferedImageWrapper box = new BufferedImageWrapper(getImage("img/tiles/boxes/box.png")); + public BufferedImageWrapper boxCoin = new BufferedImageWrapper(getImage("img/tiles/boxes/boxCoin.png")); + public BufferedImageWrapper bomb; public GamePanel(JPanel gameFrame) throws IOException, SpriteException, UnsupportedAudioFileException, LineUnavailableException { @@ -81,31 +73,34 @@ public class GamePanel extends JPanel implements Runnable, KeyListener, Serializ for (int i = 0; i < 11; i++) { BufferedImage sprite = getImage(String.format("img/walk/p1_walk%s.png", String.format("%1$2s", i+1).replace(' ', '0'))); - playerSpriteArray[1][0][i] = sprite; - playerSpriteArray[1][1][i] = sprite; - playerSpriteArray[0][0][i] = flipImageHorizontally(sprite); - playerSpriteArray[0][1][i] = flipImageHorizontally(sprite); + playerSpriteArray[1][0][i] = new BufferedImageWrapper(sprite); + playerSpriteArray[1][1][i] = new BufferedImageWrapper(sprite); + playerSpriteArray[0][0][i] = new BufferedImageWrapper(flipImageHorizontally(sprite)); + playerSpriteArray[0][1][i] = new BufferedImageWrapper(flipImageHorizontally(sprite)); } for (int i = 0; i < 9; i++) { - explosionArray[i] = getImage("img/misc/bomb/sonicExplosion0" + i + ".png"); + explosionArray[i] = new BufferedImageWrapper(getImage("img/misc/bomb/sonicExplosion0" + i + ".png")); } // load slime sprites from disk here // these variables were not defined above because they are temporary variables - BufferedImage[] temporarySlimeArray = {getImage("img/enemy/slime/slimeWalk1.png"), - getImage("img/enemy/slime/slimeWalk2.png"), - getImage("img/enemy/slime/slimeDead.png")}; - BufferedImage[] flippedTemporarySlimeArray = {flipImageHorizontally(getImage("img/enemy/slime/slimeWalk1.png")), - flipImageHorizontally(getImage("img/enemy/slime/slimeWalk2.png")), - flipImageHorizontally(getImage("img/enemy/slime/slimeDead.png"))}; + BufferedImageWrapper[] temporarySlimeArray = {new BufferedImageWrapper(getImage("img/enemy/slime/slimeWalk1.png")), + new BufferedImageWrapper(getImage("img/enemy/slime/slimeWalk2.png")), + new BufferedImageWrapper(getImage("img/enemy/slime/slimeDead.png"))}; + BufferedImageWrapper[] flippedTemporarySlimeArray = {new BufferedImageWrapper(flipImageHorizontally(getImage("img/enemy/slime/slimeWalk1.png"))), + new BufferedImageWrapper(flipImageHorizontally(getImage("img/enemy/slime/slimeWalk2.png"))), + new BufferedImageWrapper(flipImageHorizontally(getImage("img/enemy/slime/slimeDead.png")))}; // please note that these sprites are reversed compared to the player sprites slimeSpriteArray[0][0] = temporarySlimeArray; slimeSpriteArray[0][1] = temporarySlimeArray; slimeSpriteArray[1][0] = flippedTemporarySlimeArray; slimeSpriteArray[1][1] = flippedTemporarySlimeArray; + + // load bomb sprites + bomb = new BufferedImageWrapper(getImage("img/misc/bomb.png")); } catch (IOException e) { e.printStackTrace(); } - player = new Player(GAME_WIDTH/2, GAME_HEIGHT/2, 'W', 'A', 'S', 'D', playerSpriteArray); //create a player controlled player, set start location to middle of screenk + player = new Player(GAME_WIDTH/2, GAME_HEIGHT/2, playerSpriteArray); //create a player controlled player, set start location to middle of screenk // the height of 35 is set because it is half of the original tile height (i.e., 70px) this.setFocusable(true); //make everything in this class appear on the screen this.addKeyListener(this); //start listening for keyboard input @@ -124,9 +119,7 @@ public class GamePanel extends JPanel implements Runnable, KeyListener, Serializ public void mousePressed(MouseEvent e) { try { player.mousePressed(e); - } catch (SpriteException ex) { - throw new RuntimeException(ex); - } catch (IOException ex) { + } catch (SpriteException | IOException ex) { throw new RuntimeException(ex); } } @@ -146,12 +139,14 @@ public class GamePanel extends JPanel implements Runnable, KeyListener, Serializ } }); this.setPreferredSize(new Dimension(GAME_WIDTH, GAME_HEIGHT)); + } - - + // startThread is to be called after the game has started to avoid any issues TODO: better explanation + public void startThread() { //make this class run at the same time as other classes (without this each class would "pause" while another class runs). By using threading we can remove lag, and also allows us to do features like display timers in real time! gameThread = new Thread(this); gameThread.start(); + System.out.println(gameFrame); } //paint is a method in java.awt library that we are overriding. It is a special method - it is called automatically in the background in order to update what appears in the window. You NEVER call paint() yourself @@ -179,7 +174,7 @@ public class GamePanel extends JPanel implements Runnable, KeyListener, Serializ g2d.setPaint(Color.white); } //Don't want to draw off screen items - int xMin = Math.max(0,((GamePanel.camera.x+GAME_WIDTH)/Tile.length)-(GAME_WIDTH/(2*Tile.length))-5); + int xMin = Math.max(0,((this.camera.x+GAME_WIDTH)/Tile.length)-(GAME_WIDTH/(2*Tile.length))-5); int xMax = Math.min(map.length, 7+xMin + GAME_WIDTH/Tile.length); for(int i=xMin; i0&&GamePanel.map[x][y-1]==null) { - GamePanel.particleTiles.add(GamePanel.map[x][y]); + GameFrame.game.map[x][y].nonBombCollide = true; + GameFrame.game.map[x][y].kills = true; + if(y>0&&GameFrame.game.map[x][y-1]==null) { + GameFrame.game.particleTiles.add(GameFrame.game.map[x][y]); } } else if(file.charAt(i)=='o'){ newTile("img/tiles/boxes/steel.png"); - GamePanel.map[x][y].movable = true; + GameFrame.game.map[x][y].movable = true; } x+=1; } } public static void newTile(String filePath) throws IOException, SpriteException { - GamePanel.map[x][y]=(new SingleTile(TileX,TileY, GamePanel.getImage(filePath))); + GameFrame.game.map[x][y]=(new SingleTile(TileX,TileY, new BufferedImageWrapper(GamePanel.getImage(filePath)))); } } diff --git a/src/MenuPanel.java b/src/MenuPanel.java index 189976e..e480007 100644 --- a/src/MenuPanel.java +++ b/src/MenuPanel.java @@ -39,7 +39,7 @@ public class MenuPanel extends JPanel implements Runnable, KeyListener{ public static boolean gameStart = false; // image imports begin here - public BufferedImage backgroundImage = GamePanel.getImage("img/backgrounds/pointyMountains.png"); + public BufferedImageWrapper backgroundImage = new BufferedImageWrapper(GamePanel.getImage("img/backgrounds/pointyMountains.png")); public MenuPanel(CameraPanel gameFrame) throws IOException, SpriteException, UnsupportedAudioFileException, LineUnavailableException { this.gameFrame = gameFrame; @@ -148,7 +148,7 @@ public class MenuPanel extends JPanel implements Runnable, KeyListener{ //if a key is pressed, we'll send it over to the Player class for processing public void keyPressed(KeyEvent e) { - e = UtilityFunction.intercept(e, GamePanel.middlewareArray); + e = UtilityFunction.intercept(e, GameFrame.game.middlewareArray); if (e.getKeyCode() == KeyEvent.VK_ENTER) { if(textBoxArray.get(currentBox).id.equals("game")){ gameStart = true; diff --git a/src/NonPlayer.java b/src/NonPlayer.java index 124e923..b49f630 100644 --- a/src/NonPlayer.java +++ b/src/NonPlayer.java @@ -7,8 +7,9 @@ import javax.sound.sampled.UnsupportedAudioFileException; import java.awt.*; import java.awt.image.BufferedImage; import java.io.IOException; +import java.io.Serializable; -public class NonPlayer extends GenericSprite { +public class NonPlayer extends GenericSprite implements Serializable { public final int SPEED = 3; // please note that these are not static, in contrast to the player class, as different enemies will have different heights public int npcWidth; @@ -23,8 +24,8 @@ public class NonPlayer extends GenericSprite { public double fadeCounter; // private final Sound bump; - public BufferedImage[][][] spriteArray; - public NonPlayer(int x, int y, BufferedImage[][][] sprites, int npcWidth, int npcHeight, int health) throws UnsupportedAudioFileException, LineUnavailableException, IOException { + public BufferedImageWrapper[][][] spriteArray; + public NonPlayer(int x, int y, BufferedImageWrapper[][][] sprites, int npcWidth, int npcHeight, int health) throws UnsupportedAudioFileException, LineUnavailableException, IOException { super(x, y, npcHeight, npcWidth); // bump = new Sound("sound/bump.wav"); this.health = health; @@ -49,7 +50,7 @@ public class NonPlayer extends GenericSprite { public void update(){ - realX = x-GamePanel.camera.x; + realX = x-GameFrame.game.camera.x; } public void move(){ if (isDead) { @@ -88,21 +89,16 @@ public class NonPlayer extends GenericSprite { frame %= spriteArray[0][0].length - 1; currentXDirection = (int)(Math.signum(xVelocity) + 1) / 2; currentYDirection = (int)(Math.signum(yVelocity) + 1) / 2; - // x-GamePanel.camera.x is used as the camera doesn't follow NPCs - g.drawImage(spriteArray[currentXDirection][currentYDirection][frame], x-GamePanel.camera.x, y, null); + // x-GameFrame.game.camera.x is used as the camera doesn't follow NPCs + g.drawImage(spriteArray[currentXDirection][currentYDirection][frame].image, x-GameFrame.game.camera.x, y, null); return 1; } else { - try { - ((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) fadeCounter)); - g.drawImage(spriteArray[currentXDirection][currentYDirection][spriteArray[0][0].length - 1], x - GamePanel.camera.x, (int) (y + HEIGHT / 1.7), null); - // reset composite to not affect other sprites being drawn - ((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1)); - fadeCounter -= 0.01; - return 0; - }catch(Exception e){ - return 0; - } - + ((Graphics2D)g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float)fadeCounter)); + g.drawImage(spriteArray[currentXDirection][currentYDirection][spriteArray[0][0].length-1].image, x-GameFrame.game.camera.x, (int)(y+HEIGHT/1.7), null); + // reset composite to not affect other sprites being drawn + ((Graphics2D)g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1)); + fadeCounter -= 0.01; + return 0; } } } \ No newline at end of file diff --git a/src/Particle.java b/src/Particle.java index 7525446..c6e52e3 100644 --- a/src/Particle.java +++ b/src/Particle.java @@ -1,8 +1,9 @@ import java.awt.*; import java.awt.image.BufferedImage; import java.io.IOException; +import java.io.Serializable; -public class Particle extends GenericSprite{ +public class Particle extends GenericSprite implements Serializable { public static final int small = 3; public static final int big = 10; @@ -12,13 +13,13 @@ public class Particle extends GenericSprite{ public int lifeSpan = 10; - public BufferedImage sprite; + public BufferedImageWrapper sprite; public Particle(int x, int y, int xVelocity, int yVelocity, int length, String filePath) throws IOException { super(x,y,length, length); this.xVelocity = xVelocity; this.yVelocity = yVelocity; - sprite = GamePanel.getImage(filePath); + sprite = new BufferedImageWrapper(GamePanel.getImage(filePath)); } public void move(){ x+=xVelocity; @@ -26,7 +27,7 @@ public class Particle extends GenericSprite{ yVelocity+=0.5; } public void draw(Graphics g){ - g.drawImage(sprite,x-GamePanel.camera.x,y,WIDTH,HEIGHT, null); + g.drawImage(sprite.image,x-GameFrame.game.camera.x,y,WIDTH,HEIGHT, null); } } diff --git a/src/PauseMenu.java b/src/PauseMenu.java index 1b7e64c..9f289cd 100644 --- a/src/PauseMenu.java +++ b/src/PauseMenu.java @@ -1,6 +1,7 @@ import java.awt.*; +import java.io.Serializable; -public class PauseMenu extends TextBox { +public class PauseMenu extends TextBox implements Serializable { public PauseMenu(int y, int textYOffset, int xWidth, int yHeight, int totalWidth, Font font, String text) { super(y, xWidth, yHeight, totalWidth, font, text, null); this.y -= textYOffset; diff --git a/src/Player.java b/src/Player.java index d77f550..c322093 100644 --- a/src/Player.java +++ b/src/Player.java @@ -18,11 +18,10 @@ public class Player extends GenericSprite { public static final int steelReachRange = 3*Tile.length; public int lastXDirection, lastYDirection, lastFrame; - public int upKey, downKey, rightKey, leftKey; public static final int walkSpeedCap = 5; public boolean alive; - private final Sound jump; + private transient final Sound jump = new Sound("sound/jump.wav"); public static int mouseX; public static int mouseY; @@ -38,14 +37,10 @@ public class Player extends GenericSprite { // sA[1] is x, -y // sA[2] is -x, y // sA[3] is x, y - public BufferedImage[][][] spriteArray; - public Player(int x, int y, int upKey, int downKey, int leftKey, int rightKey, BufferedImage[][][] sprites) throws UnsupportedAudioFileException, LineUnavailableException, IOException { + public BufferedImageWrapper[][][] spriteArray; + public Player(int x, int y, BufferedImageWrapper[][][] sprites) throws UnsupportedAudioFileException, LineUnavailableException, IOException { super(x, y, PLAYER_HEIGHT, PLAYER_WIDTH); - jump = new Sound("sound/jump.wav"); - this.upKey = upKey; - this.downKey = downKey; - this.leftKey = leftKey; - this.rightKey = rightKey; + // jump = new Sound("sound/jump.wav"); spriteArray = sprites; alive = true; isPlayer = true; @@ -102,21 +97,21 @@ public class Player extends GenericSprite { public boolean canUpdate(double x, double y){ boolean canUpdate = true; - int lowX = Math.max(0, ((GamePanel.camera.x+GamePanel.GAME_WIDTH)/Tile.length)-4); - int highX = Math.min(lowX + 8, GamePanel.map.length); + int lowX = Math.max(0, ((GameFrame.game.camera.x+GamePanel.GAME_WIDTH)/Tile.length)-4); + int highX = Math.min(lowX + 8, GameFrame.game.map.length); int lowY = Math.max(0,(this.y/Tile.length)-6); - int highY = Math.min(lowY + 12, GamePanel.map[0].length); + int highY = Math.min(lowY + 12, GameFrame.game.map[0].length); for(int i=lowX; i3*Tile.length){canPlaceSteel = false; return;} + if(GameFrame.game.map[x][y]!=null&&!GameFrame.game.map[x][y].replaceAble){canPlaceSteel = false; return;}; } public void move() throws IOException { // mouseX = MouseInfo.getPointerInfo().getLocation().x; // mouseY = MouseInfo.getPointerInfo().getLocation().y; - int Tilex = (mouseX + GamePanel.camera.x + GamePanel.GAME_WIDTH / 2) / Tile.length; + int Tilex = (mouseX + GameFrame.game.camera.x + GamePanel.GAME_WIDTH / 2) / Tile.length; int Tiley = (mouseY / Tile.length); if(holdingSteel){ updatePlaceSteel(Tilex,Tiley); } if(canUpdate(xVelocity, 0)&&canUpdate(0, yVelocity)&&!canUpdate(xVelocity, yVelocity)){ - GamePanel.camera.x += -Math.signum(xVelocity); + GameFrame.game.camera.x += -Math.signum(xVelocity); } if(!canUpdate(xVelocity, 0)){ int updateAmount = 0; @@ -174,12 +169,12 @@ public class Player extends GenericSprite { while(canUpdate(updateAmount, 0)){ updateAmount++; } - GamePanel.camera.x+=updateAmount-1; + GameFrame.game.camera.x+=updateAmount-1; } else if(xVelocity<0){ while(canUpdate(updateAmount, 0)){ updateAmount--; } - GamePanel.camera.x+=updateAmount+1; + GameFrame.game.camera.x+=updateAmount+1; } //xVelocity = 0; } @@ -198,12 +193,12 @@ public class Player extends GenericSprite { } if(canUpdate(xVelocity, yVelocity)) { y = y + (int) yVelocity; - GamePanel.camera.x = GamePanel.camera.x + (int) xVelocity; + GameFrame.game.camera.x = GameFrame.game.camera.x + (int) xVelocity; } else if(canUpdate(0,yVelocity)){ y = y + (int) yVelocity; xVelocity*=0.75; } else if(canUpdate(xVelocity,0)){ - GamePanel.camera.x = GamePanel.camera.x + (int) xVelocity; + GameFrame.game.camera.x = GameFrame.game.camera.x + (int) xVelocity; } @@ -249,7 +244,7 @@ public class Player extends GenericSprite { public void reset(){ LevelManager.setLevel(LevelManager.level); - GamePanel.camera.x = LevelManager.xSpawn; + GameFrame.game.camera.x = LevelManager.xSpawn; y = LevelManager.ySpawn; holdingSteel = false; } @@ -261,28 +256,28 @@ public class Player extends GenericSprite { leftMouseDown = true; } if(e.getButton()==MouseEvent.BUTTON3) { - int x = (mouseX + GamePanel.camera.x + GamePanel.GAME_WIDTH / 2) / Tile.length; + int x = (mouseX + GameFrame.game.camera.x + GamePanel.GAME_WIDTH / 2) / Tile.length; int y = (mouseY / Tile.length); rightMouseDown = true; if (!holdingSteel) { - if (GamePanel.map[x][y] != null&&GamePanel.map[x][y].movable) { - double xDis = (this.x+WIDTH/2) - (GamePanel.map[x][y].realX+Tile.length/2); - double yDis = (this.y+HEIGHT/2) - (GamePanel.map[x][y].y+Tile.length/2); + if (GameFrame.game.map[x][y] != null&&GameFrame.game.map[x][y].movable) { + double xDis = (this.x+WIDTH/2) - (GameFrame.game.map[x][y].realX+Tile.length/2); + double yDis = (this.y+HEIGHT/2) - (GameFrame.game.map[x][y].y+Tile.length/2); double hypo = Math.sqrt(xDis*xDis+yDis*yDis); if(hypo0) { + if (GameFrame.game.bombs.size() < 3 && LevelManager.bombs>0) { LevelManager.bombs--; - GamePanel.bombs.add(new StickyBomb(GamePanel.player.x + GamePanel.camera.x + WIDTH/2, GamePanel.player.y+HEIGHT/2, - (mouseX - GamePanel.player.x) / 20, (mouseY - GamePanel.player.y) / 10, GamePanel.bomb, GamePanel.explosionArray)); + GameFrame.game.bombs.add(new StickyBomb(GameFrame.game.player.x + GameFrame.game.camera.x + WIDTH/2, GameFrame.game.player.y+HEIGHT/2, + (mouseX - GameFrame.game.player.x) / 20, (mouseY - GameFrame.game.player.y) / 10, GameFrame.game.bomb, GameFrame.game.explosionArray)); } } if(e.getButton()==MouseEvent.BUTTON3){ @@ -317,7 +312,7 @@ public class Player extends GenericSprite { } public void addParticle(int x) throws IOException { if(GlobalState.randInt(1,3)==3) { - GamePanel.particles.add(new Particle(this.x + GamePanel.camera.x + WIDTH / 2 + GlobalState.randInt(-PLAYER_WIDTH / 2, PLAYER_WIDTH / 2) + GameFrame.game.particles.add(new Particle(this.x + GameFrame.game.camera.x + WIDTH / 2 + GlobalState.randInt(-PLAYER_WIDTH / 2, PLAYER_WIDTH / 2) , (int) (y + HEIGHT * 0.95), GlobalState.randInt(-2, 2) + x, GlobalState.randInt(-4, 1), GlobalState.randInt(1, 7), "img/particles/GrassParticle.png")); } } @@ -327,13 +322,13 @@ public class Player extends GenericSprite { g.drawOval(x+WIDTH/2-steelReachRange,y+HEIGHT/2-steelReachRange, steelReachRange*2,steelReachRange*2); } if (!upPressed && !downPressed && !leftPressed && !rightPressed) { - g.drawImage(spriteArray[lastXDirection][lastYDirection][0], x-10, y, null); + g.drawImage(spriteArray[lastXDirection][lastYDirection][0].image, x-10, y, null); return 0; } else { lastXDirection = (int)(Math.signum(xVelocity) + 1) / 2; lastYDirection = (int)(Math.signum(yVelocity) + 1) / 2; lastFrame = frame; - g.drawImage(spriteArray[lastXDirection][lastYDirection][frame], x-10, y, null); + g.drawImage(spriteArray[lastXDirection][lastYDirection][frame].image, x-10, y, null); return 1; } diff --git a/src/SettingPanel.java b/src/SettingPanel.java index 1edb19d..5a61087 100644 --- a/src/SettingPanel.java +++ b/src/SettingPanel.java @@ -1,4 +1,4 @@ -/* GamePanel class acts as the main "game loop" - continuously runs the game and calls whatever needs to be called +/* GameFrame.game.class acts as the main "game loop" - continuously runs the game and calls whatever needs to be called Child of JPanel because JPanel contains methods for drawing to the screen @@ -36,9 +36,6 @@ public class SettingPanel extends MenuPanel { public int currentBox = 0; public PauseMenu pauseMenu; - // image imports begin here - public BufferedImage backgroundImage = GamePanel.getImage("img/backgrounds/pointyMountains.png"); - public SettingPanel(CameraPanel gameFrame) throws IOException, SpriteException, UnsupportedAudioFileException, LineUnavailableException { super(gameFrame); @@ -63,19 +60,19 @@ public class SettingPanel extends MenuPanel { title.draw(g,null, Color.black); for (TextBox t: textBoxArray) { oldText = t.text; - middlewareIndex = GamePanel.middlewareArray.indexOf(new Middleware(Integer.parseInt(t.id), -1)); - t.text += "(" + (middlewareIndex > -1 ? (char)GamePanel.middlewareArray.get(middlewareIndex).newCode: - GamePanel.middlewareArray.contains(new Middleware(-2, Integer.parseInt(t.id))) ? + middlewareIndex = GameFrame.game.middlewareArray.indexOf(new Middleware(Integer.parseInt(t.id), -1)); + t.text += "(" + (middlewareIndex > -1 ? (char)GameFrame.game.middlewareArray.get(middlewareIndex).newCode: + GameFrame.game.middlewareArray.contains(new Middleware(-2, Integer.parseInt(t.id))) ? "None":(char)Integer.parseInt(t.id)) + ")"; t.draw(g, null, Color.cyan); t.text = oldText; } oldText = textBoxArray.get(currentBox).text; // TODO: clean up - middlewareIndex = GamePanel.middlewareArray.indexOf(new Middleware(Integer.parseInt(textBoxArray.get(currentBox).id), -1)); + middlewareIndex = GameFrame.game.middlewareArray.indexOf(new Middleware(Integer.parseInt(textBoxArray.get(currentBox).id), -1)); // -2 was chosen as oldCode instead of -1 to prevent conflicts - textBoxArray.get(currentBox).text += "(" + (middlewareIndex > -1 ? (char)GamePanel.middlewareArray.get(middlewareIndex).newCode: - GamePanel.middlewareArray.contains(new Middleware(-2, Integer.parseInt(textBoxArray.get(currentBox).id))) ? + textBoxArray.get(currentBox).text += "(" + (middlewareIndex > -1 ? (char)GameFrame.game.middlewareArray.get(middlewareIndex).newCode: + GameFrame.game.middlewareArray.contains(new Middleware(-2, Integer.parseInt(textBoxArray.get(currentBox).id))) ? "None":(char)Integer.parseInt(textBoxArray.get(currentBox).id)) + ")"; textBoxArray.get(currentBox).draw(g, Color.gray, Color.blue); textBoxArray.get(currentBox).text = oldText; @@ -108,18 +105,18 @@ public class SettingPanel extends MenuPanel { boolean canRemove = true; while (canRemove) { // newCode is -1 as it does not matter - canRemove = GamePanel.middlewareArray.remove(new Middleware(Integer.parseInt(textBoxArray.get(currentBox).id), lastKeyCode)); + canRemove = GameFrame.game.middlewareArray.remove(new Middleware(Integer.parseInt(textBoxArray.get(currentBox).id), lastKeyCode)); } // add actual middleware - GamePanel.middlewareArray.add(new Middleware(Integer.parseInt(textBoxArray.get(currentBox).id), lastKeyCode)); + GameFrame.game.middlewareArray.add(new Middleware(Integer.parseInt(textBoxArray.get(currentBox).id), lastKeyCode)); // add middleware to redirect default key - GamePanel.middlewareArray.add(new Middleware(-1, Integer.parseInt(textBoxArray.get(currentBox).id))); + GameFrame.game.middlewareArray.add(new Middleware(-1, Integer.parseInt(textBoxArray.get(currentBox).id))); // lastKeyCode is set to -1 to prevent endless execution lastKeyCode = -1; // save new key bind to file try { - FileManager.writeObjectToFile("local/controls", GamePanel.middlewareArray); + FileManager.writeObjectToFile("local/controls", GameFrame.game.middlewareArray); } catch (IOException e) { e.printStackTrace(); } @@ -129,7 +126,7 @@ public class SettingPanel extends MenuPanel { //if a key is pressed, we'll send it over to the Player class for processing public void keyPressed(KeyEvent e) { if (!waitForKey) { - e = UtilityFunction.intercept(e, GamePanel.middlewareArray); + e = UtilityFunction.intercept(e, GameFrame.game.middlewareArray); } if (waitForKey) { if (e.getKeyCode() != KeyEvent.VK_ENTER) { diff --git a/src/SingleTile.java b/src/SingleTile.java index 454ca8b..445dc4c 100644 --- a/src/SingleTile.java +++ b/src/SingleTile.java @@ -1,18 +1,19 @@ import java.awt.*; import java.awt.image.BufferedImage; +import java.io.Serializable; -public class SingleTile extends Tile { - public BufferedImage tileImage; +public class SingleTile extends Tile implements Serializable { + public BufferedImageWrapper tileImage; - public SingleTile(int x, int y, BufferedImage tileImage) throws SpriteException { + public SingleTile(int x, int y, BufferedImageWrapper tileImage) throws SpriteException { super(x, y); - if (tileImage.getWidth() != tileImage.getHeight()) { + if (tileImage.image.getWidth() != tileImage.image.getHeight()) { throw new SpriteException(); } this.tileImage = tileImage; } public void draw(Graphics g){ - g.drawImage(tileImage, x-GamePanel.camera.x, y, length, length, null); + g.drawImage(tileImage.image, x-GameFrame.game.camera.x, y, length, length, null); } } diff --git a/src/Sound.java b/src/Sound.java index f5c24bf..9ad298e 100644 --- a/src/Sound.java +++ b/src/Sound.java @@ -1,8 +1,9 @@ import javax.sound.sampled.*; import java.io.File; import java.io.IOException; +import java.io.Serializable; -public class Sound { +public class Sound implements Serializable { private AudioInputStream audioInputStream; private Clip clip; private File file; diff --git a/src/StickyBomb.java b/src/StickyBomb.java index 89b4df5..aec0b25 100644 --- a/src/StickyBomb.java +++ b/src/StickyBomb.java @@ -2,8 +2,9 @@ import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; +import java.io.Serializable; -public class StickyBomb extends GenericSprite{ +public class StickyBomb extends GenericSprite implements Serializable { public static final int spriteLength = 35; @@ -12,8 +13,8 @@ public class StickyBomb extends GenericSprite{ public int yVelocity; public boolean isMove; public int realX; - public BufferedImage sprite ; - public BufferedImage[] explosionSpriteArray; + public BufferedImageWrapper sprite ; + public BufferedImageWrapper[] explosionSpriteArray; public int fuse; public int explosionPixel = 0; @@ -25,7 +26,7 @@ public class StickyBomb extends GenericSprite{ - public StickyBomb(int x, int y, int xVelocity, int yVelocity, BufferedImage sprite, BufferedImage[] explosionSpriteArray){ + public StickyBomb(int x, int y, int xVelocity, int yVelocity, BufferedImageWrapper sprite, BufferedImageWrapper[] explosionSpriteArray){ super(x,y,length,length); this.xVelocity = xVelocity; this.yVelocity = yVelocity; @@ -40,43 +41,43 @@ public class StickyBomb extends GenericSprite{ public void update(){ - realX = x - GamePanel.camera.x; + realX = x - GameFrame.game.camera.x; } public void explode(){ - double yDis = GamePanel.player.y+Player.PLAYER_HEIGHT/2-(y+(double)length/2); - double xDis = GamePanel.player.x+Player.PLAYER_WIDTH/2-(realX+(double)length/2); + double yDis = GameFrame.game.player.y+Player.PLAYER_HEIGHT/2-(y+(double)length/2); + double xDis = GameFrame.game.player.x+Player.PLAYER_WIDTH/2-(realX+(double)length/2); double hypo = Math.sqrt(yDis*yDis+xDis*xDis); if(hypo<300) { if (yDis != 0) { - GamePanel.player.yVelocity += 10 * (yDis) / (hypo); + GameFrame.game.player.yVelocity += 10 * (yDis) / (hypo); } if (xDis != 0) { - GamePanel.player.xVelocity += 10 * (xDis) / (hypo); + GameFrame.game.player.xVelocity += 10 * (xDis) / (hypo); } } - GamePanel.player.capSpeed(); + GameFrame.game.player.capSpeed(); alive = false; - for(int i=0; i