Add more comments
parent
1c3cecb6e3
commit
20f5d4b3b5
|
@ -1,3 +1,6 @@
|
||||||
|
// Eric Li, Charlie Zhao, ICS4U, Finished 6/19/2022
|
||||||
|
// fireball object that is shot by fireball tiles; this kills players and forces them to dodge
|
||||||
|
|
||||||
import javax.sound.sampled.LineUnavailableException;
|
import javax.sound.sampled.LineUnavailableException;
|
||||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
@ -11,7 +14,7 @@ public class FireBall extends GenericSprite{
|
||||||
|
|
||||||
private int lifeSpan;
|
private int lifeSpan;
|
||||||
|
|
||||||
|
// called every time GamePanel.updateShootingBlock is called
|
||||||
public FireBall(int x, int y, int xv, int yv, String dir,int height, int width) {
|
public FireBall(int x, int y, int xv, int yv, String dir,int height, int width) {
|
||||||
super(x, y, height, width);
|
super(x, y, height, width);
|
||||||
xVelocity = xv;
|
xVelocity = xv;
|
||||||
|
@ -30,16 +33,21 @@ public class FireBall extends GenericSprite{
|
||||||
lifeSpan = 1000;
|
lifeSpan = 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update realX position of fireball (is affected by camera.x instead of being pure x)
|
||||||
public void update(){
|
public void update(){
|
||||||
realX = x-GameFrame.game.camera.x;
|
realX = x-GameFrame.game.camera.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if fireball will collide with the player
|
||||||
public boolean collidePlayer(Player p){
|
public boolean collidePlayer(Player p){
|
||||||
if(realX+width>p.x&&realX<p.x+Player.PLAYER_WIDTH&&y-p.y<Player.PLAYER_HEIGHT&&p.y-y<height){
|
if(realX+width>p.x&&realX<p.x+Player.PLAYER_WIDTH&&y-p.y<Player.PLAYER_HEIGHT&&p.y-y<height){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// kills fireball if fireball has existed for longer than lifeSpan ticks
|
||||||
|
// moves fireball and kills it if it hits a block or a player
|
||||||
|
// kills player and resets level if it hits a player
|
||||||
public void move() throws UnsupportedAudioFileException, LineUnavailableException, IOException {
|
public void move() throws UnsupportedAudioFileException, LineUnavailableException, IOException {
|
||||||
lifeSpan--;
|
lifeSpan--;
|
||||||
if(lifeSpan<=0){
|
if(lifeSpan<=0){
|
||||||
|
@ -56,9 +64,6 @@ public class FireBall extends GenericSprite{
|
||||||
dead = true;
|
dead = true;
|
||||||
GameFrame.game.player.reset();
|
GameFrame.game.player.reset();
|
||||||
}
|
}
|
||||||
// if(y<0||y>GameFrame.game.HEIGHT){
|
|
||||||
// dead = true;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
public void draw(Graphics g) throws IOException {
|
public void draw(Graphics g) throws IOException {
|
||||||
g.drawImage(GamePanel.getImage(spritePath),x-GameFrame.game.camera.x,y,null);
|
g.drawImage(GamePanel.getImage(spritePath),x-GameFrame.game.camera.x,y,null);
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
|
// Eric Li, Charlie Zhao, ICS4U, Completed 6/20/2022
|
||||||
/* GameFrame class establishes the frame (window) for the game
|
/* GameFrame class establishes the frame (window) for the game
|
||||||
It is a child of JFrame because JFrame manages frames
|
It is a child of JFrame because JFrame manages frames
|
||||||
Runs the constructor in GamePanel class
|
Creates new JPanel child, and adds GamePanel, MenuPanel, and SettingPanel classes to it, allowing for navigation between them
|
||||||
|
Also initializes and deserializes them as necessary
|
||||||
*/
|
*/
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -25,50 +26,55 @@ public class GameFrame extends JFrame{
|
||||||
|
|
||||||
public GameFrame(){
|
public GameFrame(){
|
||||||
try {
|
try {
|
||||||
|
// CameraPanel is child of JPanel with camera object
|
||||||
main = new CameraPanel();
|
main = new CameraPanel();
|
||||||
|
// CardLayout is used to allow navigating between the different "cards" in the menu
|
||||||
main.setLayout(new CardLayout());
|
main.setLayout(new CardLayout());
|
||||||
try {
|
try {
|
||||||
game = (GamePanel)FileManager.readObjectFromFile("local/game_state.dat", Arrays.asList("Any"));
|
// attempts to read GamePanel object from file
|
||||||
|
// if it succeeds, this becomes the main game
|
||||||
|
// the second argument includes all the classes that are used by the GamePanel object
|
||||||
|
// this ensures that attempting to execute malicious code by tampering with saves will be more difficult, as payloads would have to stick to these classes
|
||||||
|
// please note that it is not a perfect mitigation though
|
||||||
|
game = (GamePanel)FileManager.readObjectFromFile("local/game_state.dat",
|
||||||
|
Arrays.asList("GamePanel", "javax.swing.JPanel", "javax.swing.JComponent", "java.awt.Container",
|
||||||
|
"java.awt.Component", "javax.swing.plaf.ColorUIResource", "java.awt.Color",
|
||||||
|
"javax.swing.plaf.FontUIResource", "java.awt.Font", "java.util.Locale", "java.awt.Dimension",
|
||||||
|
"java.awt.ComponentOrientation", "[Ljava.awt.Component;", "java.awt.FlowLayout",
|
||||||
|
"javax.swing.event.EventListenerList", "BackgroundImage", "BufferedImageWrapper",
|
||||||
|
"java.lang.Boolean", "Camera", "BombDirectionShow", "StickyBomb", "GenericSprite",
|
||||||
|
"java.awt.Rectangle", "java.util.ArrayList", "DialogueMenu", "TextBox", "NonPlayer",
|
||||||
|
"[[[LBufferedImageWrapper;", "[[LBufferedImageWrapper;", "[LBufferedImageWrapper;", "PauseMenu",
|
||||||
|
"WallSign", "[[LTile;", "[LTile;", "SingleTile", "Tile", "Particle", "Player"));
|
||||||
game.gameFrame = main;
|
game.gameFrame = main;
|
||||||
|
// shows that the game can be continued, as it was loaded from the file
|
||||||
game.isContinue = true;
|
game.isContinue = true;
|
||||||
|
// requests focus from OS; this is needed because otherwise Windows will not pass keystrokes to game
|
||||||
game.requestFocusable();
|
game.requestFocusable();
|
||||||
|
// add mouse listener to game
|
||||||
game.addMouseListener();
|
game.addMouseListener();
|
||||||
} catch (IOException | ClassNotFoundException | ClassCastException | SecurityException e) {
|
} catch (IOException | ClassNotFoundException | ClassCastException | SecurityException e) {
|
||||||
System.out.println(e);
|
// if an exception occurs during serialization, it is not a game-breaking exception; it is logged in the console and a new game is created
|
||||||
|
System.out.println("[LOG] NotAnError: " + e);
|
||||||
game = new GamePanel(main); //run GamePanel constructor
|
game = new GamePanel(main); //run GamePanel constructor
|
||||||
}
|
}
|
||||||
// delete saves to prevent unexpected behaviour
|
// start game thread to allow the game to run
|
||||||
try {
|
|
||||||
Files.deleteIfExists(Path.of("local/game_state.dat"));
|
|
||||||
Files.deleteIfExists(Path.of("local/temp_state.dat"));
|
|
||||||
} catch (FileSystemException e) {
|
|
||||||
System.out.println(e);
|
|
||||||
}
|
|
||||||
game.startThread();
|
game.startThread();
|
||||||
// save game after load to prevent lag spikes during the game
|
// save game after load to prevent lag spikes during the game
|
||||||
FileManager.writeObjectToFile("local\\temp_state.dat", game);
|
FileManager.writeObjectToFile("local\\temp_state.dat", game);
|
||||||
/*
|
// create menu screen and settings screen
|
||||||
try {
|
|
||||||
// read previously saved controls
|
|
||||||
// SafeObjectInputStream was implemented to prevent arbitrary code execution from occurring if the save files were modified
|
|
||||||
game.middlewareArray = (ArrayList<Middleware>)FileManager.
|
|
||||||
readObjectFromFile("local/controls", Arrays.asList("java.util.ArrayList", "Middleware"));
|
|
||||||
} catch (IOException | ClassNotFoundException | ClassCastException | SecurityException e) {
|
|
||||||
game.middlewareArray = new ArrayList<Middleware>();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
menu = new MenuPanel(main);
|
menu = new MenuPanel(main);
|
||||||
settings = new SettingPanel(main);
|
settings = new SettingPanel(main);
|
||||||
|
// adds all three panels to the CardLayout CameraPanel main, to allow for navigation between them
|
||||||
|
// the menu screen is added first because it is the first screen to show upon loading the game
|
||||||
main.add(menu, "menu");
|
main.add(menu, "menu");
|
||||||
main.add(settings, "settings");
|
main.add(settings, "settings");
|
||||||
main.add(game, "game");
|
main.add(game, "game");
|
||||||
} catch (IOException | SpriteException | UnsupportedAudioFileException | LineUnavailableException e) {
|
} 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);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
this.add(main);
|
this.add(main);
|
||||||
this.setTitle("GUI is cool!"); //set title for frame
|
this.setTitle("Kenney"); //set title for frame
|
||||||
// set game icon and ignore exception (failing to set icon doesn't otherwise break program)
|
// set game icon and ignore exception (failing to set icon doesn't otherwise break program)
|
||||||
try {
|
try {
|
||||||
this.setIconImage(GamePanel.getImage("img/misc/favicon.png"));
|
this.setIconImage(GamePanel.getImage("img/misc/favicon.png"));
|
||||||
|
|
|
@ -316,8 +316,6 @@ public class GamePanel extends JPanel implements Runnable, KeyListener, Serializ
|
||||||
if (particles.get(i).lifeSpan <= 0) {
|
if (particles.get(i).lifeSpan <= 0) {
|
||||||
particles.remove(i);
|
particles.remove(i);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
throw new RuntimeException(); // TODO: remove stack trace
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// show bomb trajectory preview if player is able to throw a bomb
|
// show bomb trajectory preview if player is able to throw a bomb
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/* PlayerBall class defines behaviours for the player-controlled ball
|
// Eric Li, Charlie Zhao, ICS4U, completed 6/10/2022
|
||||||
|
/* GenericSprite class defines behaviours for all objects that move
|
||||||
|
|
||||||
child of Rectangle because that makes it easy to draw and check for collision
|
child of Rectangle because that makes it easy to draw and check for collision
|
||||||
|
|
||||||
|
@ -15,7 +16,6 @@ public class GenericSprite extends Rectangle implements Serializable {
|
||||||
|
|
||||||
public double yVelocity;
|
public double yVelocity;
|
||||||
public double xVelocity;
|
public double xVelocity;
|
||||||
public final double SPEED = 20; //movement speed of ball
|
|
||||||
public final double speedCapx = 50;
|
public final double speedCapx = 50;
|
||||||
|
|
||||||
public final double speedCapy = 20;
|
public final double speedCapy = 20;
|
||||||
|
@ -29,7 +29,6 @@ public class GenericSprite extends Rectangle implements Serializable {
|
||||||
|
|
||||||
public boolean isPlayer = false;
|
public boolean isPlayer = false;
|
||||||
//constructor creates ball at given location with given dimensions
|
//constructor creates ball at given location with given dimensions
|
||||||
// TODO: reverse order of height and width
|
|
||||||
public GenericSprite(int x, int y, int height, int width){
|
public GenericSprite(int x, int y, int height, int width){
|
||||||
super(x, y, width, height);
|
super(x, y, width, height);
|
||||||
WIDTH = width;
|
WIDTH = width;
|
||||||
|
@ -63,6 +62,7 @@ public class GenericSprite extends Rectangle implements Serializable {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// caps x and y velocity at speedCapx and speedCapy respectively
|
||||||
public void capSpeed(){
|
public void capSpeed(){
|
||||||
if(xVelocity>speedCapx){
|
if(xVelocity>speedCapx){
|
||||||
xVelocity = speedCapx;
|
xVelocity = speedCapx;
|
||||||
|
@ -76,6 +76,7 @@ public class GenericSprite extends Rectangle implements Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// checks if the sprite is colliding with a tile
|
||||||
public boolean collide(Tile tile, double x, double y){
|
public boolean collide(Tile tile, double x, double y){
|
||||||
if(tile==null){return false;}
|
if(tile==null){return false;}
|
||||||
if(!tile.collision){
|
if(!tile.collision){
|
||||||
|
@ -87,6 +88,7 @@ public class GenericSprite extends Rectangle implements Serializable {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// checks if the sprite can move x in the x plane and y in the y plane
|
||||||
public boolean canUpdate(double x, double y) throws UnsupportedAudioFileException, LineUnavailableException, IOException {
|
public boolean canUpdate(double x, double y) throws UnsupportedAudioFileException, LineUnavailableException, IOException {
|
||||||
boolean canUpdate = true;
|
boolean canUpdate = true;
|
||||||
int lowX = Math.max(0, (this.x+GamePanel.GAME_WIDTH/2)/Tile.length-4);
|
int lowX = Math.max(0, (this.x+GamePanel.GAME_WIDTH/2)/Tile.length-4);
|
||||||
|
@ -109,8 +111,8 @@ public class GenericSprite extends Rectangle implements Serializable {
|
||||||
}
|
}
|
||||||
return canUpdate;
|
return canUpdate;
|
||||||
}
|
}
|
||||||
//called frequently from the GamePanel class
|
|
||||||
//draws the current location of the ball to the screen
|
//draws the current location of the sprite to the screen
|
||||||
public void draw(Graphics g) throws IOException, UnsupportedAudioFileException, LineUnavailableException {
|
public void draw(Graphics g) throws IOException, UnsupportedAudioFileException, LineUnavailableException {
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue