package model.state; import java.awt.Color; import java.awt.Graphics2D; import java.awt.event.KeyEvent; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.util.ArrayList; import java.util.Collection; import java.util.ConcurrentModificationException; import java.util.List; import java.util.ListIterator; import main.Main; import model.GameStateManager; import model.InfoPanel; import model.levels.Level; import model.objects.Ball; import model.objects.Player; import model.objects.ShootingLine; import resources.image.Images; import resources.image.Images.ImageType; public class PlayState extends State{ private Player player; private ShootingLine line; private ArrayList balls; private ArrayList levels; private InfoPanel infopanel; private int direction; private int currentlevel; private int timeleft; private long lasttime; public PlayState(GameStateManager gsm) { super("play", gsm); player = new Player(Images.getImage(ImageType.PLAYER1), 40, 550, "Janco"); infopanel = new InfoPanel(player, player); balls = new ArrayList(); readLevelsFromFiles(); playLevel(levels.get(currentlevel)); } /** Level file reading **/ /** * Read all level files from a specific directory into level objects */ private void readLevelsFromFiles(){ levels = new ArrayList<>(); File root = new File(Main.class.getResource("/model/levels").getPath()); File[] list = root.listFiles(); for ( File f : list ) { if(f.isFile() && f.getName().endsWith(".bb")){ try { levels.add(readLevel(Files.readAllLines(f.toPath()))); }catch (IOException | IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) { System.out.println("Level file corrputed"); e.printStackTrace(); } } } } /** * * @param levelfile * @return * @throws NumberFormatException * @throws IllegalArgumentException * @throws IllegalAccessException * @throws NoSuchFieldException * @throws SecurityException */ private Level readLevel(List levelfile) throws NumberFormatException, IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException{ Level level = new Level(); if(levelfile.size() == 3){ String[] ballsstrings = levelfile.get(0).split("\\|"); //split all the balls for(String ball:ballsstrings){ String[]ballstring = ball.split(","); if(ballstring.length == 7){ level.addBall(new Ball( Integer.parseInt(ballstring[0]), Integer.parseInt(ballstring[1]), (Color)Color.class.getField(ballstring[2]).get(null), Integer.parseInt(ballstring[3]), Integer.parseInt(ballstring[4]), Integer.parseInt(ballstring[5]), Double.parseDouble(ballstring[6]) ) ); } } String[] powerupsstring = levelfile.get(1).split("\\|"); level.setTime(Integer.parseInt(levelfile.get(2))); } return level; } public void playLevel(Level level){ balls.clear(); for(Ball b:level.getStartballs()){ balls.add(b.clone()); } timeleft = level.getTime(); player.reset(); line=null; lasttime = System.currentTimeMillis(); } /* INIT AND EXIT */ @Override public void init() { } @Override public void exit() { } /* UPDATE */ @Override public void update() { if(direction == 1) player.walkRight(); else if(direction == -1) player.walkLeft(); player.update(); if(line != null){ line.setLength(line.getLength()+1); if(line.getMaxHeight() < 0){ //Line hit the ceiling, so "remove" it line = null; } } //Collision detection try{ ListIterator b = balls.listIterator(); while(b.hasNext()){ Ball bal = b.next(); if(line != null && bal.hitLine(line)){ // Collision between line and ball line = null; b.remove(); b.add(new Ball(bal.getSize()-1, (int) (bal.getBounceHeight()/1.2), bal.getColor(), bal.getX(), bal.getY(), -1, Math.abs(bal.getYSpeed())*-1)); b.add(new Ball(bal.getSize()-1, (int) (bal.getBounceHeight()/1.2), bal.getColor(), bal.getX(), bal.getY(), 1, Math.abs(bal.getYSpeed())*-1)); }else if(bal.hitPlayer(player)){ // Collision between player and ball player.setHealth(player.getHealth()-1); playLevel(levels.get(currentlevel)); }else if(bal.getSize() <= 0 ){ // Remove ball from arraylist when size is 0 (not visible) b.remove(); }else{ bal.update(); } } }catch(ConcurrentModificationException e){ } timeleft -= (System.currentTimeMillis() - lasttime); if(balls.size() == 0){ playLevel(levels.get(currentlevel+=1)); }else if(timeleft < 0){ player.setHealth(player.getHealth()-1); playLevel(levels.get(currentlevel)); }else if(player.getHealth() <= 0) { int i = 1/0; } lasttime = System.currentTimeMillis(); } @Override public void paint(Graphics2D g2d) { g2d.drawImage(Images.getImage(ImageType.BACKGROUND),null,0,0); if(line != null){ line.paint(g2d); } for(Ball b: balls){ b.paint(g2d); } player.paint(g2d); infopanel.paint(g2d); } /* EVENTS */ @Override public void keyPressed(KeyEvent e) { switch(e.getKeyCode()) { case KeyEvent.VK_RIGHT: direction = 1; break; case KeyEvent.VK_LEFT: direction = -1; break; case KeyEvent.VK_SPACE: if(line == null){ line = new ShootingLine((int)player.getX()+player.getWidth()/2, 600); } } } @Override public void keyReleased(KeyEvent e) { switch(e.getKeyCode()) { case KeyEvent.VK_RIGHT: direction = 0; case KeyEvent.VK_LEFT: direction = 0; break; case KeyEvent.VK_ESCAPE: gsm.setState("menu"); break; } } @Override public void keyTyped(KeyEvent e) {}; }