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
Super_Hippo Super_Hippo

2017/2/22

#
This line
this(new UserWalk1(), 0, -1);
calls the other constructor, so this line:
public MyWorld(Actor p, int worldType, int lastWorldType)
So 'p' is now the new UserWalk1 object and can be used to assign it to the player variable with
player = p;
When changing the world,
Greenfoot.setWorld(new MyWorld(player, type+change, type));
the player is passed to the next world, so 'p' and then also 'player' in the next world is the same UserWalk1 object. (Now, after thinking about it, you could probably just make it static and even final and forget about all this "pass to new world" thing...) The x and y variable are used as the location where the player (=UserWalk1) should be added. The x variable is depending on the last world (right or left edge). (If any world should effect this, too, you add it to its switch case. For EloraWalk1, you would also create an x and y variable (maybe xElora and yElora), set it depending on the last world and then, add it to the world:
addObject(player.getEloraWalk(), xElora, yElora);
SallySanban SallySanban

2017/2/23

#
The World cannot seem to find the method getEloraWalk(). I placed that in the UserWalk1 class.
Nosson1459 Nosson1459

2017/2/23

#
Look at Hippo's post the one previous to the last.
Super_Hippo wrote...
Make sure you have a method to get the EloraWalk1 object from the UserWalk1 object.
private EloraWalk1 elorawalk;

public UserWalk1(EloraWalk1 e)
{
    elorawalk = e;
    //...
}

public EloraWalk1 getEloraWalk() {return elorawalk;}
Then, in the second world constructor, you can also add the EloraWalk1 object depending on which type of world is created and what the last world was.
SallySanban SallySanban

2017/2/23

#
I had that in my UserWalk1 class already. In the World class, getEloraWalk() isn't recognized?
Super_Hippo Super_Hippo

2017/2/23

#
Oh, that's my fault. You have to change the 'Actor' in these two lines
private Actor player;
//...
public MyWorld(Actor p, int worldType, int lastWorldType)
to 'UserWalk1'.
SallySanban SallySanban

2017/2/23

#
Ah, I see. If I wanted to add more objects into the World aside from UserWalk1 and EloraWalk1, how would I do it? I would like to put an Inventory object in the World and have it stay there for the entirety of the game.
Super_Hippo Super_Hippo

2017/2/23

#
Add them in the second constructor. Everything which should be added to every world has to be outside of the switch. If you want to have something in only world x, add it like the CafeteriaDoor object in a switch case. If you need to have the SAME inventory object in every world, you have to pass it like the UserWalk1 object. The more objects you want to have like that, the more useful it will be to either pass the whole world and get the references to the objects or (-as suggested in the first post on this page-) make the references static, so they are shared with all MyWorld instances.
SallySanban SallySanban

2017/2/24

#
Was I able to get this right?
//...
private Inventory inventory;

public MyWorld()
    {
        this(new UserWalk1(new EloraWalk1()), new Inventory(), 0, -1);
    }
public MyWorld(UserWalk1 p, Inventory i, int worldType, int lastWorldType)
    {
        inventory = i;
        //...
        addObject(inventory, 45, 361);
    }

public void changeBackground(int change) //1 for right, -1 or left
    {
        Greenfoot.setWorld(new MyWorld(player, inventory, type+change, type));
    }
If I want to add the same object in every world, I have to keep adding it to the parameter of the second constructor and work from there?
Super_Hippo Super_Hippo

2017/2/24

#
Yes, that's correct. As I mentioned, this is the alternative:
private static final UserWalk1 player = new UserWalk1(new EloraWalk1());
private static final Inventory inventory = new Inventory();

public MyWorld()
{
    this(0, -1);
}
public MyWorld(int worldType, int lastWorldType)
{
    //...
}
This alternative is probably better and makes adding new objects much easier.
SallySanban SallySanban

2017/2/24

#
Thank you very much! I understand that part now, somehow, hehe! Say, I wanted to make the UserWalk1 class unable to move right further only in background #5 so that whoever is playing the game has no other choice but to click the door to move on to the next background, how would I do it?
Super_Hippo Super_Hippo

2017/2/24

#
You could have this method in your world:
private boolean atRightEdge(int x)
{
    int xEdge = 600;
    switch(type)
    {
        case 5: xEdge=510; break;
    }
    return x>xEdge;
}
In your case, since you only have this "invisible wall in "world 5", this would be enough:
private boolean atRightEdge(int x)
{
    if (type==5) return x>510;
    return false;
}
In your UserWalk1 before moving (after checking for the key press):
if (!((MyWorld)getWorld()).atRightEdge())
{
    //moving right
}
SallySanban SallySanban

2017/2/25

#
Your first code makes UserWalk1 stop moving as soon as she enters background #5, but I want her to stop moving at the right most edge. The second code doesn't make her stop at all. :(
SallySanban SallySanban

2017/2/25

#
Here's what I tried to do:
 public boolean atRightEdge()
    {
        if(player.getX() == 510 && type == 5)
        {
            return false;
        }
        return true;
    }
In the UserWalk1 class:
public void controls()
    {
        if(Greenfoot.isKeyDown("right"))
        {
            if (((Alleyway4)getWorld()).atRightEdge()) //Alleyway4 is the name of my World
            {
                move(2);
                setImage(costume[Greenfoot.getRandomNumber(2)]);
            }
        }
//...
This seems to work now but I'm wondering if it's an efficient way to get this done. I don't know if there could possibly be any errors in running it in the future. What do you think?
danpost danpost

2017/2/25

#
You could eliminate the literals 'false' and 'true' in the 'atRightEdge' method with this:
public boolean atRightEdge()
{
    return type != 5 || player.getX() != 510;
}
Although the name of the method and what it returns are really total opposites. Better would be:
public boolean atRightEdge()
{
    return type == 5 && player.getX() == 510;
}
where line 5 in the UserWalk1 class 'controls' method would be:
if ( ! ((Alleyway4)getWorld()).atRightEdge() )
which asks if the actor is not at the right edge as the condition to move.
SallySanban SallySanban

2017/2/25

#
What if I wanted the "invisible wall" in other backgrounds too, along with #5?
There are more replies on the next page.
1
2
3
4