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

2023/11/19

Turn actor invisible from another actor

Lupical Lupical

2023/11/19

#
Hi everyone, I'm working on a crab game for a school project. The game consist of crab which walks where you click and can eat worms on the way. But I can't really find a solution to stop the crab from going any further. To stop at the x and y coordinates of the mouse doesn't work, so I have tried to create an actor at the position where the mouse clicks and stop the crab through isTouching(). But the actor needs to be invisible. So I have tried to turn the transparency of the class (CrabTouching) to 255, but that didn't work, so I tried it through a variable from the CopyOfCrab code, but that didn't work either. Has anybody a way to turn the actor invisible, or how to stop the crab without another actor?
import greenfoot.*;

/**
 * Diese Klasse definiert eine Krabbe. Krabben leben am Strand.
 */
public class CopyOfCrab extends Actor
{
    static int crabX, crabY;
    static int MouseToCrabX, MouseToCrabY;
    static double hypothenuse;
    public void CrabPosition()
    {
        crabX = this.getX();
        crabY = this.getY();
    }
    public void MouseToCrab()
    {
        MouseToCrabX = Math.abs(CrabWorld.mouseX - crabX);
        MouseToCrabY = Math.abs(CrabWorld.mouseY - crabY);
    }
    public void findhypothenuse()
    {
        hypothenuse = Math.round(Math.sqrt(Math.pow(MouseToCrabX, 2) + Math.pow(MouseToCrabY, 2)));
    }
    public void act()
    {
        turnTowards(CrabWorld.mouseX, CrabWorld.mouseY);
        if (Greenfoot.mouseClicked(null)){
            getWorld().addObject(new CrabTouching(), CrabWorld.mouseX, CrabWorld.mouseY);
            while (!isTouching(CrabTouching.class)) {
                move(5);
                Greenfoot.delay(1);
                if (isTouching(Worm.class)) {
                    removeTouching(Worm.class);
                }
            }
            getWorld().removeObjects(getWorld().getObjects(CrabTouching.class));
        }
        
        CrabPosition();
        MouseToCrab();
        findhypothenuse();
    }
        public void move(double distance)
    {
        double angle = getRotation();
        int x = (int) Math.round(getX() + Math.cos(angle) * 5);
        int y = (int) Math.round(getY() + Math.sin(angle) * 5);
        
        setLocation(x, y);
    }
}
import greenfoot.*;  // (Actor, World, Greenfoot, GreenfootImage)

public class CrabWorld extends World
{
    /**
     * Erzeugt die Krabbenwelt (den Strand). Unsere Welt hat eine Größe 
     * von 560x560 Zellen, wobei jede Zelle nur ein Pixel groß ist.
     */
    public CrabWorld() 
    {
        super(560, 560, 1);
        addObject(new CopyOfCrab(), getWidth()/2, getHeight()/2);
        int NumberOfWorms = Greenfoot.getRandomNumber(11);
        for(int i = NumberOfWorms; i<11; i++){
        addObject(new Worm(), Greenfoot.getRandomNumber(560), Greenfoot.getRandomNumber(560));
        }
    }
    
    static int mouseX, mouseY;

    public void act()
    {
        if (Greenfoot.mouseMoved(null) || Greenfoot.mouseDragged(null))
        {
            MouseInfo mouse = Greenfoot.getMouseInfo();
            mouseX = mouse.getX();
            mouseY = mouse.getY();
        }
    }
}
danpost danpost

2023/11/20

#
Lupical wrote...
Has anybody a way to turn the actor invisible, or how to stop the crab without another actor?
Adding an extra (invisible) actor is not necessary. There are two possibilities as to why the crab does not stop; one is that because the rotation of an actor is in units of whole degrees, turning towards the mouse coordinates may not be in a direct line with the mouse click location; the other is moving 5 units at a time may cause the crab to skip over the coordinates. Also, using while (CoypOfCrab: 30) will cause all other actors to remain in stasis (perfectly still) during the entire move to any new mouse coordinates given. The following should be sufficient:
import greenfoot.*;

public class Crab extends Actor
{
    private int mouseX, mouseY;
    
    protected void addedToWorld(World world) {
        mouseX = getX();
        mouseY = getY();
    }
    
    public void act() {
        if (Greenfoot.mouseClicked(null)) {
            MouseInfo mouse = Greenfoot.getMouseInfo();
            mouseX = mouse.getX();
            mouseY = mouse.getY();
        }
        if (mouseX != getX() || mouseY != getY()) {
            turnTowards(mouseX, mouseY());
            int dist = (int)Math.hypot(mouseX-getX(), mouseY-getY());
            if (dist < 6) {
                setLocation(mouseX, mouseY);
            }
            else {
                move(5);
            }
        }
    }
}
danpost danpost

2023/11/21

#
Lupical wrote...
I have tried to turn the transparency of the class (CrabTouching) to 255, but that didn't work
For future reference, to make an actor invisible, use:
setImage((GreenfootImage)null);
or
setImage(new GreenfootImage(5, 5); // min:  (1, 1)
Lupical Lupical

2023/11/21

#
So the reason I used such overcomplicated code was because I used move() before and the actor was only moving horizontally, vertically or diagonal, so I thought that was a limitation of move(), but apparently that was just my fault. Thank you very much, danpost, you helped me a lot.
You need to login to post a reply.