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

2023/3/24

How do I make an actor turn into a frog upon contact with another actor

KCee KCee

2023/3/24

#
i have two actors under the same superclass "Pedestrian". One of the actors is called villager and I want him to turn into a frog upon contact with the other actor called "EvilWitch". Heres the code for the pedestrian superclass:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * A Pedestrian that tries to walk across the street
 */
public abstract class Pedestrian extends SuperSmoothMover
{
    protected double speed;
    protected double maxSpeed;
    protected int direction; // direction is always -1 or 1, for moving down or up, respectively
    protected boolean awake;
    public Pedestrian()
    {
        this(1);
    }
    
    public Pedestrian(int direction) {
        // choose a random speed
        maxSpeed = Math.random() * 2 + 1;
        speed = maxSpeed;
        // start as awake 
        awake = true;
        this.direction = direction;
    }

    /**
     * Act - do whatever the Pedestrian wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void move()
    {
        // If there is a v
        if (awake){
            if (getOneObjectAtOffset(0, (int)(direction * getImage().getHeight()/2 + (int)(direction * speed)), Vehicle.class) == null){
                //setLocation (getX(), getY() + (speed*direction));
                setLocation(getPreciseX(), getPreciseY()+speed*direction);
            }
            if (direction == -1 && getY() < 100){
                getWorld().removeObject(this);
            } else if (direction == 1 && getY() > 550){
                getWorld().removeObject(this);
            }
        }
    }
    
    /**
     * Method to cause this Pedestrian to become knocked down - stop moving, turn onto side
     */
    public void knockDown () {
        speed = 0;
        setRotation (90);
        awake = false;
    }
    
    public void rooted ()
    {
        speed = maxSpeed/2;
    }
    
    public void frogged()
    {
        speed = maxSpeed/3;
    }
    
    public void grabbed()
    {
        
    }
    
    /**
     * Method to allow a downed Pedestrian to be healed
     */
    public void healMe () {
        speed = maxSpeed;
        setRotation (0);
        awake = true;
    }
    
    public boolean isAwake () {
        return awake;
    }
}
heres the code for villager:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Villager here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Villager extends Pedestrian
{
    private GreenfootImage image;
    public Villager(int dir)
    {
        super(dir);
        image = getImage();
        image.scale(image.getWidth() - 340, image.getHeight() - 340);
        setImage(image);
    }
    
    /**
     * Act - do whatever the Villager wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act()
    {
        move();
    }
    
    public void rooted()
    {
        speed = maxSpeed/2;
        image = new GreenfootImage("rootedvillager.png");
        
        image.scale(image.getWidth() - 340, image.getHeight() - 340);
        setImage(image);
    }
    
    public void frogged()
    {
        speed = maxSpeed/3;
        
        image = new GreenfootImage("frog.png");
        image.scale(image.getWidth() - 65, image.getHeight() - 65);
        setImage(image);
        
    }
    
    public void grabbed()
    {
        
    }
}                       
and heres the code for the evil witch:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class EvilWitch here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class EvilWitch extends Pedestrian
{
    public EvilWitch(int dir)
    {
        super(dir);
        GreenfootImage image = getImage();
        image.scale(image.getWidth() - 280, image.getHeight() - 290);
        setImage(image);
    }
    
    /**
     * Act - do whatever the Villager wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act()
    {
        move();
    }
    
    public boolean checkHitPedestrian () {
        Villager v = (Villager)getOneObjectAtOffset((int)speed + getImage().getWidth()/2, 0, Villager.class);
        if (v != null){
            v.frogged();
            return true;
        }
        return false;
    }
}
danpost danpost

2023/3/24

#
KCee wrote...
i have two actors under the same superclass "Pedestrian". One of the actors is called villager and I want him to turn into a frog upon contact with the other actor called "EvilWitch". << Codes Omitted >>
Looks like you have code in the Villager class to do just that. Only problem is that if contact with EvilWitch is more than one act step, which is most probably the case, then the image will be made smaller multiple times; and, at some point, it will try to make it a size that is zero or less, causing an error. You need a way to check whether the actor was already frogged or not. That could simply be:
if (speed == maxSpeed) {
whose scope can include everything within the frogged method of the Villager class.
You need to login to post a reply.