I have a actor called BloodDemon who chases after villagers and kills them. My problem is that actors that grab the villagers first before killing them are giving me errors because the blood demon will kill the villagers while they are grabbed. How do i fix this?
Blood Demon code:
Grabber code:
import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) import java.util.ArrayList; /** * The Ambulance subclass */ public class BloodDemon extends Vehicle { private ArrayList <Villager> villagers; private Villager targetVillager; private int soulCount = 0; public BloodDemon(VehicleSpawner origin){ super(origin); // call the superclass' constructor GreenfootImage image = getImage(); image.scale(image.getWidth() - 200, image.getHeight() - 250); setImage(image); maxSpeed = 0.7; speed = maxSpeed; yOffset = 0; //enableStaticRotation(); } /** * Act - do whatever the Ambulance wants to do. This method is called whenever * the 'Act' or 'Run' button gets pressed in the environment. */ public void act() { if (targetVillager != null && targetVillager.getWorld() != null) { moveTowardVillager(); checkHitPedestrian(); } else { targetClosestVillager(); moveRandomly(); } if (getX() <= 5 || getX() >= getWorld().getWidth() - 5) { turn(180); } if (getY() <= 5 || getY() >= getWorld().getWidth() - 5) { turn(180); } /*drive(); checkHitPedestrian(); if (checkEdge()){ getWorld().removeObject(this); }*/ } private void targetClosestVillager () { double closestTargetDistance = 0; double distanceToActor; int numVil; // Get a list of all Villagers in the World, cast it to ArrayList // for easy management numVil = getWorld().getObjects(Villager.class).size(); // If any villagers are found if (numVil > 50) // If lots of villagers are found, search small area { villagers = (ArrayList)getObjectsInRange(80, Villager.class); } else if (numVil > 20) // If less villagers are found, search wider radius { villagers= (ArrayList)getObjectsInRange(180, Villager.class); } else // If even fewer villagers are found, search the whole World villagers = (ArrayList)getWorld().getObjects(Villager.class); if (villagers.size() > 0) { // set the first one as my target targetVillager = villagers.get(0); // Use method to get distance to target. This will be used // to check if any other targets are closer closestTargetDistance = VehicleWorld.getDistance (this, targetVillager); // Loop through the objects in the ArrayList to find the closest target for (Villager o : villagers) { // Cast for use in generic method //Actor a = (Actor) o; // Measure distance from me distanceToActor = VehicleWorld.getDistance(this, o); // If I find a villager closer than my current target, I will change // targets if (distanceToActor < closestTargetDistance) { targetVillager = o; closestTargetDistance = distanceToActor; } } } } private void moveRandomly() { if (Greenfoot.getRandomNumber (100) == 50) { turn (Greenfoot.getRandomNumber(360)); } else drive(); } private void moveTowardVillager() { turnTowards(targetVillager.getX(), targetVillager.getY()); drive(); } public boolean checkHitPedestrian () { Actor v = getOneIntersectingObject(Villager.class); if (v != null){ getWorld().removeObject(v); soulCount+=1; return true; } return false; } private void explode() { if (soulCount >= 20) { } } }
import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) /** * Write a description of class Grabber here. * * @author (your name) * @version (a version number or a date) */ public abstract class Grabber extends Vehicle { private Villager grabbed; public Grabber(final VehicleSpawner origin) { super(origin); } public void act() { drive(); checkHitPedestrian(); } public boolean checkHitPedestrian() { final boolean isNewlyGrabbed = tryGrab(); if (grabbed != null) { if (grabbed.getWorld() == null) { grabbed = null; } else { actionWithGrabbed(grabbed, isNewlyGrabbed); } } return grabbed != null; } public Villager getGrabbed() { return grabbed; } private boolean tryGrab() { if (grabbed == null) { final VehicleWorld world = (VehicleWorld)getWorld(); for (final Villager villager : getObjectsAtOffset((int)speed + getImage().getWidth() / 2, 0, Villager.class)) { if (!world.isGrabbed(villager)) { grabbed = villager; return true; } } } return false; } /** * Do whatever has to be done with the grabbed villager. * * This method is automatically called after checkHitPedestrian has grabbed onto a villager. * * @param grabbed the grabbed villager, must not be null. * @param isNewlyGrabbed whether the villager has just been grabbed in this act. */ protected abstract void actionWithGrabbed(final Villager grabbed, final boolean isNewlyGrabbed); public void releaseGrabbed() { grabbed = null; } }