diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..e96534f --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/img/walk/Thumbs.db b/img/walk/Thumbs.db new file mode 100644 index 0000000..4d3d7fb Binary files /dev/null and b/img/walk/Thumbs.db differ diff --git a/img/walk/p1_walk01.png b/img/walk/p1_walk01.png new file mode 100644 index 0000000..cc543a2 Binary files /dev/null and b/img/walk/p1_walk01.png differ diff --git a/img/walk/p1_walk02.png b/img/walk/p1_walk02.png new file mode 100644 index 0000000..180f2f1 Binary files /dev/null and b/img/walk/p1_walk02.png differ diff --git a/img/walk/p1_walk03.png b/img/walk/p1_walk03.png new file mode 100644 index 0000000..dbce258 Binary files /dev/null and b/img/walk/p1_walk03.png differ diff --git a/img/walk/p1_walk04.png b/img/walk/p1_walk04.png new file mode 100644 index 0000000..4a55d2c Binary files /dev/null and b/img/walk/p1_walk04.png differ diff --git a/img/walk/p1_walk05.png b/img/walk/p1_walk05.png new file mode 100644 index 0000000..67db592 Binary files /dev/null and b/img/walk/p1_walk05.png differ diff --git a/img/walk/p1_walk06.png b/img/walk/p1_walk06.png new file mode 100644 index 0000000..3b2d2c8 Binary files /dev/null and b/img/walk/p1_walk06.png differ diff --git a/img/walk/p1_walk07.png b/img/walk/p1_walk07.png new file mode 100644 index 0000000..b15b9a5 Binary files /dev/null and b/img/walk/p1_walk07.png differ diff --git a/img/walk/p1_walk08.png b/img/walk/p1_walk08.png new file mode 100644 index 0000000..d19be3e Binary files /dev/null and b/img/walk/p1_walk08.png differ diff --git a/img/walk/p1_walk09.png b/img/walk/p1_walk09.png new file mode 100644 index 0000000..eff480f Binary files /dev/null and b/img/walk/p1_walk09.png differ diff --git a/img/walk/p1_walk10.png b/img/walk/p1_walk10.png new file mode 100644 index 0000000..df9b7e7 Binary files /dev/null and b/img/walk/p1_walk10.png differ diff --git a/img/walk/p1_walk11.png b/img/walk/p1_walk11.png new file mode 100644 index 0000000..8c45b97 Binary files /dev/null and b/img/walk/p1_walk11.png differ diff --git a/out/production/final/GenericSprite.class b/out/production/final/GenericSprite.class new file mode 100644 index 0000000..4f63f0a Binary files /dev/null and b/out/production/final/GenericSprite.class differ diff --git a/out/production/final/Player.class b/out/production/final/Player.class new file mode 100644 index 0000000..2357d2c Binary files /dev/null and b/out/production/final/Player.class differ diff --git a/src/GamePanel.java b/src/GamePanel.java index c43b40d..617a083 100644 --- a/src/GamePanel.java +++ b/src/GamePanel.java @@ -9,6 +9,10 @@ Implements Runnable interface to use "threading" - let the game do two things at */ import java.awt.*; import java.awt.event.*; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; import java.util.ArrayList; import javax.swing.*; @@ -21,11 +25,30 @@ public class GamePanel extends JPanel implements Runnable, KeyListener{ public Thread gameThread; public Image image; public Graphics graphics; - public PlayerBall ball; + public Player player; + public int frame; + // keeps track of how many ticks has elapsed since last frame change + public int frameCounter = 0; + + public BufferedImage[][] spriteArray = new BufferedImage[4][11]; public static ArrayListmap = new ArrayList(); public GamePanel(){ + for (int i = 0; i < 11; i++) { + try { + BufferedImage sprite = getImage(String.format("img/walk/p1_walk%s.png", String.format("%1$2s", i+1).replace(' ', '0'))); + + spriteArray[1][i] = sprite; + spriteArray[3][i] = sprite; + spriteArray[0][i] = sprite; + spriteArray[2][i] = sprite; + + } catch (IOException e) { + e.printStackTrace(); + } + } + player = new Player(GAME_WIDTH/2, GAME_HEIGHT/2, 'W', 'A', 'S', 'D', spriteArray); //create a player controlled player, set start location to middle of screen map.add(new Tile(1000, 700)); ball = new PlayerBall(GAME_WIDTH/2, GAME_HEIGHT/2); //create a player controlled ball, set start location to middle of screen this.setFocusable(true); //make everything in this class appear on the screen @@ -34,7 +57,7 @@ public class GamePanel extends JPanel implements Runnable, KeyListener{ //add the MousePressed method from the MouseAdapter - by doing this we can listen for mouse input. We do this differently from the KeyListener because MouseAdapter has SEVEN mandatory methods - we only need one of them, and we don't want to make 6 empty methods addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { - ball.mousePressed(e); + player.mousePressed(e); } }); this.setPreferredSize(new Dimension(GAME_WIDTH, GAME_HEIGHT)); @@ -49,12 +72,14 @@ public class GamePanel extends JPanel implements Runnable, KeyListener{ //we are using "double buffering here" - if we draw images directly onto the screen, it takes time and the human eye can actually notice flashes of lag as each pixel on the screen is drawn one at a time. Instead, we are going to draw images OFF the screen, then simply move the image on screen as needed. image = createImage(GAME_WIDTH, GAME_HEIGHT); //draw off screen graphics = image.getGraphics(); - draw(graphics);//update the positions of everything on the screen + draw(graphics, frame);//update the positions of everything on the screen g.drawImage(image, 0, 0, this); //move the image on the screen } //call the draw methods in each class to update positions as things move + public void draw(Graphics g, int frame){ + frameCounter += player.draw(g, frame); public void draw(Graphics g){ ball.draw(g); for(Tile i: map){ @@ -65,31 +90,35 @@ public class GamePanel extends JPanel implements Runnable, KeyListener{ //call the move methods in other classes to update positions //this method is constantly called from run(). By doing this, movements appear fluid and natural. If we take this out the movements appear sluggish and laggy public void move(){ - ball.move(); + player.move(); } //handles all collision detection and responds accordingly public void checkCollision(){ - ball.isGrounded = false; + player.isGrounded = false; for(Tile i: map){ } //force player to remain on screen - if(ball.y<= 0){ - ball.y = 0; + if(player.y<= 0){ + player.y = 0; } + if(player.y >= GAME_HEIGHT - Player.PLAYER_HEIGHT){ + player.y = GAME_HEIGHT- Player.PLAYER_HEIGHT; if(ball.y >= GAME_HEIGHT - PlayerBall.BALL_DIAMETER){ ball.y = GAME_HEIGHT-PlayerBall.BALL_DIAMETER; ball.yVelocity = 0; ball.isGrounded = true; } + if(player.x <= 0){ + player.x = 0; if(ball.x <= 0){ ball.x = 0; } - if(ball.x + PlayerBall.BALL_DIAMETER >= GAME_WIDTH){ - ball.x = GAME_WIDTH-PlayerBall.BALL_DIAMETER; + if(player.x + Player.PLAYER_WIDTH >= GAME_WIDTH){ + player.x = GAME_WIDTH- Player.PLAYER_WIDTH; } } @@ -112,23 +141,34 @@ public class GamePanel extends JPanel implements Runnable, KeyListener{ move(); checkCollision(); repaint(); + if (frameCounter > 10) { + System.out.println(frameCounter); + // increment sprite image to be used and keeps it below 12 + frame = (frame + 1) % 11; + frameCounter -= 10; + } delta--; } } } - //if a key is pressed, we'll send it over to the PlayerBall class for processing + //if a key is pressed, we'll send it over to the Player class for processing public void keyPressed(KeyEvent e){ - ball.keyPressed(e); + player.keyPressed(e); } - //if a key is released, we'll send it over to the PlayerBall class for processing + //if a key is released, we'll send it over to the Player class for processing public void keyReleased(KeyEvent e){ - ball.keyReleased(e); + player.keyReleased(e); } //left empty because we don't need it; must be here because it is required to be overridded by the KeyListener interface public void keyTyped(KeyEvent e){ } + + public BufferedImage getImage(String imageLocation) throws IOException { + return ImageIO.read(new File(imageLocation)); + } + } \ No newline at end of file diff --git a/src/PlayerBall.java b/src/GenericSprite.java similarity index 95% rename from src/PlayerBall.java rename to src/GenericSprite.java index cbd6611..c33e069 100644 --- a/src/PlayerBall.java +++ b/src/GenericSprite.java @@ -7,7 +7,7 @@ In 2D GUI, basically everything is a rectangle even if it doesn't look like it! import java.awt.*; import java.awt.event.*; -public class PlayerBall extends Rectangle{ +public class GenericSprite extends Rectangle{ public double yVelocity; public double xVelocity; @@ -21,8 +21,8 @@ public class PlayerBall extends Rectangle{ public boolean downPressed = false; public boolean isGrounded = false; //constructor creates ball at given location with given dimensions - public PlayerBall(int x, int y){ - super(x, y, BALL_DIAMETER, BALL_DIAMETER); + public GenericSprite(int x, int y, int height, int width){ + super(x, y, height, width); } //called from GamePanel when any keyboard input is detected diff --git a/src/Player.java b/src/Player.java new file mode 100644 index 0000000..dc34f67 --- /dev/null +++ b/src/Player.java @@ -0,0 +1,57 @@ +/* Eric Li, ICS4U, Completed 5/29/2022 + +Paddle class defines behaviours for the left and right player-controlled paddles */ + +import java.awt.*; +import java.awt.event.KeyEvent; +import java.awt.image.BufferedImage; +import java.awt.image.ImageObserver; + +public class Player extends GenericSprite { + public final int SPEED = 5; + public static final int PLAYER_WIDTH = 8; + public static final int PLAYER_HEIGHT = 80; + public int upKey, downKey, rightKey, leftKey; + // sA[0] is -x, -y + // 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) { + super(x, y, PLAYER_HEIGHT, PLAYER_WIDTH); + + this.upKey = upKey; + this.downKey = downKey; + this.leftKey = leftKey; + this.rightKey = rightKey; + spriteArray = sprites; + } + + + + // moves paddle when key is pressed + public void keyPressed(KeyEvent e) { + super.keyPressed(e); + } + + // stops moving paddle when key is released + public void keyReleased(KeyEvent e) { + super.keyReleased(e); + } + + // calls parent + public void move() { + super.move(); + } + + public int draw(Graphics g, int frame) { + // g.setColor(Color.WHITE); + if (xVelocity == 0 && yVelocity == 0) { + g.drawImage(spriteArray[1][0], x, y, null); + return 0; + } else { + g.drawImage(spriteArray[(int)(Math.signum(xVelocity)+Math.signum(yVelocity)*2+3)/2][frame], x, y, null); + return 1; + } + } +} \ No newline at end of file