package vooga.fighter.model.objects; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import util.Location; import util.Vector; import vooga.fighter.model.ModelConstants; import vooga.fighter.model.loaders.CharacterLoader; import vooga.fighter.model.utils.Effect; import vooga.fighter.model.utils.Health; import vooga.fighter.model.utils.UpdatableLocation; /** * Represents a character in the game, as well as the character's current state * in the given session. * * @author James Wei, edited by alanni, edited by David Le * */ public class CharacterObject extends GameObject { private static final int DEGREES_180 = 180; private Map<String, AttackObject> myAttacks; private Vector myForcesApplied; private List<Effect> myActiveEffects; private Health myHealth; private List<AttackObject> myCurrentAttacks; private int myMovingDirection; private Vector myVelocity; /** * Constructs a new CharacterObject. * @param charName is the String name of the character (for use by loader) * @param center is the location to create the character * @param pathHierarchy is the path to the game's resources folder */ public CharacterObject(String charName, UpdatableLocation center, String pathHierarchy) { super(); myAttacks = new HashMap<String, AttackObject>(); myActiveEffects = new ArrayList<Effect>(); myHealth = new Health(); myMovingDirection = ModelConstants.RIGHT; myCurrentAttacks = new ArrayList<AttackObject>(); setLoader(new CharacterLoader(charName, this, pathHierarchy)); setHealth(getProperty(ModelConstants.MAXHEALTH_PROPERTY)); setToDefaultState(); getCurrentState().setLooping(true); setLocation(center); myVelocity = getLocation().getVelocity(); setImageData(); } /** * Updates the character for one game loop cycle. Applies effects currently * active on the character. */ @Override public void completeUpdate() { for (int i=0; i<myActiveEffects.size(); i++) { Effect effect = myActiveEffects.get(i); effect.update(); if (effect.hasEnded()) { removeActiveEffect(effect); } } } /** * Calls GameObject's updateState() method as well as sets the default state to stand * if no other state actions are going on. */ @Override public void updateState() { super.updateState(); if (getCurrentState().hasCompleted()) { setCurrentState(ModelConstants.STAND); } } /** * Adds an effect to this character's list of active effects. * @param effect is the effect to add */ public void addActiveEffect(Effect effect) { effect.setOwner(this); myActiveEffects.add(effect); } /** * Removes an effect from this character's list of active effects. * @param effect is the effect to remove */ public void removeActiveEffect(Effect effect) { myActiveEffects.remove(effect); } /** * Returns list of currently active effects on this character. */ public List<Effect> getActiveEffects() { return myActiveEffects; } /** * Returns the mass for character */ public int getMass() { return getProperty(ModelConstants.MASS_PROPERTY); } /** * Returns the speed of the character */ public Vector getVelocity() { return myVelocity; } /** * Adds an AttackObject to the list of attacks available for this character. * Note that this attack will not be added to the list of game objects in a * level, thus it will not update and should be used solely for generating * other attack objects as needed. Overwrites any existing attack. * @param key is the String key used to identify the attack * @param object is the AttackObject to add */ public void addAttack(String key, AttackObject object) { myAttacks.put(key, object); } /** * Creates and returns an attack object based on a given identifier. Returns null * if the specified attack does not exist. * * @param key is the String key used to identify the attack */ public AttackObject createAttack(String key) { if (myAttacks.containsKey(key)) { Location charLocation = getLocation().getLocation(); UpdatableLocation newLocation = new UpdatableLocation(charLocation.getX(), charLocation.getY()); return new AttackObject(myAttacks.get(key), newLocation); } else { return null; } } /** * Returns the health of the character. */ public Health getHealth() { return myHealth; } /** * Returns whether or not the character has remaining health. */ public boolean hasHealthRemaining() { return myHealth.hasHealthRemaining(); } /** * Sets the health of the character * @param amount is the amount of health to set to */ public void setHealth(int amount) { myHealth.setHealth(amount); } /** * Changes the player's health by a given amount. Positive input raises it, and * negative input decreases it. Returns health remaining. * @param amount is the amount to change health by */ public int changeHealth(int amount) { return myHealth.changeHealth(amount); } /** * Creates and returns a new AttackObject by cloning the object identified * by the given key in the attacks map. * @param key is the String key identifying the attack to create */ public AttackObject attack(String key) { setCurrentState(key); AttackObject newAttack = createAttack(key); newAttack.setOwner(this); return newAttack; } /** * Moves in given direction at speed of character * @param direction is the angle in degrees to move in */ public void move(int direction) { myMovingDirection = direction; getLocation().translate(new Vector(direction, getProperty(ModelConstants.MOVESPEED_PROPERTY))); } /** * Makes the character move back if it runs into another character or * environment object. */ public void moveBack() { myVelocity.setMagnitude(myForcesApplied.getMagnitude()); reverseVelocity(); getLocation().translate(myVelocity); } /** * Gets the direction the character is moving */ public int getMovingDirection() { return myMovingDirection; } /** * Will add jump method */ public void jump() { getLocation().addAcceleration(new Vector(ModelConstants.UP, getProperty(ModelConstants.JUMPFACTOR_PROPERTY))); } /** * Returns list of all attackObjects */ public List<AttackObject> getAttackObjects() { return myCurrentAttacks; } /** * Reverse the direction of the given vector */ public void reverseVelocity() { myVelocity.setDirection(myVelocity.getDirection() - DEGREES_180); } /** * Sets the applied forces acting on a character object * @param sumOfForces is the total set of forces being applied to this object */ public void setAppliedForces(Vector sumOfForces) { myForcesApplied = sumOfForces; } /** * Gets the attackobjects of characters */ public Map<String, AttackObject> getAttackMapping(){ return myAttacks; } }