Ive looked at the ant simulation and copied the code into mine and edited some to see how it would work and ive run into some issues:
1. The forager continuously move in a circle and does not move around the screen
2. The pheromones just get put in one place which is in the middle of where the forager bees are going round
This is the code for the bee class, forager class and flower class
Does anyone have any idea how to make them move around normally?
public class Bee extends Actor { /** The maximum movement speed of the ant. */ private static final int SPEED = 3; /** Current movement. Defined as the offset in x and y direction moved in each step. */ private int deltaX; private int deltaY; /** The home ant hill. */ private Hive home; /** * Crtae a new creature with neutral movement (movement speed is zero). */ public Bee() { deltaX = 0; deltaY = 0; } /** * Set the home hill of this creature. */ public void setHomeHive(Hive homeHive) { home = homeHive; } /** * Get the home hill of this creature. */ public Hive getHomeHive() { return home; } /** * Walk around randomly (random direction and speed). */ public void randomWalk() { if (randomChance(25)) { deltaX = adjustSpeed(deltaX); deltaY = adjustSpeed(deltaY); } walk(); } /** * Try to walk home. Sometimes creatures get distracted or encounter small obstacles, so * they occasionally head in a different direction for a moment. */ public void walkTowardsHome() { if(home == null) { //if we do not have a home, we can not go there. return; } if (randomChance(2)) { randomWalk(); // cannot always walk straight. 2% chance to turn off course. } else { headRoughlyTowards(home); walk(); } } /** * Try to walk away from home. (Goes occasionally off course a little.) */ public void walkAwayFromHome() { if(home == null) { //if we do not have a home, we can not head away from it. return; } if (randomChance(2)) { randomWalk(); // cannot always walk straight. 2% chance to turn off course. } else { headRoughlyTowards(home); // first head towards home... deltaX = -deltaX; // ...then turn 180 degrees deltaY = -deltaY; walk(); } } /** * Adjust the walking direction to head towards the given co-ordinates. */ public void headTowards(Actor target) { deltaX = capSpeed(target.getX() - getX()); deltaY = capSpeed(target.getY() - getY()); } /** * Walk forward in the current direction with the current speed. * (Does not change direction or speed.) */ public void walk() { setLocation(getX() + deltaX, getY() + deltaY); setRotation((int) (180 * Math.atan2(deltaY, deltaX) / Math.PI)); } /** * Adjust the walking direction to head somewhat towards the given co-ordinates. This does not * always head in the same direction. The heading is slightly random (but likely to be somewhat * towards the target) to make it look more natural. */ private void headRoughlyTowards(Actor target) { int distanceX = Math.abs(getX() - target.getX()); int distanceY = Math.abs(getY() - target.getY()); boolean moveX = (distanceX > 0) && (Greenfoot.getRandomNumber(distanceX + distanceY) < distanceX); boolean moveY = (distanceY > 0) && (Greenfoot.getRandomNumber(distanceX + distanceY) < distanceY); deltaX = computeHomeDelta(moveX, getX(), target.getX()); deltaY = computeHomeDelta(moveY, getY(), target.getY()); } /** * Compute and return the direction (delta) that we should steer in when * we're on our way home. */ private int computeHomeDelta(boolean move, int current, int home) { if (move) { if (current > home) return -SPEED; else return SPEED; } else return 0; } /** * Adjust the speed randomly (start moving, continue or slow down). The * speed returned is in the range [-SPEED .. SPEED]. */ private int adjustSpeed(int speed) { speed = speed + Greenfoot.getRandomNumber(2 * SPEED - 1) - SPEED + 1; return capSpeed(speed); } /** * Make sure the speed returned is in the range [-SPEED .. SPEED]. */ private int capSpeed(int speed) { if (speed < -SPEED) return -SPEED; else if (speed > SPEED) return SPEED; else return speed; } /** * Return 'true' in exactly 'percent' number of calls. That is: a call * randomChance(25) has a 25% chance to return true. */ private boolean randomChance(int percent) { return Greenfoot.getRandomNumber(100) < percent; }
public class Forager extends Bee { /** Every how many steps can we place a pheromone drop. */ private static final int MAX_PH_LEVEL = 18; /** How long do we keep direction after finding pheromones. */ private static final int PH_TIME = 30; /** Indicate whether we have any food with us. */ private boolean carryingFlower = false; /** How much pheromone do we have right now. */ private int pheromoneLevel = MAX_PH_LEVEL; /** How well do we remember the last pheromone - larger number: more recent */ private int foundLastPheromone = 0; /** * Create an ant with a given home hill. The initial speed is zero (not moving). */ public Forager(Hive home) { setHomeHive(home); //set image of forager setImage(new GreenfootImage("foragerBee.png")); GreenfootImage image = getImage(); image.scale(image.getWidth() - 1300, image.getHeight() - 700); setImage(image); } /** * Do what an ant's gotta do. */ public void act() { if (carryingFlower) { walkTowardsHome(); handlePheromoneDrop(); checkHome(); } else { searchForFlower(); } } /** * Walk around in search of food. */ private void searchForFlower() { if (foundLastPheromone > 0) { // if we can still remember... foundLastPheromone--; walkAwayFromHome(); } else if (smellPheromone()) { walkTowardsPheromone(); } else { randomWalk(); } checkFlower(); } /** * Are we home? Drop the food if we are, and start heading back out. */ private void checkHome() { if (atHome()) { dropFlower(); } } /** * Are we home? */ private boolean atHome() { if (getHomeHive() != null) { return (Math.abs(getX() - getHomeHive().getX()) < 4) && (Math.abs(getY() - getHomeHive().getY()) < 4); } else { return false; } } /** * Is there any food here where we are? If so, take some!. */ public void checkFlower() { Flower flower = (Flower) getOneIntersectingObject(Flower.class); if (flower != null) { takeFlower(flower); } } /** * Take some food from a fool pile. */ private void takeFlower(Flower flower) { carryingFlower = true; //setImage("ant-with-food.gif"); } /** * Drop our food in the ant hill. */ private void dropFlower() { carryingFlower = false; getHomeHive().countFlower(); //setImage("ant.gif"); } /** * Check whether we can drop some pheromone yet. If we can, do it. */ private void handlePheromoneDrop() { if (pheromoneLevel == MAX_PH_LEVEL) { Pheromone ph = new Pheromone(); getWorld().addObject(ph, getX(), getY()); pheromoneLevel = 0; } else { pheromoneLevel++; } } /** * Check whether we can smell pheromones. If we can, return true, otherwise return false. */ public boolean smellPheromone() { Actor ph = getOneIntersectingObject(Pheromone.class); return (ph != null); } /** * If we can smell some pheromone, walk towards it. If not, do nothing. */ public void walkTowardsPheromone() { Actor ph = getOneIntersectingObject(Pheromone.class); if (ph != null) { headTowards(ph); walk(); if (ph.getX() == getX() && ph.getY() == getY()) { foundLastPheromone = PH_TIME; } } } }
public class Flower extends Actor { /** * Create a pile of food with an image depicting the amount. */ public Flower() { //set image of this type of flower setImage(new GreenfootImage("pinkFlower.png")); GreenfootImage image = getImage(); image.scale(image.getWidth() - 500, image.getHeight() - 500); setImage(image); } }