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

2021/3/31

Game won't load main game on Greenfoot website

Gbasire Gbasire

2021/3/31

#
I have a big problem. Basically, my game Trash Pokemon, when played on the greenfoot website, works well in the menu, but won't manage to set the main world after clicking on the "new game" button (it will stop the game and show a black screen), although it works super well on the greenfoot software. I have no idea why this is happening. Things I changed since last time when it worked : I made so that all objects come from the same classes, only the image, some variables and the collision changing with the constructor. Example : before, I had one class for every object like the sign, the flowerpot, the chair... etc, and now I'm only using specific classes (ObjectBasic, for objects without collision, ObjectSimple, for objects with a collision, ObjectText, for objects that display some text, and I did the same with my NPCs, there are 2 main classes : ObjectNPC and ObjectNPCItem. Some objects with special properties still use their own classes though.) and they have constructors with some parameters like "String object" for example, that directly sets the object's image in the constructor when created. Here is the code of ObjectSimple, to give an example :
import greenfoot.*;
public class ObjectSimple extends WorldObjects
{
    GreenfootImage centerTable = new GreenfootImage("/Objects/Simple/CenterTable.png");
    GreenfootImage houseTable = new GreenfootImage("/Objects/Simple/HouseTable.png");
    GreenfootImage flowerPot = new GreenfootImage("/Objects/Simple/FlowerPot.png");
    GreenfootImage houseSink = new GreenfootImage("/Objects/Simple/HouseSink.png");
    GreenfootImage chairLeft = new GreenfootImage("/Objects/Simple/ChairLeft.png");
    GreenfootImage chairRight = new GreenfootImage("/Objects/Simple/ChairRight.png");
    GreenfootImage bookShelf = new GreenfootImage("/Objects/Simple/BookShelf.png");
    GreenfootImage wallBackHouse = new GreenfootImage("/Objects/Simple/WallBackHouse.png");
    GreenfootImage wallBackCenter = new GreenfootImage("/Objects/Simple/WallBackCenter.png");
    GreenfootImage tree = new GreenfootImage("/Objects/Simple/Tree.png");
    GreenfootImage treeBottom = new GreenfootImage("/Objects/Simple/TreeBottom.png");
    GreenfootImage treeLine6 = new GreenfootImage("/Objects/Simple/TreeLine6.png");
    GreenfootImage buildCenterUp = new GreenfootImage("/Objects/Builds/CenterPokemon/CenterUp.png");
    GreenfootImage buildCenterLeft = new GreenfootImage("/Objects/Builds/CenterPokemon/CenterLeft.png");
    GreenfootImage buildCenterRight = new GreenfootImage("/Objects/Builds/CenterPokemon/CenterRight.png");
    GreenfootImage buildHomePlayerUp = new GreenfootImage("/Objects/Builds/HomePlayer/HomePlayerUp.png");
    GreenfootImage buildHomePlayerLeft = new GreenfootImage("/Objects/Builds/HomePlayer/HomePlayerLeft.png");
    GreenfootImage buildHomePlayerRight = new GreenfootImage("/Objects/Builds/HomePlayer/HomePlayerRight.png");
    public ObjectSimple(String object)
    {
        if(object == "centerTable")
        {
            setImage(centerTable);
            objectCenter = 25;
        }
        if(object == "houseTable")
        {
            setImage(houseTable);
            objectCenter = 27;
        }
        if(object == "flowerPot")
        {
            setImage(flowerPot);
            objectCenter = 25;
        }
        if(object == "houseSink")
        {
            setImage(houseSink);
            objectCenter = 20;
        }
        if(object == "chairLeft")
        {
            setImage(chairLeft);
            objectCenter = 15;
        }
        if(object == "chairRight")
        {
            setImage(chairRight);
            objectCenter = 15;
        }
        if(object == "bookShelf")
        {
            setImage(bookShelf);
            objectCenter = 25;
        }
        if(object == "tree")
        {
            setImage(tree);
            objectCenter = 50;
        }
        if(object == "treeBottom")
        {
            setImage(treeBottom);
            objectCenter = 50;
        }
        if(object == "treeLine6")
        {
            setImage(treeLine6);
            objectCenter = 50;
        }
        if(object == "wallBackHouse")
        {
            setImage(wallBackHouse);
            objectCenter = 20;
        }
        if(object == "wallBackCenter")
        {
            setImage(wallBackCenter);
            objectCenter = 20;
        }
        if(object == "buildCenterUp")
        {
            setImage(buildCenterUp);
            objectCenter = 75;
        }
        if(object == "buildCenterLeft")
        {
            setImage(buildCenterLeft);
            objectCenter = 75;
        }
        if(object == "buildCenterRight")
        {
            setImage(buildCenterRight);
            objectCenter = 75;
        }
        if(object == "buildHomePlayerUp")
        {
            setImage(buildHomePlayerUp);
            objectCenter = 75;
        }
        if(object == "buildHomePlayerLeft")
        {
            setImage(buildHomePlayerLeft);
            objectCenter = 75;
        }
        if(object == "buildHomePlayerRight")
        {
            setImage(buildHomePlayerRight);
            objectCenter = 75;
        }
    }
    public void act()
    {
        //both methods are super class methods, the collide method uses the objectCenter variable to collide with the player
        checkPlayer();
        collide();
    }
}
I thought that the fact that the classes had no base images would cause the crash, so I put a base image on all classes, but it did not work. I also cleaned the code of a lot of classes, but I don't think this has a lot to do with the problem, as it was simple things like changing "time = time + 1" to "time++" for example. I really need help to understand what's happening
Gbasire Gbasire

2021/3/31

#
Also, here is the code of TownWorld, the world that fails to load on the greenfoot website :
import greenfoot.*;
public class WorldTown extends World
{
    public static int originalXValue = 350;
    public static int originalYValue = 380;
    public static boolean object1WasTaken;
    public static boolean object2WasTaken;
    public static boolean npc1WasTaken;
    public static boolean npc2WasTaken;
    private int timer = 0;
    OverlayText overlaytext = new OverlayText();
    public WorldTown()
    {
        super(755, 570, 1);
        prepareTrees();
        prepareCenter();
        prepareHomePlayer();
        preparePokemonData();
        prepareData();
        prepare();
        setPaintOrder(ObjectBasicZone.class, OverlayText.class, ObjectBasicOver.class, Boy.class);
    }
    public void act()
    {
        timer++;
        if(timer == 1)
        {
            prepareBoy();
        }
    }
    public void prepareTrees()
    {
        addObject(new ObjectSimple("treeLine6"), 295, 30);
        addObject(new ObjectSimple("tree"), 32, 30);
        addObject(new ObjectSimple("tree"), 648, 30);
        addObject(new ObjectSimple("tree"), 722, 30);
        addObject(new ObjectSimple("tree"), 722, 110);
        addObject(new ObjectSimple("tree"), 722, 190);
        addObject(new ObjectSimple("tree"), 722, 270);
        addObject(new ObjectSimple("tree"), 722, 350);
        addObject(new ObjectSimple("tree"), 722, 430);
        addObject(new ObjectSimple("tree"), 722, 510);
        addObject(new ObjectSimple("tree"), 32, 110);
        addObject(new ObjectSimple("tree"), 32, 190);
        addObject(new ObjectSimple("tree"), 32, 270);
        addObject(new ObjectSimple("tree"), 32, 350);
        addObject(new ObjectSimple("tree"), 32, 430);
        addObject(new ObjectSimple("tree"), 32, 510);
        addObject(new ObjectBasicOver("treeTop"), 722, 550);
        addObject(new ObjectBasicOver("treeTop"), 32, 550);
        addObject(new ObjectBasicOver("treeTop"), 332, 550);
        addObject(new ObjectBasicOver("treeTop"), 256, 550);
        addObject(new ObjectBasicOver("treeTop"), 181, 550);
        addObject(new ObjectBasicOver("treeTop"), 108, 550);
        addObject(new ObjectBasicOver("treeTop"), 645, 550);
        addObject(new ObjectBasicOver("treeTop"), 256, 550);
        addObject(new ObjectBasicOver("treeTop"), 407, 550);
        addObject(new ObjectBasicOver("treeTop"), 566, 550);
        addObject(new ObjectBasicOver("treeTop"), 486, 550);
    }
    public void prepare()
    {
        if(object1WasTaken == false)
            addObject(new ObjectItem("potion", 1, 1), 90, 110);
        addObject(new ObjectBasicZone("townTrash"), 377, 280);
        addObject(new ObjectBasic("groundPath"), 377, 280);
        addObject(new ObjectText("sign", "Route 113"), 514, 105);
        addObject(new ObjectNPC(
            "oldMan", true, "down", 
            "I was a trash pokémon trainer when I was young."), 
            350, 200);
        addObject(new Flower(), 610, 400);
        addObject(new Flower(), 610, 370);
        addObject(new Flower(), 610, 340);
        addObject(new Flower(), 513, 340);
        addObject(new Flower(), 513, 400);
        addObject(new Flower(), 513, 370);
        addObject(new Flower(), 610, 260);
        addObject(new Flower(), 513, 260);
        addObject(new Flower(), 610, 230);
        addObject(new Flower(), 513, 230);
        addObject(new Flower(), 610, 200);
        addObject(new Flower(), 513, 200);
    }
    public void prepareCenter()
    {
        addObject(new DoorCenter(), 199, 241);
        addObject(new ObjectSimple("buildCenterLeft"), 145, 180);
        addObject(new ObjectSimple("buildCenterRight"), 253, 180);
        addObject(new ObjectSimple("buildCenterUp"), 199, 140);
        addObject(new ObjectBasicOver("buildCenterMiddle"), 199, 202);
    }
    public void prepareHomePlayer()
    {
        addObject(new DoorPlayerHome(), 164, 486);
        addObject(new ObjectSimple("buildHomePlayerLeft"), 129, 425);
        addObject(new ObjectSimple("buildHomePlayerRight"), 235, 425);
        addObject(new ObjectSimple("buildHomePlayerUp"), 164, 384);
        addObject(new ObjectBasicOver("buildHomePlayerMiddle"), 164, 446);
    }
    public void prepareBoy()
    {
        addObject(new Boy(), originalXValue, originalYValue);
    }
    public void prepareData()
    {
        addObject(new DataPokemon(), 0, 0);
        addObject(new DataInventory(), 0, 0);
        addObject(new DataWildPokemon(), 0, 0);
        addObject(new DataSound(), 0, 0);
    }
    public void preparePokemonData()
    {
        addObject(new PokemonEmboar(), 0, 0);
        addObject(new PokemonGeodude(), 0, 0);
    }
    public void overlayText()
    {
        addObject(overlaytext, 378, 515);
    }
    public void removeOverlayText()
    {
        removeObject(overlaytext);
    }
}
I really need help, please help me !
Gbasire Gbasire

2021/3/31

#
Tested more things, but none worked, I'm desperate :( If anyone knows how to fix it, it would be very appreciated.
Gbasire Gbasire

2021/3/31

#
just quickly bumping the topic, I searched through my whole code, but still can't figure out what could be wrong
danpost danpost

2021/4/1

#
Gbasire wrote...
Tested more things, but none worked, I'm desperate :( If anyone knows how to fix it, it would be very appreciated.
It may be an overload of sorts. Now that you have "combined" classes, each and every ObjectSimple object will have to create and store 18 images. Try having the class store the images by making lines 4 thru 21 "static".
rocket770 rocket770

2021/4/1

#
No clue why it's crashing but please, for your ObjectSimple constructor where you pass in a string and then have like a hundred lines of "if" statements, either use a switch/case statement as it's much more efficient. Otherwise, instead of taking a string parameter, take a GreenfootImage parameter and maybe an integer for the object centre like:
public ObjectSimple(GreenfootImage img, int objectCenter){
       setImage(img);
       this.objectCenter= objectCenter; 
}
Or if you must for some other reason, use a case statement:
public ObjectSimple(String object){
    switch(object){
         case "charLeft": setImage(charLeft);
                                   objectCenter = 15;
                                   break;
         case "flowerPot": setImage(flowerPot);
                                    objectCenter = 25;
                                    break; 
        // you get the idea

    }
}
Gbasire Gbasire

2021/4/1

#
Thank you danpost, I'll try that, I did it like that at the beginning but thought it had no use, thanks :) And thank you as well rocket770, I'm still a bit new to java so I didn't know what was the most efficient way to do it. I just probably won't do it with objectCenter as a parameter, I tried it as well at the beginning but it was too difficult to remember what was all the objects values. Thank you again, I'll post when I'll be at home.
danpost danpost

2021/4/1

#
What does objectCenter represent?
Gbasire Gbasire

2021/4/1

#
objectCenter is used in the actor super class WorldObjects to start a collision in the player class (Boy.class) when he gets close to the center of the object. For example, if objectCenter is at 20, the collision will happen when the player touches the center of the object + 20 on the y axis. This allows the player to walk in front of objects and still collide with them once he gets to a certain point :
//in WorldObjects.class
    public void checkPlayer()
    {
        Boy boy = (Boy)getWorld().getObjects(Boy.class).get(0);
        playerx = boy.getX();
        playery = boy.getY();
    }
    public void collide()
    {
        Boy boy = (Boy)getWorld().getObjects(Boy.class).get(0);
        if(isTouching(Boy.class) && playery < getY() + objectCenter)
        {
            boy.hitBox();
        }
    }
//in Boy.class
    public void hitBox()
    {
        if(this.getWorld().getClass() == WorldRoute.class)
        {
            setLocation(originalX, originalY);
        }
        else if(this.getWorld().getClass() == WorldTown.class)
        {
            setLocation(originalX1, originalY1);
        }
        else if(this.getWorld().getClass() == WorldCenter.class)
        {
            setLocation(originalX2, originalY2);
        }
        else if(this.getWorld().getClass() == WorldPlayerRoom.class)
        {
            setLocation(originalX3, originalY3);
        }
        else if(this.getWorld().getClass() == WorldTest.class)
        {
            setLocation(originalX9, originalY9);
        }
    }
Gbasire Gbasire

2021/4/1

#
Oh my god, after 1 hour of testing, I finally understand what was wrong. The game simply doesn't load because it doesn't recognize the images' path in the folders. every time I called a GreenfootImage, I wrote something like "new GreenfootImage("/Objects/Basic/Couch.png");" It works well in the software, but not in the website, juste because of the first "/". The solution was basically to remove it like this : "new GreenfootImage("Objects/Basic/Couch.png");" This was a nightmare to find but I'm glad I did lol. Thanks for the help !
danpost danpost

2021/4/1

#
Actually, best might be to remove lines 4 thru 21 altogether with a constructor like this:
public ObjectSimple(String object)
{
    setImage("/Objects/" + (object.beginsWith("Build) ? "Builds/" : "Simple/") + object + ".png");
    switch(object.substring(0, 4))
    {
        case "cent" :
        case "flow" :
        case "book" : objectCenter = 25; break;
        case "hous" : objectCenter = object.charAt(5) == "T" ? 27 : 20; break;
        case "chai" : objectCenter = 15; break;
        case "tree" : objectCenter = 50; break;
        case "wall" : objectCenter = 20; break;
        case "buil" : objectCenter = 75; break;
        default : objectCenter = 25; break;
    }
}
With this, you will have to either make all the first character of strings being passed to the ObjectSimple constructor uppercase or rename all the image files with lowercase first characters.
You need to login to post a reply.