This site requires JavaScript, please enable it in your browser!
Greenfoot back
GP2
GP2 wrote ...

2014/5/20

canSee method not working

GP2 GP2

2014/5/20

#
Hello again greenfoot community, if anyone remembers I asked for help yesterday on this game but I have come across another issue. I now have arrows in my game that I want to destroy viruses on the screen. I want the arrow to disappear on contact with the virus and the virus to disappear after it is hit with 2 arrows. I used the canSee method for both and for some reason it works for the arrow but not for the virus. Here is the code for both the arrow and virus
public class Arrow extends Actor
{
    private int speed;
    private int arrowCounter;
    public Arrow(int x, int y, int s, int d)
    {
        setLocation(x,y);
        speed = s;
        arrowCounter = 10;
        if(d == 4)
        {
            setRotation(0);
        }
        else if(d==1)
        {
            setRotation(90);
        }
        else if(d==2)
        {
            setRotation(180);
        }
        else if(d==3)
        {
            setRotation(270);
        
        }
   }
    
    public void act()
    {
        move(speed);
        if(atWorldEdge()) //|| isOn(Virus.class))
        {
            getWorld().removeObject(this);
        }
        if(isOn(Virus.class))
        {
            speed = 0;
            arrowCounter --;
            if(arrowCounter == 0)
            {
                getWorld().removeObject(this);
            }
        }
    }
    
    public boolean isOn(Class clss)//this is the same as the canSee method
    {
        Actor actor = getOneObjectAtOffset(0, 0, clss);
        return actor != null;        
    }
    
      public boolean atWorldEdge()
    {
        if(getX() < 20 || getX() > getWorld().getWidth() - 20)
            return true;
        if(getY() < 20 || getY() > getWorld().getHeight() - 20)
            return true;
        else
            return false;
    }
}
public class Virus extends Animal
{
    private int damageCount;
    
    public Virus()
    {
        super();
        damageCount = 0;
    }
    public void act() 
    {
        checkForArrows();
        checkDeath();
    }
    public void checkForArrows()
    {
        if(canSee(Arrow.class))
        {
            damageCount++;
        }
    }
    public void checkDeath()
    {
        if(damageCount == 2)
        {
            getWorld().removeObject(this);
        }
    }
}
And here are the issues I am getting Here the arrow is touching the virus for the arrow, the method returns true however for the virus, it returns false
danpost danpost

2014/5/20

#
I think the difference in results is due to the size of the images of the actors involved. The image of the larger actor overlaps the center of the smaller one; but the image of the smaller actor does not overlap the center of the larger one. However, you should only check the two type of actors intersecting from only one of the classes and deal with both actors right then and there. Since the virus will need two 'hits' to die, the code will be more easily placed in the Virus class.
public void checkForArrows()
{
    if (canSee(Arrow.class))
    {
        eat(Arrow.class);
        damageCount++;
    }
}
You should remove from the Arrow class (as shown above): line 4, lines 36 through 44 and lines 47 through 52.
danpost danpost

2014/5/20

#
You only really need to check for death of the virus when an arrow is encountered and the damage count increases. Checking for death every act cycles is a waste of CPU time. You can remove the call to 'checkDeath' from the act method and the 'checkDeath' method itself and change your 'checkForArrows' method to this:
public void checkForArrows()
{
    if (canSee(Arrow.class))
    {
        eat(Arrow.class);
        damageCount++;
        if (damageCount == 2)
        {
            getWorld().removeObject(this);
        }
    }
}
GP2 GP2

2014/5/20

#
Thank you so much! the code worked perfectly
You need to login to post a reply.