package com.shade.entities.mole; import org.newdawn.slick.Animation; import org.newdawn.slick.Graphics; import org.newdawn.slick.SlickException; import org.newdawn.slick.SpriteSheet; import org.newdawn.slick.geom.Vector2f; import org.newdawn.slick.state.StateBasedGame; import com.shade.base.Entity; import com.shade.base.util.State; import com.shade.crash.CrashGeom; import com.shade.entities.Roles; import com.shade.entities.mushroom.Mushroom; import com.shade.util.Geom; /** * A mole who has zero or more mushrooms in toe but hasn't yet returned * underground. * * Working moles: + Have identified a target mushroom + Have zero or more * mushrooms attached + Will try to grab the nearest uncollected mushroom + * Return underground after a set amount of time * * @author Alexander Schearer <aschearer@gmail.com> */ public class WorkerMole implements State { private static final int WORK_TIME = 5000; private Mole mole; private Animation working; private int timer; public WorkerMole(Mole mole) throws SlickException { this.mole = mole; initResources(); } private void initResources() throws SlickException { SpriteSheet works = new SpriteSheet("entities/mole/move.png", 40, 40); working = new Animation(works, 300); working.setAutoUpdate(false); } public void enter() { working.restart(); timer = 0; } public int getRole() { return Roles.MOLE.ordinal(); } public boolean isNamed(Object o) { return o == Mole.States.WORKING; } public void onCollision(Entity obstacle) { if (obstacle.equals(mole.target)) { mole.target = null; timer = 0; } if (obstacle.getRole() == Roles.OBSTACLE.ordinal()) { mole.kill(); } } public void render(StateBasedGame game, Graphics g) { working.draw(mole.getX(), mole.getY(), mole.getWidth(), mole .getHeight()); } public void update(StateBasedGame game, int delta) { working.update(delta); testTimer(delta); testForTarget(mole); testAndMove(mole); } private void testTimer(int delta) { timer += delta; if (timer > WORK_TIME) { mole.kill(); // TODO dig a hole and escape w/ your catch } } private void testForTarget(Mole mole) { if (eligibleForWork(mole)) { mole.target = null; Util.foundTarget(mole); } } private boolean eligibleForWork(Mole mole2) { return (mole.target == null || !aMushroom(mole.target)) && mole.mushroomsCollected() < 3; } private boolean aMushroom(Mushroom target) { return (mole.target.getRole() == Roles.MUSHROOM.ordinal()); } private void testAndMove(Mole mole) { if (mole.target != null) { seekTarget(); } else { mole.nudge(mole.getXVelocity(), mole.getYVelocity()); } } private void seekTarget() { float[] d = new float[3]; d[0] = CrashGeom.distance2(mole.target, mole); d[1] = d[0]; d[2] = d[0]; // if I'm left of my target if (mole.getX() < mole.target.getX()) { d[1] = CrashGeom.distance2(mole.target, mole.getXCenter() + 800, mole.getYCenter()); } else { d[1] = CrashGeom.distance2(mole, mole.target.getXCenter() + 800, mole.target.getYCenter()); } // if I'm above my target if (mole.getY() < mole.target.getY()) { d[2] = CrashGeom.distance2(mole.target, mole.getXCenter(), mole .getYCenter() + 600); } else { d[2] = CrashGeom.distance2(mole, mole.target.getXCenter(), mole.target.getYCenter() + 600); } mole.heading = CrashGeom.calculateAngle(mole.target, mole); if (d[1] < d[0] || d[2] < d[0]) { mole.heading += Math.PI; } Vector2f v = Geom.calculateVector(.9f, mole.heading); mole.nudge(v.x, v.y); } }