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

2017/2/21

Does Greenfoot.mouseClicked() only work if the parameter is the object itself (this)?

1
2
3
4
SallySanban SallySanban

2017/2/21

#
I would like to allow the user to click a door so that the background changes and the location of the characters in the game are set to make it look like they entered a room. This is my code:
int background = 0;
    int totalBG = 26;
public void changeBackground()
    {
        int bgNumber = background % totalBG;
        CafeteriaDoor cafeteriadoor = new CafeteriaDoor();
....
        else if(bgNumber == 5)
        {
            getWorld().setBackground("Cafeteria Entrance.JPG");
            
            getWorld().addObject(cafeteriadoor, 429, 146);
            if(Greenfoot.mouseClicked(cafeteriadoor))
            {
                background++;
                setLocation(125, 243);
                elorawalk1.setLocation(60, 270);
            }
        }
        else if(bgNumber == 6)
        {
            getWorld().setBackground("Cafeteria 1.JPG");
            getWorld().removeObject(cafeteriadoor);
        }
This code is in the UserWalk1 class instead of the CafeteriaDoor class. I need it there because I do not know how to do object interaction passing two objects to another one, and I need to do that to be able to set the location of both UserWalk1 and EloraWalk1 once CafeteriaDoor is clicked. When I try it out and click the door, cafeteriadoor, the variable 'bgNumber' does not increment and stays as 5, which is why the background does not change. My guess is that even if I click the door, the program does not consider it clicked so the if statement is ignored? When I tried using the Greenfoot.mouseClicked() in the CafeteriaDoor class, it worked because I placed 'this', itself, in the parameter. However, I cannot set the location of both UserWalk1 and EloraWalk1. I can only set the location of one. How do I fix this?
danpost danpost

2017/2/21

#
Your mouse clicked line (line 11) would work if only you gave the new door time to be in the world before checking for a click on it. Each time the 'changeBackground' method is called, you create a new cafeteria door object and place it in the world and immediately check for a click on it. I have a feeling that you are ending up with door upon door within your world (stop the scenario and drag the cafeteria door around with the mouse). The reason you were able to do it in the CafeteriaDoor class is because you had a reference to the door (with 'this'). Here, where the code above is located, you do not have a reference to that door and must somehow obtain one. The following should get that reference:
Actor door = null; // to hold the reference
if (!getObjects(CafeteriaDoor.class).isEmpty()) // ensure the door is in the world (if needed)
{
    door = (Actor) getObjects(CafeteriaDoor.class).get(0); // getting the reference
    // now that you have the reference
    if (Greenfoot.mouseClicked(door))
    {
        // etc.
SallySanban SallySanban

2017/2/21

#
Could you please explain the code? I've never seen those types of methods since I'm just a beginner in Greenfoot.
Super_Hippo Super_Hippo

2017/2/21

#
The 'getObjects' method returns a list of all objects from the given type (CafeteriaDoor in this case) which are currently in the world. 'isEmpty' returns true if the list does not contain objects (= there are no CafeteriaDoor objects in the world). The '!' negates this, so the condition in line 2 is met when there is at least one CafeteriaDoor object in the world. 'get(0)' gets the first object in the list. Then, the object 'door' can be used as a parameter for the 'mouseClicked' method.
SallySanban SallySanban

2017/2/21

#
Here is what I did:
else if(bgNumber == 5)
        {
            getWorld().setBackground("Cafeteria Entrance.JPG");
            enterCafeteria();
        }
        else if(bgNumber == 6)
        {
            getWorld().setBackground("Cafeteria 1.JPG");
        }
public void enterCafeteria()
    {
        CafeteriaDoor cafeteriadoor = new CafeteriaDoor();
        Actor door = null;    
        getWorld().addObject(cafeteriadoor, 429, 146);
        if(!getWorld().getObjects(CafeteriaDoor.class).isEmpty())
        {
            door = (Actor) getWorld().getObjects(CafeteriaDoor.class).get(0);
            if(Greenfoot.mouseClicked(door))
            {
                background++;
                setLocation(125, 243);
                elorawalk1.setLocation(60, 270);
            }
        }
    }
It is true that the doors pile up one after another. Is it possible to only create one door? It also still does not change background when I click the door. How do I solve this?
SallySanban SallySanban

2017/2/21

#
I managed to only create one door using this code:
public void enterCafeteria()
    {
        CafeteriaDoor cafeteriadoor = new CafeteriaDoor();
        Actor door = null; 
        if(getWorld().getObjects(CafeteriaDoor.class).isEmpty())
        {
            getWorld().addObject(cafeteriadoor, 429, 146);
        }
        
        if(!getWorld().getObjects(CafeteriaDoor.class).isEmpty())
        {
            door = (Actor) getWorld().getObjects(CafeteriaDoor.class).get(0);
            if(Greenfoot.mouseClicked(door))
            {
                background++;
                setLocation(125, 243);
                elorawalk1.setLocation(60, 270);
            }
        }
    }
However, still nothing happens when the door is clicked.
Super_Hippo Super_Hippo

2017/2/21

#
Right now, you are creating the object and check for a click at the same moment. You can't click an object which is technically not there before the click could have been made. Try to move the mouse click check to the act method of the world and only add one Door in the constructor of the world. Also, background++ does not change the background. Only if you change the background afterwards. You also have a background variable and a bgNumber. Actually I just noticed this code is not in the world.
SallySanban SallySanban

2017/2/21

#
Yes, the 'background' is a variable I named previously. The variable 'bgNumber' uses mod with background and totalBG, which is a constant 26 in my case. Would you like to see my entire code? Placing the mouseClicked method in the act method will not work because door is not named there. It is named in enterCafeteria().
Super_Hippo Super_Hippo

2017/2/21

#
If this method is not called from the act method, a click will never be detected though.
SallySanban SallySanban

2017/2/21

#
It is called in a method that is called by the act method.
Super_Hippo Super_Hippo

2017/2/21

#
What is the condition for the Door to be placed in the world? If it is not by an action of this Actor, add the Door from the world. Maybe showing the entire class code might help. I am pretty sure all these 'background' things should go into the world class. Btw, am I the only one which has problems accessing greenfoot.org since yesterday?
SallySanban SallySanban

2017/2/21

#
Here you go.
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class UserWalk1 here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class UserWalk1 extends Walk
{
    private int costume;
    private int costumeElora;
    private EloraWalk1 elorawalk1;
    //RightButton right;
    //LeftButton left;
    int background = 0;
    int totalBG = 26; //change to how many number of backgrounds you have!
    int bgNumber = background % totalBG;

    public UserWalk1(EloraWalk1 elora)
    {
        elorawalk1 = elora;
    }

    /**
     * Act - do whatever the UserWalk1 wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        controls();
        followUser();
    }

    /**
     * Keyboard controls of the User with costume changing.
     */
    public void controls()
    {
        if(Greenfoot.isKeyDown("right"))
        {
            move(2);
            changeBackground();
            costume = Greenfoot.getRandomNumber(2) + 1;
            if(costume == 1)
            {
                switchCostume(2);
            }
            else if(costume == 2)
            {
                switchCostume(1);
            }
        }

        if(Greenfoot.isKeyDown("left"))
        {
            move(-2);
            changeBackground();
            costume = Greenfoot.getRandomNumber(2) + 3;
            if(costume == 3)
            {
                switchCostume(4);
            }
            else if(costume == 4)
            {
                switchCostume(3);
            }
        }
    }

    /**
     * Changes the costume of the User to make her look like she's walking.
     */
    public void switchCostume(int costumeNumber)
    {
        GreenfootImage costume1 = new GreenfootImage("User Walk 1.gif");
        GreenfootImage costume2 = new GreenfootImage("User Walk 2.gif");
        GreenfootImage costume3 = new GreenfootImage("User Walk 3.gif");
        GreenfootImage costume4 = new GreenfootImage("User Walk 4.gif");
        if(costumeNumber == 1)
        {
            setImage(costume2);
        }
        else if(costumeNumber == 2)
        {
            setImage(costume1);
        }
        else if(costumeNumber == 3)
        {
            setImage(costume4);
        }
        else if(costumeNumber == 4)
        {
            setImage(costume3);
        }
    }

    /**
     * Changes the background to let the User move rooms + stops
     * the background changing if it's first/last + lets Elora
     * switch rooms too!
     */
    public void changeBackground()
    {
        int bgNumber = background % totalBG;

        /**
         * Stopping rule for the FIRST background
         */
        if(bgNumber == 0 && this.getX() < 91)
        {
            setLocation(91, 243);
        }

        /**
         * General moving rule to the RIGHT
         */
        if(bgNumber < totalBG - 1 && this.getX() > 519)
        {  
            background++;
            setLocation(125, 243);
            elorawalk1.setLocation(60, 270);
        }

        /**
         * Moving rule to the RIGHT for SCHOOL ENTRANCE BACKGROUND
         */
        if(bgNumber == 2 && this.getX() > 464)
        {  
            background++;
            setLocation(125, 243);
            elorawalk1.setLocation(60, 270);
        }

        /**
         * Stopping rule to the RIGHT for CAFETERIA ENTRANCE BACKGROUND
         */
        if(bgNumber == 5 && this.getX() > 510)
        {  
            setLocation(510, 243);
        }

        /**
         * General moving rule to the LEFT
         */
        if(bgNumber > 0 && this.getX() < 91)
        {
            background--;
            setLocation(500, 243);
            elorawalk1.setLocation(578, 270);
        }

        /**
         * Stopping rule for the LAST background
         */
        if(bgNumber == totalBG - 1 && this.getX() > 519)
        {
            setLocation(519, 243);
        }

        /**
         * Changes background
         */
        if(bgNumber == 0)
        {
            getWorld().setBackground("Alleyway 4.PNG");
        }
        else if(bgNumber == 1)
        {
            getWorld().setBackground("Kalachuchi Walk 1.JPG");
        }
        else if(bgNumber == 2)
        {
            getWorld().setBackground("School Entrance.JPG");
        }
        else if(bgNumber == 3)
        {
            getWorld().setBackground("Lockers 1.JPG");
        }
        else if(bgNumber == 4)
        {
            getWorld().setBackground("Lockers 2.JPG");
        }
        else if(bgNumber == 5)
        {
            getWorld().setBackground("Cafeteria Entrance.JPG");
            enterCafeteria();
        }
        else if(bgNumber == 6)
        {
            getWorld().setBackground("Cafeteria 1.JPG");
        }
        else if(bgNumber == 7)
        {
            getWorld().setBackground("Cafeteria 2.jpg");
        }
        else if(bgNumber == 8)
        {
            getWorld().setBackground("Cafeteria Entrance Stairs.JPG");
        }
        else if(bgNumber == 9)
        {
            getWorld().setBackground("Classroom Entrance.jpg");
        }
        else if(bgNumber == 10)
        {
            getWorld().setBackground("Classroom.PNG");
        }
        else if(bgNumber == 11)
        {
            getWorld().setBackground("Student Bathroom Entrance.JPG");
        }
        else if(bgNumber == 12)
        {
            getWorld().setBackground("Student Bathroom.png");
        }
        else if(bgNumber == 13)
        {
            getWorld().setBackground("Classroom Entrance Stairs.JPG");
        }
        else if(bgNumber == 14)
        {
            getWorld().setBackground("Library Entrance.JPG");
        }
        else if(bgNumber == 15)
        {
            getWorld().setBackground("Library 1.JPG");
        }
        else if(bgNumber == 16)
        {
            getWorld().setBackground("Library 2.JPG");
        }
        else if(bgNumber == 17)
        {
            getWorld().setBackground("Faculty Study Entrance.jpg");
        }
        else if(bgNumber == 18)
        {
            getWorld().setBackground("Faculty Study.JPG");
        }
        else if(bgNumber == 19)
        {
            getWorld().setBackground("Principal's Office.jpg");
        }
        else if(bgNumber == 20)
        {
            getWorld().setBackground("Teacher Bathroom Entrance.jpg");
        }
        else if(bgNumber == 21)
        {
            getWorld().setBackground("Female Teacher Bathroom.png");
        }
        else if(bgNumber == 22)
        {
            getWorld().setBackground("Male Teacher Bathroom.png");
        }
        else if(bgNumber == 23)
        {
            getWorld().setBackground("Basement Entrance.JPG");
        }
        else if(bgNumber == 24)
        {
            getWorld().setBackground("Janitor's Closet.png");
        }
        else if(bgNumber == 25)
        {
            getWorld().setBackground("Dark Room.PNG");
        }
    }

    /**
     * Makes Elora follow the User
     * with her 'own mind' as you called it, because she always follows
     * from behind and in a distance, and she still walks
     * even if User is unable to move at an edge.
     */
    public void followUser()
    {
        if(Greenfoot.isKeyDown("right"))
        {
            if(elorawalk1.getX() < this.getX())
            {
                elorawalk1.move(1);
                costumeElora = Greenfoot.getRandomNumber(2) + 1;
                if(costumeElora == 1)
                {
                    switchCostumeElora(2);
                }
                else if(costumeElora == 2)
                {
                    switchCostumeElora(1);
                }
            }
        }
        if(Greenfoot.isKeyDown("left"))
        {
            if(elorawalk1.getX() > this.getX())
            {
                elorawalk1.move(-1);
                costumeElora = Greenfoot.getRandomNumber(2) + 3;
                if(costumeElora == 3)
                {
                    switchCostumeElora(4);
                }
                else if(costumeElora == 4)
                {
                    switchCostumeElora(3);
                }
            }
        }
    }

    /**
     * Changes the costume of Elora to make her look like she's walking.
     */
    public void switchCostumeElora(int costumeNumber)
    {
        GreenfootImage costume1 = new GreenfootImage("Elora Walk 1.gif");
        GreenfootImage costume2 = new GreenfootImage("Elora Walk 2.gif");
        GreenfootImage costume3 = new GreenfootImage("Elora Walk 3.gif");
        GreenfootImage costume4 = new GreenfootImage("Elora Walk 4.gif");
        if(costumeNumber == 1)
        {
            elorawalk1.setImage(costume2);
        }
        else if(costumeNumber == 2)
        {
            elorawalk1.setImage(costume1);
        }
        else if(costumeNumber == 3)
        {
            elorawalk1.setImage(costume4);
        }
        else if(costumeNumber == 4)
        {
            elorawalk1.setImage(costume3);
        }
    }

    public void enterCafeteria()
    {
        CafeteriaDoor cafeteriadoor = new CafeteriaDoor();
        Actor door = null; 
        if(getWorld().getObjects(CafeteriaDoor.class).isEmpty())
        {
            getWorld().addObject(cafeteriadoor, 429, 146);
        }
        
        if(!getWorld().getObjects(CafeteriaDoor.class).isEmpty())
        {
            door = (Actor) getWorld().getObjects(CafeteriaDoor.class).get(0);
            
        }
        
        if(Greenfoot.mouseClicked(door))
            {
                background++;
                setLocation(125, 243);
                elorawalk1.setLocation(60, 270);
            }
    }
}
Super_Hippo Super_Hippo

2017/2/21

#
Well...It is not a good idea trying to handle like the whole game from the UserWalk1 class. I still think that most of this code should go into the world subclass. Then the actor could (after moving) call a method in the world which checks (depending on the background) if the background should change. The CafeteriaDoor could check for clicks on itself and tell its world that the background should be changed. Btw, the switch costume methods and the calls to the methods are pretty complicated even what they do is pretty simple. You get a random number, then pass the other number to the method which itself takes the original number to set the costume...
SallySanban SallySanban

2017/2/21

#
I only want the door to appear if the background of the World is the cafeteria entrance. When bgNumber becomes 5, the background of the World becomes cafeteria entrance, and the door should be added (and should be clickable) so that the World could switch to the next background, the inside of the cafeteria.
SallySanban SallySanban

2017/2/21

#
Super_Hippo wrote...
Well...It is not a good idea trying to handle like the whole game from the UserWalk1 class. I still think that most of this code should go into the world subclass. Then the actor could (after moving) call a method in the world which checks (depending on the background) if the background should change. The CafeteriaDoor could check for clicks on itself and tell its world that the background should be changed. Btw, the switch costume methods and the calls to the methods are pretty complicated even what they do is pretty simple. You get a random number, then pass the other number to the method which itself takes the original number to set the costume...
Could you give me an example on how to code that, please?
There are more replies on the next page.
1
2
3
4