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;
}
}