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

2023/11/30

Why do the additional methods cause the first two to not work?

DemDev DemDev

2023/11/30

#
I'm one of those people that will spend hours trying to learn by myself (and I have) while trying to wrap my head around why adding more than two "Tele" methods cause all of the Tele methods to not work (the mouse gets stuck in a teleport loop). I hate asking for help. On top of that I'm also one of those people that will want to know WHY something doesn't work and not just, "That doesn't work, try something else." Which is another reason I hate asking for help. I know a lot of people that respond negatively to the question, "Why?" The first two methods (hitTeleOne & hitTeleTwo) work exactly as I would expect them to when they are the only two methods that are active. However, the moment I un-comment out TeleThree through TeleSix it all goes crazy, and the poor mouse gets stuck in space-time continuum. The rest of the code (classes and subclasses) are all set up in a very basic "I'm learning" style and I fully understand that there is a better way to go about it. credit to Danpost for the Tele code I found while Googling my heart out trying to figure this out. Setup:  World --MyWorld Actor --Cheese(pizza bc Greenfoot doesn't have a cheese image lol) --Mouse --Teleporter ...........^-- TeleOne ...........^--TeleTwo ...........^--TeleThree ...........^--TeleFour ...........^--TeleFive ...........^--TeleSix --Walls ..........^-- *a bunch of WallHeightSmall/XLarge and WallWidthSmall/XLarge There is no out of the ordinary code in any other area other than the Mouse class (which is posted below). Everything else is your basic Scaling images down and obviously all the addObject code in the MyWorld class.
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class Mouse here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Mouse extends Actor
{
    /**
     * Act - do whatever the Mouse wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    
    public boolean teleporting = false;
    
    public Mouse()
    {
        //getting image of Mouse actor and scaling the width and height by 3
        getImage().scale(getImage().getWidth() / 3 , getImage().getHeight() / 3);
    }
    public void act()
    {
        // Add your action code here.
        moveAround();
        hitFood();
        hitTeleOne();
        hitTeleTwo();
        //hitTeleThree();
        //hitTeleFour();
        //hitTeleFive();
        //hitTeleSix();
        
    }
    public void moveAround()
    {
        //checking if the right key is down
        if (Greenfoot.isKeyDown("right"))
        {
            //setting the location of the Mouse actor to the right 3 pixels
            setLocation(getX() + 3 , getY());
            //checking if our hitWall method is returning true
            if (hitWall() == true)
            {
                //if method returns true and the Mouse actor is hitting a wall then it does not move to the right
                setLocation(getX() -3 , getY());
            }
        }
        if (Greenfoot.isKeyDown("left"))
        {
            setLocation(getX() - 3 , getY());
            if (hitWall() == true)
            {
                setLocation(getX() + 3 , getY());
            }
        }
        if (Greenfoot.isKeyDown("up"))
        {
            setLocation(getX() , getY() - 3);
            if (hitWall() == true)
            {
                setLocation(getX() , getY() + 3);
            }
        }
        if (Greenfoot.isKeyDown("down"))
        {
            setLocation(getX() , getY() + 3);
            if (hitWall() == true)
            {
                setLocation(getX() , getY() - 3);
            }
        }
    }
    public boolean hitWall()
    {
        //checking if the Mouse actor is touching an actor/object in the Walls class
        if (isTouching(Walls.class))
        {
            return true; 
        }
        else
        {
            return false;
        }
    }
    public void hitFood()
    {
        //checking if the Mouse actor is intersecting with an object in the Cheese class and if that something does not equal to nothing
        if(getOneIntersectingObject(Cheese.class) != null)
        {
            //retrieving said object from the Cheese class that is being intersected from the World and removing it
            getWorld().removeObject(getOneIntersectingObject(Cheese.class));
        }
    }
    public void hitTeleOne()
    {
        //checking if teleporting is NOT true & if TeleOne is NOT empty
        if(!teleporting && !getIntersectingObjects(TeleOne.class).isEmpty())
        {
            //initiating the teleporter by now declaring it as true
            teleporting = true;
            //get teleporter two object from world and assign to a variable
            TeleTwo teletwo = (TeleTwo) getWorld().getObjects(TeleTwo.class).get(0);
            //move mouse to teleporter two
            setLocation(teletwo.getX() , teletwo.getY());
        }
        //checking if teleporting is true & if TeleTwo is clear of intersecting objects & if TeleOne is clear of intersecting objects
        if(teleporting ==true && getIntersectingObjects(TeleTwo.class).isEmpty() && getIntersectingObjects(TeleOne.class).isEmpty())
        {
            teleporting = false;
        }
    }
    public void hitTeleTwo()
    {
        //checking if teleporting is NOT true & if TeleTwo is NOT empty
        if(!teleporting && !getIntersectingObjects(TeleTwo.class).isEmpty())
        {
            //initiating the teleporting by now declaring it as true
            teleporting = true;
            //get teleporter one object from world and assign to a variable
            TeleOne teleone = (TeleOne) getWorld().getObjects(TeleOne.class).get(0);
            //move mouse to teleporter one
            setLocation(teleone.getX() , teleone.getY());
            
        }
        //checking if teleporting is true & if TeleOne is clear of intersecting objects & if TeleTwo is clear of intersecting objects
        if(teleporting ==true && getIntersectingObjects(TeleOne.class).isEmpty() && getIntersectingObjects(TeleTwo.class).isEmpty())
        {
            teleporting = false;
        }
    }
    /*
    public void hitTeleThree()
    {
        //checking if teleporting is NOT true & if TeleThree is NOT empty
        if(!teleporting && !getIntersectingObjects(TeleThree.class).isEmpty())
        {
            //initiating the teleporting by now declaring it as true
            teleporting = true;
            //get teleporter four object from world and assign to a variable
            TeleFour telefour = (TeleFour) getWorld().getObjects(TeleFour.class).get(0);
            //move mouse to teleporter four
            setLocation(telefour.getX() , telefour.getY());
        }
        //checking if teleporting is true & if TeleFour is clear of intersecting objects & if TeleThree is clear of intersecting objects
        if(teleporting ==true && getIntersectingObjects(TeleFour.class).isEmpty() && getIntersectingObjects(TeleThree.class).isEmpty())
        {
            teleporting = false;
        }
    }
    
    public void hitTeleFour()
    {
        //checking if teleporting is NOT true & if TeleFour is NOT empty
        if(!teleporting && !getIntersectingObjects(TeleFour.class).isEmpty())
        {
           //initiating the teleporting by now declaring it as true
           teleporting = true;
           //get teleporter three object from world and assign to a variable
           TeleThree telethree = (TeleThree) getWorld().getObjects(TeleThree.class).get(0);
           //move mouse to teleporter three
           setLocation(telethree.getX() , telethree.getY());
        }
        //checking if teleporting is true & if TeleThree is clear of intersecting objects & if TeleFour is clear of intersecting objects
        if(teleporting ==true && getIntersectingObjects(TeleThree.class).isEmpty() && getIntersectingObjects(TeleFour.class).isEmpty())
        {
            teleporting = false;
        }
    }
    
    public void hitTeleFive()
    {
        //checking if teleporting is NOT true & if TeleFive is NOT empty
        if(!teleporting && !getIntersectingObjects(TeleFive.class).isEmpty())
        {
            //initiating the teleporting by now declaring it as true
            teleporting = true;
            //get teleporter six object from world and assign to a variable
            TeleSix telesix = (TeleSix) getWorld().getObjects(TeleSix.class).get(0);
            //move mouse to teleporter six
            setLocation(telesix.getX() , telesix.getY());
        }
        //checking if teleporting is true & if TeleSix is clear of intersecting objects & if TeleFive is clear of intersecting objects
        if(teleporting ==true && !getIntersectingObjects(TeleSix.class).isEmpty() && getIntersectingObjects(TeleFive.class).isEmpty())
        {
                teleporting = false;
        }
    }
    public void hitTeleSix()
    {
        //checking if teleporting is NOT true & if TeleSix is NOT empty
        if(!teleporting && !getIntersectingObjects(TeleSix.class).isEmpty())
        {
            //initiating the teleporting by now declaring is as true
            teleporting = true;
            //get teleporter five object from world and assign to variable
            TeleFive telefive = (TeleFive) getWorld().getObjects(TeleFive.class).get(0);
            //move mouse to teleporter five
            setLocation(telefive.getX() , telefive.getY());
        }
        //checking if teleporting is true & if TeleFive is clear of intersecting objects & if TeleSix is clear of intersecting objects
        if(teleporting ==true && !getIntersectingObjects(TeleFive.class).isEmpty() && !getIntersectingObjects(TeleSix.class).isEmpty())
        {
            teleporting = false;
        }
    }
    */
}
nccb nccb

2023/11/30

#
If you hit teleporter 1, then teleporting is set to true in hitTeleOne by the first if, but not by the second if (because you are touching teleporter 2). However, in hitTeleTwo, because you are teleporting and no longer touching teleporter 1, the second if flips teleporting back to false. I suspect when you then add more methods you can get stuck teleporting back and forth between all the teleporters. Rather than a boolean you may need an integer (or an object reference to the teleporter instance) to keep track of which teleporter you arrived at, so you can check you are clear of that specific teleporter, rather than just checking you are clear of any teleporter.
DemDev DemDev

2023/11/30

#
I had the thought that I was travelling between all of them simultaneously. However, I couldn't grasp how that is possible since I'm calling on each one individually. Could you explain why that is when I'm calling on each one individually through their respective class? TeleOne & TeleTwo are a pair TeleThree & TeleFour are a pair TeleFive & TeleSix are a pair If I hit the TeleOne object (thats what I called) and get sent to TeleTwo (also what I called) shouldn't the method end by declaring teleporting = False and that be the end of the it until I clear (move away from) and then hit another Tele object? I'm still confused as to why they are all being treated as one object instead of six (only when I add more than two) when they are all clearly called for individually in the code by individual methods. I am going to try the integer route and I'll post an update if I get it working the way I would like it to. Please don't share any code unless I come back with my head down and tail between my legs lol.
DemDev DemDev

2023/11/30

#
Well that was ridiculous....... Figured it out. By that I mean I figured out how to get it working the way I want it to. But I'm still confused as to why they were all being treated as the same object. If I was asking (calling) for BlueMM1 & BlueMM2 to play (Interact) individually (per method) then why did YellowMM1, YellowMM2, RedMM1, & RedMM2 all come off the bench screaming and yelling when it wasn't their turn? I guess that is what's still hanging me up about all this. Posting my tele code below in case other beginners run into a similar issue or want to make some teleporters as well. I'm sure it is inefficient to constantly check a boolean by using a method within the act method; but for a day 2 Greenfoot user I'll take it until I can learn more. Thank you NCCB! Reading your reply as I slowly followed along in my code with what you said helped spark some helpful thought processes! 
    public void hitTeleOne()
    {
        //checking if teleporting is NOT true & if TeleOne is NOT empty
        if(!teleporting && !getIntersectingObjects(TeleOne.class).isEmpty())
        {
            //initiating the teleporter by now declaring it as true
            teleporting = true;
            //get teleporter two object from world and assign to a variable
            TeleTwo teletwo = (TeleTwo) getWorld().getObjects(TeleTwo.class).get(0);
            //move mouse to teleporter two
            setLocation(teletwo.getX() , teletwo.getY());
        }
        //checking if teleporting is true & if TeleTwo is clear of intersecting objects & if TeleOne is clear of intersecting objects
        if(checkTeleporting() ==true )
        {
            teleporting = false;
        }
    }
    public void hitTeleTwo()
    {
        //checking if teleporting is NOT true & if TeleTwo is NOT empty
        if(!teleporting && !getIntersectingObjects(TeleTwo.class).isEmpty())
        {
            //initiating the teleporting by now declaring it as true
            teleporting = true;
            //get teleporter one object from world and assign to a variable
            TeleOne teleone = (TeleOne) getWorld().getObjects(TeleOne.class).get(0);
            //move mouse to teleporter one
            setLocation(teleone.getX() , teleone.getY());
            
        }
        //checking if teleporting is true & if TeleOne is clear of intersecting objects & if TeleTwo is clear of intersecting objects
        if(checkTeleporting() ==true )
        {
            teleporting = false;
        }
    }
    
    public void hitTeleThree()
    {
        //checking if teleporting is NOT true & if TeleThree is NOT empty
        if(!teleporting && !getIntersectingObjects(TeleThree.class).isEmpty())
        {
            //initiating the teleporting by now declaring it as true
            teleporting = true;
            //get teleporter four object from world and assign to a variable
            TeleFour telefour = (TeleFour) getWorld().getObjects(TeleFour.class).get(0);
            //move mouse to teleporter four
            setLocation(telefour.getX() , telefour.getY());
        }
        //checking if teleporting is true & if TeleFour is clear of intersecting objects & if TeleThree is clear of intersecting objects
        if(checkTeleporting() ==true)
        {
            teleporting = false;
        }
    }
    
    public void hitTeleFour()
    {
        //checking if teleporting is NOT true & if TeleFour is NOT empty
        if(!teleporting && !getIntersectingObjects(TeleFour.class).isEmpty())
        {
           //initiating the teleporting by now declaring it as true
           teleporting = true;
           //get teleporter three object from world and assign to a variable
           TeleThree telethree = (TeleThree) getWorld().getObjects(TeleThree.class).get(0);
           //move mouse to teleporter three
           setLocation(telethree.getX() , telethree.getY());
        }
        //checking if teleporting is true & if TeleThree is clear of intersecting objects & if TeleFour is clear of intersecting objects
        if(checkTeleporting() ==true )
        {
            teleporting = false;
        }
    }
    
    public void hitTeleFive()
    {
        //checking if teleporting is NOT true & if TeleFive is NOT empty
        if(!teleporting && !getIntersectingObjects(TeleFive.class).isEmpty())
        {
            //initiating the teleporting by now declaring it as true
            teleporting = true;
            //get teleporter six object from world and assign to a variable
            TeleSix telesix = (TeleSix) getWorld().getObjects(TeleSix.class).get(0);
            //move mouse to teleporter six
            setLocation(telesix.getX() , telesix.getY());
        }
        //checking if teleporting is true & if TeleSix is clear of intersecting objects & if TeleFive is clear of intersecting objects
        if(checkTeleporting() ==true )
        {
                teleporting = false;
        }
    }
    
    public void hitTeleSix()
    {
        //checking if teleporting is NOT true & if TeleSix is NOT empty
        if(!teleporting && !getIntersectingObjects(TeleSix.class).isEmpty())
        {
            //initiating the teleporting by now declaring is as true
            teleporting = true;
            //get teleporter five object from world and assign to variable
            TeleFive telefive = (TeleFive) getWorld().getObjects(TeleFive.class).get(0);
            //move mouse to teleporter five
            setLocation(telefive.getX() , telefive.getY());
        }
        //checking if teleporting is true & if TeleFive is clear of intersecting objects & if TeleSix is clear of intersecting objects
        if(checkTeleporting() ==true )
        {
            teleporting = false;
        }
    }
    
    public boolean checkTeleporting()
    {
        if(isTouching(Teleporter.class))
        {
            return false;
        }
        else
        {
            return true;
        }
    }
Spock47 Spock47

2023/11/30

#
DemDev wrote...
But I'm still confused as to why they were all being treated as the same object. If I was asking (calling) for BlueMM1 & BlueMM2 to play (Interact) individually (per method) then why did YellowMM1, YellowMM2, RedMM1, & RedMM2 all come off the bench screaming and yelling when it wasn't their turn?
Because they are connected by the "teleporting" variable. The teleporting variable is like a lock. If it is locked, no teleport is possible anymore until the lock gets opened again. In the implementation with tele1 and tele2, the lock gets closed with the teleport and the only way to open up the lock is when the mouse gets clear from the area of tele1 AND tele2. Therefore, teleporting back cannot occur without leaving the tele1/tele2 area. But then you added tele3 and tele4 with the same lock (teleporting). Now, all four tele gets locked when teleporting variable is set (which is ok). But also, there are now two ways to open the lock: 1. Still, if the mouse is clear of the area of tele1 and tele2, the lock gets opened. 2. But additionally, if the mouse is clear of the are of tele3 and tele4, the lock gets opened, too. And since the mouse will not touch tele3 and tele4 while arriving at tele2, the lock gets immediately opened. Therefore, tele2 sees there is no lock and will immediately teleport the mouse back to tele1. Again, since mouse does not touch tele3 and tele4, lock gets immediately unlocked again, and mouse gets teleported again... and so on. Or in source code: in each call to act method, tele1/tele2 will make teleport and activate the teleporting lock. But immediately, tele3 will deactivate the teleporting lock, so at the end of the act method, teleporting lock is always open. You found yourself that the problem is with the teleporting variable and found a solution how to do it, well done. For reference: Another solution would be to use a different lock for each teleport pair, i.e. tele1/tele2 are using teleportingA, tele3/tele4 are using teleportingB, tele5/tele6 are using teleportingC... Similar to how each door has its own lock instead of all doors using the same lock. Live long and prosper, Spock47
DemDev DemDev

2023/12/2

#
@Spock47 Your comment cleared it up for me about 90% of the way lol. The "In each call to act method..." made me remember that everything in the act method is CONSTANTLY acting/running so long as the game is acting/running. Which led to the AHA! moment I needed to wrap my head around why they all came "off the bench" so to speak. They were never on the bench lol. For whatever reason I forgot that anything in the act method is being ran over'n'over and not just when the mouse hits one of the Tele to do a check.
DemDev DemDev

2023/12/2

#
I got it. 100% wrapped my head around it and understand now. Took a bit more time slowly going over the code and tracing the teleporting variable back and forth from true to false while jumping around the tele methods and it finally hit me. THANK YOU BOTH! For your patience and willingness to help explain it.
You need to login to post a reply.