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

2019/4/11

Game runs slow/fails when switching worlds

renniemm renniemm

2019/4/11

#
My game is almost finished. This one thing is driving me crazy! I have a world subclass called Menu that is a title screen. When the game runs it displays an image and you press space to start (which switches it to the other world subclass called MyWorld (the actual game)). Sometimes it works perfectly. But about 3/4 of the time, when you press the space bar, nothing happens. On Greenfoot, the little loading symbol appears. If you try to reset, a message comes up that says "Execution is taking a long time. You may need to terminate execution using the spinning button, below right." So I have to terminate it and try it a few more times until it works. I have no clue what is causing this. Here is my menu subclass if it helps. It's very simple and only starts the music, displays the image, and (usually) switches to the game world when the space key is pressed:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Menu extends World
{
 
    
    public Menu()
    {   
         
        super(600, 400, 1);
        
    }
    public static GreenfootSound backgroundMusic = new GreenfootSound("nyanmusic.mp3");
 
     public void started(){
        
        backgroundMusic.playLoop();
    }
    
    public void act(){
        if (Greenfoot.isKeyDown("space")) {
            Greenfoot.setWorld(new MyWorld());
    }
}
}
Super_Hippo Super_Hippo

2019/4/11

#
More important to show would be the MyWorld constructor and the methods it might call because the creation of the world seems to cause problems.
renniemm renniemm

2019/4/11

#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
public class MyWorld extends World
{
    private double timer = 1500.0;
    DecimalFormat seconds = new DecimalFormat("#.00");
    GreenfootSound backgroundMusic = new GreenfootSound("nyanmusic.mp3");
     
    public MyWorld()
    {   
         
        super(600, 400, 1);
        prepare();
        act();
 
    }
    public void prepare(){
        setPaintOrder(Cat.class, Cupcake.class);
        addObject(new Cat(), 300, 200);
 
        for(int i = 0; i<20; i++){
            addObject(new Cupcake(), Greenfoot.getRandomNumber(580)+10,Greenfoot.getRandomNumber(380)+10);
 
        }
        for(int j=0; j<20; j++){
            addObject(new Broccoli(), Greenfoot.getRandomNumber(580)+10, Greenfoot.getRandomNumber(380)+10);
        }
    }
    public void act(){
         
         
        if(timer!=0.00){
            timer --;
            if(timer == 0.00){
                Greenfoot.stop();
                failed();
                
                Greenfoot.playSound("fail.mp3");
 
            }
        }
        showTime();
        List cupcakes = getObjects(Cupcake.class);
        if(cupcakes.size()==0){
            Greenfoot.stop();
            showEndTime();
             
            Greenfoot.playSound("victory.mp3");
             
 
        }
        List broccoli= getObjects(Broccoli.class);
        if(broccoli.size()<20){
            Greenfoot.stop();
             
            Greenfoot.playSound("fail.mp3");
            ateBroccoli();
        }
    }
 
    public void started(){
        Menu.backgroundMusic.playLoop();
    }
 
    public void stopped(){
        Menu.backgroundMusic.pause();
    }
 
    private void showTime(){
        showText("Time: "+(seconds.format(timer/60.0)), 60, 20);
    }
 
    public void showEndTime(){
        double score = 25.0-(timer)/60.0;
        String finalscore= seconds.format(score);
        showText("You won! You finished in "+finalscore+" seconds!", 300, 200);
        Greenfoot.stop();
 
    }
 
    public void ateBroccoli(){
        showText("Oh no! You ate the broccoli! Bleh! Try again.", 300, 200);
 
    }
 
    private void failed(){
        showText("Oh no! You ran out of time! :( Try again.", 300, 200);
    }
 
     
}
Super_Hippo Super_Hippo

2019/4/11

#
I don't see a problem with the code which could cause it. Could check the constructors of the objects that you create if you do something weird there. But I also sometimes have the problem that I have to close and restart Greenfoot. So it is possible that it isn't your fault. You could try to increase the java heap space or the shm size (even though you don't get an error message). This won't solve, but could delay the problem. For the java heap size, find the Greenfoot installation folder. Then in the "lib" folder you can find the greenfoot.defs and bluej.defs file. Not really sure which one you need to edit, but you can basically just edit both. You will find a line like this:
1
2
3
greenfoot.windows.vm.args=-Xmx512M -Djavafx.embed.singleThread=true
 
bluej.windows.vm.args=-Xmx512M -Djavafx.embed.singleThread=true
Increase the 512M. Make sure your PC can handle it. (Make a backup of the file or remember what you changed. Just in case.) You probably can't save the file directly even with Admin rights. Save the file for example on the desktop (make sure you don't save it as a TXT file and then move it to the correct folder again. You need Admin rights to do that. For the shm size, you get this message when you create a world with too many cells:
World size is too large. If your world contains more than around 2.5 million pixels you will need to do the following. Close your project, then edit project.greenfoot in a text editor to add the following line: shm.size=40000000
You can still do that even though you don't get this error. Maybe it helps. I don't know.
renniemm renniemm

2019/4/11

#
I'm using a mac- also, I've tried this on different computers and have the same issue each time. I tried to run the JAR file too but that didn't work either (only sometimes). Here's what I have for my objects. It's not much:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Cupcake extends Actor
{
    GifImage cupcake = new GifImage("cupcake.gif");
    public void act()
    {
        setImage(cupcake.getCurrentImage());
    }   
    protected void addedToWorld(World w)
    {
    while (!getObjectsInRange(10, Cupcake.class).isEmpty() || !getObjectsInRange(50, Broccoli.class).isEmpty()|| !getObjectsInRange(50, Cat.class).isEmpty());
    {
        setLocation(10+Greenfoot.getRandomNumber(getWorld().getWidth()), 10+Greenfoot.getRandomNumber(getWorld().getHeight()));
    }
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Broccoli extends Actor
{
public void act()
    {
         
    }   
    protected void addedToWorld(World w)
    {
    while (!getObjectsInRange(10, Broccoli.class).isEmpty() || !getObjectsInRange(50, Cupcake.class).isEmpty()|| !getObjectsInRange(50, Cat.class).isEmpty())
    {
        setLocation(10+Greenfoot.getRandomNumber(getWorld().getWidth()), 10+Greenfoot.getRandomNumber(getWorld().getHeight()));
    }
}
}
And the last object which is the player:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public class Cat extends Actor
{
GifImage gifImage = new GifImage("nyan.gif");
    GifImage flipped = new GifImage("flipnyan.gif");
    public void act()
    {
 
        int speed = 3;
 
        if(Greenfoot.isKeyDown("up")){
            setImage(gifImage.getCurrentImage());
            setRotation(270);
            setLocation(getX(), getY() - speed);}
        if(Greenfoot.isKeyDown("down")){
            setImage(gifImage.getCurrentImage());
            setRotation(90);
            setLocation(getX(), getY() + speed);}
 
        if(Greenfoot.isKeyDown("left")){
            setImage(flipped.getCurrentImage());
            setRotation(0);
            setLocation(getX() - speed, getY());
 
        }
 
        if(Greenfoot.isKeyDown("right")){
            setImage(gifImage.getCurrentImage());
            setRotation(0);
            setLocation(getX() + speed, getY());}
        if(canSee(Cupcake.class)){
            eat(Cupcake.class);
        }   
        if(canSee(Broccoli.class)){
            eat(Broccoli.class);
 
        }
    }
 
    public boolean canSee(Class clss)
    {
        Actor actor = getOneObjectAtOffset(0, 0, clss);
        return actor != null;       
    }
 
    public void eat(Class clss)
    {
        Actor actor = getOneObjectAtOffset(0, 0, clss);
        if(actor != null) {
            getWorld().removeObject(actor);
        }
        Greenfoot.playSound("chomp.wav");
    }
}
I don't see anything weird with it but I'm not sure. Do you know how to change the shm on a Mac? I can't find an installation folder on here. It's just the application and the zip file.
Super_Hippo Super_Hippo

2019/4/11

#
The shm is not in the installation folder, it is the project.greenfoot file which you open when you open your scenario in Greenfoot. (Unless this is different with a Mac, I use Windows.) But for your problem: Try to increase the world size and/or decrease the number of objects you add and/or decrease the minimum space between objects. In a bad case, an object can't find a possible place and it keeps searching for it forever. If the total number of objects doesn't matter that much, you could also do something like this in the addedToWorld method. Then it will stop searching for a new place and removes the object when it failed too often.
1
2
3
4
5
6
7
8
9
10
int numOfTries = 0;
while (<too near to an object>)
{
    if (++numOfTries>20)
    {
        getWorld().removeObject(this);
        return;
    }
    <choose another random location>;
}
You need to login to post a reply.