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

2017/2/25

How do I create an inventory?

1
2
3
4
danpost danpost

2017/3/2

#
Please show the class code where you declare and create the Inventory object (in the class where 'new Inventory()' is located).
SallySanban SallySanban

2017/3/2

#
Here is where Inventory() is created:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * Write a description of class MyWorld here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Alleyway4 extends World
{
    private int type;
    private static final UserWalk1 player = new UserWalk1(new EloraWalk1());
    private static final Inventory inventory = new Inventory();
    private int changeLeft = 91, changeRight = 519;
    private static final String[] bgImages =
        {
            "Alleyway 4.PNG", //0
            "Kalachuchi Walk 1.JPG", //1
            "School Entrance.JPG", //2
            "Lockers 1.JPG", //3
            "Lockers 2.JPG", //4
            "Cafeteria Entrance.JPG", //5
            "Cafeteria 1.JPG", //6
            "Cafeteria 2.PNG", //7
            "Cafeteria Entrance Stairs.JPG", //8
            "Classroom Entrance.JPG", //9
            "Classroom 1.jpg", //10
            "Student Bathroom Entrance.JPG", //11
            "Student Bathroom.JPG", //12
            "Classroom Entrance Stairs.JPG", //13
            "Library Entrance.JPG", //14
            "Library 1.JPG", //15
            "Library 2.JPG", //16
            "Faculty Study Entrance.PNG", //17
            "Faculty Study.JPG", //18
            "Principal's Office.JPG", //19
            "Teacher Bathroom Entrance.JPG", //20
            "Female Teacher Bathroom.JPG", //21
            "Male Teacher Bathroom.JPG", //22
            "Basement Entrance.JPG", //23
            "Janitor's Closet.JPG", //24
            "Dark Room.PNG" //25
        };

    public Alleyway4()
    {
        this(0, -1);
    } 

    public Alleyway4(int worldType, int lastWorldType)
    {
        super(600, 400, 1);
        type = worldType;
        setBackground(new GreenfootImage(bgImages[type]));
        int x, y = 243; //where to add User
        int xElora, yElora = 270; //where to add Elora

        if(lastWorldType < worldType) //moved right
        {
            x = 154;
            xElora = 33;
        }
        else //moved left
        {
            x = 500;
            xElora = 578;
        }

        switch(type)
        {
            case 2: addObject(new Gate(), 553, 306); break;
            case 5: addObject(new CafeteriaDoor(), 429, 146); break;
            case 8: addObject(new CafeteriaStairs(), 536, 323); addObject(new CafeteriaDoor2(), 234, 176); break;
            case 9: addObject(new ClassroomDoor(), 368, 202); break;
            case 11: addObject(new StudentDoor(), 505, 195); addObject(new SipmaMini(), 381, 227); break;
            case 13: addObject(new ClassroomStairs(), 505, 307); break;
            case 14: addObject(new LibraryDoor(), 303, 198); break;
            case 17: addObject(new FacultyDoor(), 76, 177); addObject(new PrincipalDoor(), 498, 175); break;
            case 20: addObject(new GirlDoor(), 265, 187); addObject(new BoyDoor(), 66, 189); break; //change x and y coordinates once you get the actual door
            case 23: addObject(new JanitorDoor(new StarKey()), 102, 208); addObject(new BasementDoor(), 478, 210); break;
        }

        addObject(player, x, y);
        addObject(player.getEloraWalk(), xElora, yElora);
        addObject(inventory, 45, 361);
        setPaintOrder(Texts.class, TextBox.class, Characters.class, Props.class, Overlaps.class, UserWalk1.class, EloraWalk1.class, SipmaMini.class, Doors.class);
    }

    public void changeBackground(int change) //1 for right, -1 or left
    {
        Greenfoot.setWorld(new Alleyway4(type + change, type));
    }

    public boolean atRightEdge()
    {
        if(player.getX() == 510 && type == 5)
        {
            return true;
        }
        else if(player.getX() == 510 && type == 10)
        {
            return true;
        }
        else if(player.getX() == 510 && type == 12)
        {
            return true;
        }
        else if(player.getX() == 510 && type == 14)
        {
            return true;
        }
        else if(player.getX() == 510 && type == 18)
        {
            return true;
        }
        else if(player.getX() == 510 && type == 19)
        {
            return true;
        }
        else if(player.getX() == 510 && type == 21)
        {
            return true;
        }
        else if(player.getX() == 510 && type == 22)
        {
            return true;
        }
        else if(player.getX() == 510 && type == 24)
        {
            return true;
        }
        else if(player.getX() == 510 && type == 25)
        {
            return true;
        }
        return false;
    }
    
    public boolean atLeftEdge()
    {
        if(player.getX() == 100 && type == 8)
        {
            return true;
        }
        return false;
    }

    public void act()
    {
        int x = player.getX();
        
        if(x < changeLeft && type == 0) //Stopping rule for FIRST background
        {
            player.setLocation(91, 243);
        }
        else if(x < changeLeft && type != 0) //General moving rule to the LEFT 
        {
            changeBackground(-1);
            if(type == 11)
            {
                changeBackground(-2);
            }
            else if(type == 13)
            {
                changeBackground(-2);
            }
            else if(type == 19)
            {
                changeBackground(-2);
            }
            else if(type == 20)
            {
                changeBackground(-3);
            }
            else if(type == 22)
            {
                changeBackground(-2);
            }
            else if(type == 23)
            {
                changeBackground(-3);
            }
            else if(type == 25)
            {
                changeBackground(-2);
            }
        }
        else if(x > changeRight && type != 23) //General moving rule to the RIGHT
        {
            changeBackground(1);
            if(type == 9)
            {
                changeBackground(2);
            }
            else if(type == 11)
            {
                changeBackground(2);
            }
            else if(type == 17)
            {
                changeBackground(3);
            }
            else if(type == 20)
            {
                changeBackground(3);
            }
        }
        else if(x > changeRight && type == 23) //Stopping rule for LAST background
        {
            player.setLocation(519, 243);
        }
    }
}
Here is my Inventory class code:
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.List;
import java.awt.Color;
import java.util.ArrayList;

/**
 * Write a description of class Inventory here.
 * 
 * @author (your name) 
 * @version (a version number or a date)
 */
public class Inventory extends Props
{
    public static List<Actor> collectedObjects = new ArrayList(0); //the hints which were collected and should show up in the inventory
    public boolean inventoryShowing = false; //true if the inventory is showing right now
    public List<Actor> inventoryObjects = new ArrayList(0); //all actors which are added when x is pressed so they can be removed when x is pressed again
    //CaramelApple apple = new CaramelApple();
    
    /**
     * Act - do whatever the Inventory wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        clue();
        if(Greenfoot.isKeyDown("x"))
        {
            showInventory();
        }
        if(Greenfoot.mouseClicked(this))
        {//remove inventory
            getWorld().removeObjects(inventoryObjects); //remove all objects relating to the inventory
            inventoryShowing = false;
            inventoryObjects = new ArrayList(0);
        }
    } 

    public void clue()
    {
        //collectedObjects.add(apple);
        for(Clues h: getWorld().getObjects(Clues.class))
        {
            if (Greenfoot.mouseClicked(h))
            {
                collectedObjects.add(h); //add the hint to the list of collected hints
                getWorld().removeObject(h); //remove the clicked hint from the world
            }
        }
    }

    public void showInventory()
    {
        if(!inventoryShowing)
        {
            int i = 0, numItems = collectedObjects.size();

            for(i = 0; i < numItems; i++)
            {
                Actor item = collectedObjects.get(i);
                item.setImage(new GreenfootImage(item.getImage())); //.scale(10, 10));
                int xItem = (i + 2) * 60;
                getWorld().addObject(item, xItem, getY());
                inventoryObjects.add(item);
            }
            i++;
        }
        inventoryShowing = true;
    }
}
danpost danpost

2017/3/2

#
Okay -- change line 13 to:
private static Inventory inventory;
Then before line 85, insert the following line:
if (worldType == 0 && lastWorldType == -1) inventory = new Inventory();
and remove 'static' from the collectedObjects declaration line in the Inventory class (line 14). Better yet, just add the following line after line 47:
inventory.collectedObjects.clear();
SallySanban SallySanban

2017/3/2

#
Thanks! That worked. I also need a door to be accessible when a specific key is in the inventory. This is what I did in the class of the key:
public int isFirstTime = 1;
    public boolean isCollected = false;
    
    /**
     * Act - do whatever the StarKey wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        if(Greenfoot.mouseClicked(this) && isFirstTime == 1)
        {
            isCollected = true;
            isFirstTime = 0;
        }
    }    
In the class of the door:
private StarKey star;
    
    public JanitorDoor(StarKey s)
    {
        star = s;
    }
    
    /**
     * Act - do whatever the JanitorDoor wants to do. This method is called whenever
     * the 'Act' or 'Run' button gets pressed in the environment.
     */
    public void act() 
    {
        if(Greenfoot.mouseClicked(this) && star.isCollected)
        {
            ((Alleyway4) getWorld()).changeBackground(1); //changeBackground sets the background to the one inside the door (as if the player enters the room)
        }
    }    
This doesn't work because the boolean isCollected does not become true once the key is clicked.
danpost danpost

2017/3/2

#
SallySanban wrote...
Thanks! That worked.
I hope you used the edited way or the following will not work. You will not need the 'boolean isCollected' field. For the moment, you can have the following for the StarKey class:
public class StarKey extends greenfoot.Actor {}
The door can just check the inventory to see if the key is there:
if (Greenfoot.mouseClicked(this) && Alleyway4.getInventory().collectedObjects.contains(star))
If you do not already have one, add the following method into your Alleyway4 class:
public static Inventory getInventory()
{
    return inventory;
}
As an alternative to the last step (adding the method), you could just declare the inventory as public and change 'getInventory()' in the previous step to 'inventory'.
Super_Hippo Super_Hippo

2017/3/2

#
Btw, you can change your atRightEdge method so it only compares the position once:
public boolean atRightEdge()
{
    if(player.getX() == 510))
    {
        switch (type)
        {
            case 5: case 10: case 12: case 14: case 18: case 19: case 21: case 22: case 24: case 25:
            return true;
        }
    }
    return false;
}
The switch can also be the following if-condition, but I find that the switch is more clearly arranged:
if (type==5 || type==10 || type==12 || type==14 || type==18 || type==19 || type==21 || type==22 || type==24 || type==25)
{
    return true;
}
With this, you can also put it together.
public boolean atRightEdge()
{
    return player.getX()==510 && (type==5 || type==10 || type==12 || type==14 || type==18 || type==19 || type==21 || type==22 || type==24 || type==25);
}
You can use which one you want but I would suggest to not use compare the users position to 510 for every type again.
SallySanban SallySanban

2017/3/2

#
danpost wrote...
SallySanban wrote...
Thanks! That worked.
I hope you used the edited way or the following will not work. You will not need the 'boolean isCollected' field. For the moment, you can have the following for the StarKey class:
public class StarKey extends greenfoot.Actor {}
The door can just check the inventory to see if the key is there:
if (Greenfoot.mouseClicked(this) && Alleyway4.getInventory().collectedObjects.contains(star))
If you do not already have one, add the following method into your Alleyway4 class:
public static Inventory getInventory()
{
    return inventory;
}
As an alternative to the last step (adding the method), you could just declare the inventory as public and change 'getInventory()' in the previous step to 'inventory'.
I tried that code, but the backgrounds still don't switch. I don't think the door recognizes that the key is already inside the list.
SallySanban SallySanban

2017/3/2

#
Super_Hippo wrote...
Btw, you can change your atRightEdge method so it only compares the position once:
public boolean atRightEdge()
{
    if(player.getX() == 510))
    {
        switch (type)
        {
            case 5: case 10: case 12: case 14: case 18: case 19: case 21: case 22: case 24: case 25:
            return true;
        }
    }
    return false;
}
The switch can also be the following if-condition, but I find that the switch is more clearly arranged:
if (type==5 || type==10 || type==12 || type==14 || type==18 || type==19 || type==21 || type==22 || type==24 || type==25)
{
    return true;
}
With this, you can also put it together.
public boolean atRightEdge()
{
    return player.getX()==510 && (type==5 || type==10 || type==12 || type==14 || type==18 || type==19 || type==21 || type==22 || type==24 || type==25);
}
You can use which one you want but I would suggest to not use compare the users position to 510 for every type again.
Thank you! I'll try that once I solve this problem.
danpost danpost

2017/3/2

#
SallySanban wrote...
I tried that code, but the backgrounds still don't switch. I don't think the door recognizes that the key is already inside the list.
There is an easy way to check that -- change the 'if' line to this:
if (Greenfoot.mouseClicked(this))
in the Door class and test it out. Click on the door and see if the background changes.
SallySanban SallySanban

2017/3/2

#
It does, so it means the line after the && was not followed?
danpost danpost

2017/3/2

#
SallySanban wrote...
It does, so it means the line after the && was not followed?
Apparently, it was tested and the result failed (false was returned). Show the code that adds the door and key into the world and all related code (dealing with the door or the key) within the class.
SallySanban SallySanban

2017/3/2

#
I actually don't add the key into the World yet. I just manually add it for now to test it out. (If I add in from the World class it still shows up when I go back to that background, even if I clicked it already) I add the door from my World class, which I already showed you above, but this is the specific method:
 public Alleyway4(int worldType, int lastWorldType)
    {
        super(600, 400, 1);
        type = worldType;
        setBackground(new GreenfootImage(bgImages[type]));
        int x, y = 243; //where to add User
        int xElora, yElora = 270; //where to add Elora

        if(lastWorldType < worldType) //moved right
        {
            x = 154;
            xElora = 33;
        }
        else //moved left
        {
            x = 500;
            xElora = 578;
        }

        switch(type)
        {
            case 2: addObject(new Gate(), 553, 306); break;
            case 5: addObject(new CafeteriaDoor(), 429, 146); break;
            case 8: addObject(new CafeteriaStairs(), 536, 323); addObject(new CafeteriaDoor2(), 234, 176); break;
            case 9: addObject(new ClassroomDoor(), 368, 202); break;
            case 11: addObject(new StudentDoor(), 505, 195); break;
            case 13: addObject(new ClassroomStairs(), 505, 307); break;
            case 14: addObject(new LibraryDoor(), 303, 198); break;
            case 17: addObject(new FacultyDoor(), 76, 177); addObject(new PrincipalDoor(), 498, 175); break;
            case 20: addObject(new GirlDoor(), 265, 187); addObject(new BoyDoor(), 66, 189); break; //change x and y coordinates once you get the actual door
            case 23: addObject(new JanitorDoor(), 102, 208); addObject(new BasementDoor(), 478, 210); break;
        }

        addObject(player, x, y);
        addObject(player.getEloraWalk(), xElora, yElora);
        addObject(inventory, 45, 361);
        setPaintOrder(Texts.class, TextBox.class, Characters.class, Props.class, Overlaps.class, UserWalk1.class, EloraWalk1.class, SipmaMini.class, Doors.class);
    }
In the StudentDoor class, which is the door:
public void act() 
    {
        if(Greenfoot.mouseClicked(this) && ((Alleyway4) getWorld()).getInventory().collectedObjects.contains(DiamondKey.class))
        {
            ((Alleyway4) getWorld()).changeBackground(1);
        }
    }   
In the DiamondKey class, which is the key that's supposed to 'unlock' the door:
public void act() 
    {
        if(Greenfoot.mouseClicked(this))
        {
            ((Alleyway4) getWorld()).getInventory().collectedObjects.add(this);
            ((Alleyway4) getWorld()).removeObject(this);
        }
    }
danpost danpost

2017/3/2

#
Yes, but line 31 of the Alleyway4 code just given does not set a specific key to the janitor's door. The JanitorDoor constructor shown earlier requires a Starkey object to be assigned to it. If there is no other constructor in the class, your project should not compile properly. How are you assigning the specific keys to the specific doors?
SallySanban SallySanban

2017/3/2

#
I would put them in the parameter of the door. I just removed them because it didn't work at the time.
danpost danpost

2017/3/2

#
SallySanban wrote...
If I add in from the World class it still shows up when I go back to that background, even if I clicked it already
When you create a new background, you can immediately remove anything that is already in the inventory:
Alleyway4 aw4 = new Alleyway4(type, lastType);
aw4.removeObjects(inventory.collectedObjects);
There are more replies on the next page.
1
2
3
4