package com.opticalcobra.storybear.game; import java.awt.Point; import java.sql.SQLException; import java.util.LinkedList; import java.awt.Component; import javax.swing.ImageIcon; import javax.swing.JLabel; import com.opticalcobra.storybear.db.DBConstants; import com.opticalcobra.storybear.db.TileResult; import com.opticalcobra.storybear.exceptions.ImageNotFoundException; import com.opticalcobra.storybear.res.Imagelib; import com.opticalcobra.storybear.main.Ringbuffer; import com.opticalcobra.storybear.res.Ressources; /** * * SINGLETON * */ public class Hero extends JLabel{ private static Hero hero = null; private int width = 0; private LinkedList<TileResult> tileQue; public LinkedList<TileResult> getTileQue() { return tileQue; } private Imagelib imageLib = Imagelib.getInstance(); private char type; //shows which kind of hero it is, eg. bear, ... //Jump Attributes private boolean inADoubleJump = false; private double jumpSpeed = 0; private boolean inRunFreazing = false; private boolean justSpawned = false; private boolean walkinLeft = false; private boolean normalWalk = true; //Run attributes private char runDirection = 'n'; private int queCounter = 0; //Es sind auf dem Screen immer 5-6 Kacheln zur freien Bewegung verf�gbar private int annimation=0; private int highscore = 0; private int currentBlock = 0; private int queCounterReduce = 0; private Hero(){ } public static Hero getInstance(){ if (hero == null){ hero = new Hero(); } return hero; } public void initHero(char type){ this.type = type; try { this.setIcon(new ImageIcon(this.imageLib.loadHeroPic("n", this.type))); } catch (ImageNotFoundException e) { System.err.println(e.getMessage()); e.printStackTrace(); } catch (SQLException e) { System.err.println(e.getMessage()); e.printStackTrace(); } catch (NullPointerException e) { System.err.println(e.getMessage()); e.printStackTrace(); } if (type == 'f'){ width = Ressources.CHARACTERWIDTHFAIRY; } else{ width = Ressources.CHARACTERWIDTH; } this.setBounds(Ressources.CHARACTERSPAWNPOSITIONX, DBConstants.LEVELHEIGHTZERO - Ressources.CHARACTERHEIGHT, width, Ressources.CHARACTERHEIGHT); } /** * let hero do, whatever he has to do * @author Martika & Tobias */ public void heroStep(int stepCounterLayer){ ImageIcon image; this.queCounter = (stepCounterLayer/Ressources.RASTERSIZE) + (this.getLocation().x/Ressources.RASTERSIZE) + ((this.getLocation().x%Ressources.RASTERSIZE)+(stepCounterLayer%Ressources.RASTERSIZE))/Ressources.RASTERSIZE + this.queCounterReduce; this.currentBlock = (stepCounterLayer/Ressources.RASTERSIZE) + (this.getLocation().x/Ressources.RASTERSIZE) + ((this.getLocation().x%Ressources.RASTERSIZE)+(stepCounterLayer%Ressources.RASTERSIZE))/Ressources.RASTERSIZE; //bear looks in a direction try { if(!isInAJump()&&runDirection != 'n'){ image = new ImageIcon(this.imageLib.loadHeroPic(runDirection+(Math.abs(annimation/2)+""), this.type)); } else if(runDirection == 'n'){ image = new ImageIcon(this.imageLib.loadHeroPic(isInAJump()?"j":"n", this.type)); } else { image = new ImageIcon(this.imageLib.loadHeroPic("j"+runDirection, this.type)); } this.setIcon(image); annimation=annimation>=8?-6:annimation+1; } catch (ImageNotFoundException e) { System.err.println(e.getMessage()); e.printStackTrace(); } catch (SQLException e) { System.err.println(e.getMessage()); e.printStackTrace(); } if (isInAJump()){ jump(); if(runDirection != 'n'){ justSpawned = false; run(stepCounterLayer); } } else{ if(runDirection == 'r' && tileQue.get(queCounter).isWalkable() || runDirection == 'l' && tileQue.get(queCounter).isWalkable()){ run(stepCounterLayer); justSpawned = false; } } if (!tileQue.get(queCounter).isWalkable() && !isInAJump()){ spawnBack(); } } /** * @author Martika */ private void spawnBack() { //decrese the score when you make a mistake this.highscore -= Ressources.SCOREDECREASEAFTERMISTAKE; if(this.highscore < 0) this.highscore = 0; inRunFreazing = false; int counter = 0; while (!tileQue.get(queCounter).isWalkable()){ queCounter--; counter ++; } if (super.getLocation().x - counter * Ressources.RASTERSIZE < 0){ queCounter = queCounter + counter; counter = 0; while (!tileQue.get(queCounter).isWalkable()){ queCounter++; counter ++; } setLocation(super.getLocation().x + (counter * Ressources.RASTERSIZE), tileQue.get(queCounter).getTileHeight()-Ressources.CHARACTERHEIGHT); } else{ setLocation(super.getLocation().x - (counter * Ressources.RASTERSIZE), tileQue.get(queCounter).getTileHeight()-Ressources.CHARACTERHEIGHT); } justSpawned = true; } /** * starts the jump of hero by pressing keys * @author Martika & Tobias */ public void startJump(){ if (!inADoubleJump){ if (isInAJump()){ inADoubleJump = true; } jumpSpeed = Ressources.SPEEDCONSTANT; } } /** * @author Miriam * execution of the jump */ private void jump(){ int posX = super.getLocation().x; int posY = super.getLocation().y; //Collision with collectables if(this.tileQue.get(queCounter).getInteractionObjectLabel() != null){ if((this.tileQue.get(queCounter).getInteractionObjectLabel().getLocationOnScreen().x <= this.getLocation().x) && (this.tileQue.get(queCounter).getInteractionObjectLabel().getLocationOnScreen().x + Ressources.CONTAINERCOLLECTABLE >= this.getLocation().x) && (this.tileQue.get(queCounter).getInteractionObjectLabel().getLocationOnScreen().y <= this.getLocation().y + this.getHeight()/2) && (this.tileQue.get(queCounter).getInteractionObjectLabel().getLocationOnScreen().y + Ressources.CONTAINERCOLLECTABLE >= this.getLocation().y + this.getHeight()/2)){ this.tileQue.get(queCounter).getInteractionObjectLabel().setVisible(false); this.tileQue.get(queCounter).setInteractionObjectLabel(null); this.highscore += Ressources.SCOREPERCOLLECTABLE; } } jumpSpeed = jumpSpeed - Ressources.JUMPCONSTANTY; posY = (int) (posY - jumpSpeed); //Rangecheck --> don't run out of window if (posY < 0) posY = 0; else if (posY > (Ressources.WINDOW.height - Ressources.CHARACTERHEIGHT)){ posY = Ressources.WINDOW.height - Ressources.CHARACTERHEIGHT; jumpSpeed = 0; inADoubleJump = false; } setLocation(posX, posY); //Reaching the current Levelheight if(getLocation().y >= tileQue.get(queCounter).getTileHeight() - Ressources.CHARACTERHEIGHT){ setLocation(super.getLocation().x, tileQue.get(queCounter).getTileHeight() - Ressources.CHARACTERHEIGHT); jumpSpeed = 0; inADoubleJump = false; } } /** * @author Miriam */ public void run(int stepCounterLayer){ int posX = super.getLocation().x; double runConstant = Ressources.RUNCONSTANT; ImageIcon image; //Collision with collectables if(this.tileQue.get(queCounter).getInteractionObjectLabel() != null){ if((this.tileQue.get(queCounter).getInteractionObjectLabel().getLocationOnScreen().x <= this.getLocation().x) && (this.tileQue.get(queCounter).getInteractionObjectLabel().getLocationOnScreen().x + Ressources.CONTAINERCOLLECTABLE >= this.getLocation().x) && (this.tileQue.get(queCounter).getInteractionObjectLabel().getLocationOnScreen().y <= this.getLocation().y + this.getHeight()/2) && (this.tileQue.get(queCounter).getInteractionObjectLabel().getLocationOnScreen().y + Ressources.CONTAINERCOLLECTABLE >= this.getLocation().y + this.getHeight()/2)){ this.tileQue.get(queCounter).getInteractionObjectLabel().setVisible(false); this.tileQue.get(queCounter).setInteractionObjectLabel(null); this.highscore += Ressources.SCOREPERCOLLECTABLE; } } if(runDirection == 'l'){ setInRunFreazing(false); if (posX > 0){ posX -= (int) runConstant; } if (checkIfHeroReachsANewTileByWalkingLeft(stepCounterLayer, runConstant)){ if(!isInAJump()){ if(tileQue.get(queCounter).isWalkable()){ setLocation(super.getLocation().x, tileQue.get(queCounter).getTileHeight() - Ressources.CHARACTERHEIGHT); } } } walkinLeft = true; } else if(runDirection == 'r'){ if (posX + (width/2) < Ressources.RASTERSIZE*5){ posX += (int) runConstant; } if (!inRunFreazing){ if (checkIfHeroReachsANewTileByWalkingRight(stepCounterLayer, runConstant)){ if(!isInAJump()){ if(tileQue.get(queCounter).isWalkable()){ setLocation(super.getLocation().x, tileQue.get(queCounter).getTileHeight() - Ressources.CHARACTERHEIGHT); } } } } walkinLeft = false; } this.setLocation(posX, this.getLocation().y); } /** * requires that hero runs to the left * checks if hero reaches a new Tile. If yes, the height will be adjusted and the Ringbuffer refreshed * @author Martika * @param stepCounterLayer * @param runConstant */ public boolean checkIfHeroReachsANewTileByWalkingLeft(int stepCounterLayer, double runConstant){ //Ringbuffer f�r die Tiles aktuallisieren if (getLocation().x < Ressources.RASTERSIZE*5 && walkinLeft){ //Befindet sich Hero genau auf einer Kachelgrenze? if (((Ressources.RASTERSIZE - (getLocation().x + (stepCounterLayer % Ressources.RASTERSIZE)) % Ressources.RASTERSIZE)) - runConstant <= 0){ // && Ressources.RASTERSIZE*5 - getLocation().x > Ressources.RASTERSIZE - 2 *runConstant){ // && Ressources.RASTERSIZE*5 - getLocation().x < stepCounterLayer% Ressources.RASTERSIZE){ // if (((Ressources.RASTERSIZE - (getLocation().x + (stepCounterLayer % Ressources.RASTERSIZE)) % Ressources.RASTERSIZE)) - runConstant == 0 && // stepCounterLayer% Ressources.RASTERSIZE <4 && stepCounterLayer% Ressources.RASTERSIZE > 0){ // queCounter--; return true; // } } } return false; } /** * requires that hero runs to the right * checks if hero reaches a new Tile. If yes, the height will be adjusted and the Ringbuffer refreshed * @author Martika * @param stepCounterLayer * @param runConstant */ public boolean checkIfHeroReachsANewTileByWalkingRight(int stepCounterLayer, double runConstant){ if (getLocation().x < Ressources.RASTERSIZE*5){ if ((((getLocation().x + (stepCounterLayer % Ressources.RASTERSIZE)) % Ressources.RASTERSIZE) - runConstant < 0 || (Ressources.RASTERSIZE*5 - getLocation().x < runConstant && stepCounterLayer% Ressources.RASTERSIZE <4 && stepCounterLayer% Ressources.RASTERSIZE > 0)) && justSpawned == false){ if(normalWalk) // queCounter++; return true; } } normalWalk=true; return false; } /** * it looks like hero is running * @author Martika * @param currentCounterStep * @param direction */ public void runFreazing(int currentCounterStep){ if((currentCounterStep) % Ressources.RASTERSIZE == 0 || currentCounterStep ==0){ // if(!normalWalk){ // queCounter++; // } //Collision with collectables if(this.tileQue.get(queCounter).getInteractionObjectLabel() != null){ if((this.tileQue.get(queCounter).getInteractionObjectLabel().getLocationOnScreen().x <= this.getLocation().x) && (this.tileQue.get(queCounter).getInteractionObjectLabel().getLocationOnScreen().x + Ressources.CONTAINERCOLLECTABLE >= this.getLocation().x) && (this.tileQue.get(queCounter).getInteractionObjectLabel().getLocationOnScreen().y <= this.getLocation().y + this.getHeight()/2) && (this.tileQue.get(queCounter).getInteractionObjectLabel().getLocationOnScreen().y + Ressources.CONTAINERCOLLECTABLE >= this.getLocation().y + this.getHeight()/2)){ this.tileQue.get(queCounter).getInteractionObjectLabel().setVisible(false); this.tileQue.get(queCounter).setInteractionObjectLabel(null); this.highscore += Ressources.SCOREPERCOLLECTABLE; } } this.highscore += Ressources.SCOREPOINTSFORRUNNING; } normalWalk = false; } /** * @author Martika * Is Tile walkable? * @return */ public boolean isHeroAllowedToWalk(){ if (isInAJump() && runDirection != 'n'){ return true; } //Nur rechts notwendig? if (!isInAJump() && (runDirection == 'r' && tileQue.get(queCounter).isWalkable() || runDirection == 'l' && tileQue.get(queCounter).isWalkable())){ return true; } return false; } /** * is hero in a jump or not * @author Martika & Tobias * @return */ public boolean isInAJump(){ if(jumpSpeed > 0){ //jump up return true; } if (getLocation().y == tileQue.get(queCounter).getTileHeight() - Ressources.CHARACTERHEIGHT){ //current hero position is current level height return false; } else { if (jumpSpeed == 0 && getLocation().y == tileQue.get(queCounter).getTileHeight() - Ressources.CHARACTERHEIGHT){ return false; } //falling down return true; } } public boolean checkIfHeroReachedEnding(int endingBlock){ if(this.currentBlock > endingBlock){ return true; } else{ return false; } } @Override public Point getLocation(){ Point pnt = super.getLocationOnScreen(); pnt.setLocation(pnt.x+(width/2), pnt.y); return pnt; } public void setTileQue(LinkedList<TileResult> tileQue) { this.tileQue = tileQue; } public char getRunDirection() { return runDirection; } public void setRunDirection(char runDirection) { this.runDirection = runDirection; } public int getHighscore() { return highscore; } public void setHighscore(int highscore) { this.highscore = highscore; } public int getQueCounter() { return queCounterReduce; } public void setQueCounter(int queCounter) { this.queCounterReduce = queCounter; } public int getWidth() { return width; } public boolean isInRunFreazing() { return inRunFreazing; } public void setInRunFreazing(boolean inRunFreazing) { this.inRunFreazing = inRunFreazing; } public void cleanup() { hero = null; } }