/* Eric Li, ICS4U, Completed 5/29/2022 Paddle class defines behaviours for the left and right player-controlled paddles */ import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.UnsupportedAudioFileException; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.awt.image.ImageObserver; import java.io.IOException; import java.util.Arrays; import java.util.LinkedList; public class Player extends GenericSprite { public final int SPEED = 5; public static final int PLAYER_WIDTH = 52; public static final int PLAYER_HEIGHT = 94; public static final int steelReachRange = 4*Tile.length; public int lastXDirection, lastYDirection, lastFrame; public static final int walkSpeedCap = 5; public boolean alive; private transient final Sound jump = new Sound("sound/jump.wav"); public static int mouseX; public static int mouseY; public boolean leftMouseDown; public boolean rightMouseDown; boolean holdingSteel; boolean canPlaceSteel; // sA[0] is -x, -y // sA[1] is x, -y // sA[2] is -x, y // sA[3] is x, y 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"); spriteArray = sprites; alive = true; isPlayer = true; leftMouseDown = false; holdingSteel = false; canPlaceSteel = false; } // moves paddle when key is pressed public void keyPressed(KeyEvent e) { if(e.getKeyCode() == KeyEvent.VK_D){ rightPressed = true; } if(e.getKeyCode() == KeyEvent.VK_A){ leftPressed = true; } if(e.getKeyCode() == KeyEvent.VK_W){ upPressed = true; } if(e.getKeyCode() == KeyEvent.VK_S){ downPressed = true; } } // stops moving paddle when key is released public void keyReleased(KeyEvent e) { if(e.getKeyCode() == KeyEvent.VK_D){ rightPressed = false; } if(e.getKeyCode() == KeyEvent.VK_A){ leftPressed = false; } if(e.getKeyCode() == KeyEvent.VK_W){ upPressed = false; } if(e.getKeyCode() == KeyEvent.VK_S){ downPressed = false; } } public boolean collide(Tile tile, double x, double y){ if(tile==null){return false;} if(!tile.collision){ return false; } if(x+WIDTH>tile.realX&&xtile.realX&&xsteelReachRange){canPlaceSteel = false; return;} if(GameFrame.game.map[x][y]!=null&&!GameFrame.game.map[x][y].replaceAble){canPlaceSteel = false; return;} if(!canReach(xx,yy)){canPlaceSteel = false; return;}; //System.out.println(realX); } public void move() throws IOException { // mouseX = MouseInfo.getPointerInfo().getLocation().x; // mouseY = MouseInfo.getPointerInfo().getLocation().y; 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)){ GameFrame.game.camera.x += -Math.signum(xVelocity); } if(!canUpdate(xVelocity, 0)){ int updateAmount = 0; if(xVelocity>0){ while(canUpdate(updateAmount, 0)){ updateAmount++; } GameFrame.game.camera.x+=updateAmount-1; } else if(xVelocity<0){ while(canUpdate(updateAmount, 0)){ updateAmount--; } GameFrame.game.camera.x+=updateAmount+1; } //xVelocity = 0; } if(!canUpdate(0, yVelocity)){ if(yVelocity>0){ while(canUpdate(0,1)){ y+=1; } isGrounded = true; } else if(yVelocity<0){ while(canUpdate(0,-1)){ y-=1; } } yVelocity = 0; } if(canUpdate(xVelocity, yVelocity)) { y = y + (int) yVelocity; 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)){ GameFrame.game.camera.x = GameFrame.game.camera.x + (int) xVelocity; } if(rightPressed){ if(isGrounded){ addParticle(-1); } if(xVelocity<5) { xVelocity += 1; } } if(leftPressed) { if(isGrounded){ addParticle(1); } if(xVelocity>-5) { xVelocity -= 1; } } if(upPressed&isGrounded){ y-=1; isGrounded = false; if(canUpdate(0,-8)) { if (jump != null) { jump.start(); } } yVelocity = -10; } xVelocity *= 0.93; if(!isGrounded) { yVelocity += 0.3; if(downPressed){ yVelocity+=1; } } if(!alive){ alive = true; reset(); } capSpeed(); } public void reset(){ LevelManager.setLevel(LevelManager.level); GameFrame.game.camera.x = LevelManager.xSpawn; y = LevelManager.ySpawn; holdingSteel = false; } public void mousePressed(MouseEvent e) throws SpriteException, IOException { canReach(1,1); mouseX = e.getX(); mouseY = e.getY(); if(e.getButton()==MouseEvent.BUTTON1) { leftMouseDown = true; } if(e.getButton()==MouseEvent.BUTTON3) { int x = (mouseX + GameFrame.game.camera.x + GamePanel.GAME_WIDTH / 2) / Tile.length; int y = (mouseY / Tile.length); rightMouseDown = true; if (!holdingSteel) { 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 (hypo xx = new LinkedList<>(); LinkedList yy = new LinkedList<>(); xx.add(pX); yy.add(pY); dis[pX][pY] = 0; vis[pX][pY] = true; while(!xx.isEmpty()){ int tempX = xx.poll(); int tempY = yy.poll(); for(int[]a: check){ try{ int newX = tempX + a[0]; int newY = tempY + a[1]; if(dis[tempX][tempY]+1<(Math.min(6,dis[newX][newY]))) { dis[newX][newY] = dis[tempX][tempY]+1; if(GameFrame.game.map[newX][newY]==null||GameFrame.game.map[newX][newY].replaceAble) { xx.add(newX); yy.add(newY); } } } catch(Exception e){ } } } if(dis[x][y]<=6){ return true; } return false; } public void mouseDragged(MouseEvent e) { mouseX = e.getX(); mouseY = e.getY(); } public void mouseMoved(MouseEvent e) { mouseX = e.getX(); mouseY = e.getY(); } public void mouseReleased(MouseEvent e) { mouseX = e.getX(); mouseY = e.getY(); if(e.getButton()==MouseEvent.BUTTON1) { leftMouseDown = false; if (GameFrame.game.bombs.size() < 3 && LevelManager.bombs>0) { LevelManager.bombs--; 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){ rightMouseDown = false; } } public void addParticle(int x) throws IOException { if(GlobalState.randInt(1,3)==3) { 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")); } } public int draw(Graphics g, int frame) { frame %= spriteArray[0][0].length; if(rightMouseDown){ 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].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].image, x-10, y, null); return 1; } } //public int BfsDis() }