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

2016/6/6

Get Timer To Stop At 30 Seconds

ssenese19 ssenese19

2016/6/6

#
I have a simple timer class that counts up (from code that I found on the forums and then modified) and am wondering how I can get it to stop at a certain time. So far I tried Greenfoot.stop(); but the entire game stops as opposed to just the timer. Additionally, if you had any advice on how to add seconds onto a timer (for example, if my game had a feature where when you found an object, five seconds would be added to the timer) that would be appreciated. Thanks! (High School CompSci Student)
ssenese19 ssenese19

2016/6/6

#
1
2
3
if ( time >= 30) {
    Greenfoot.stop();
}
danpost danpost

2016/6/6

#
You will have to show the code to the timer class and any code related to object(s) created from the class (indicate where each piece of code is from -- class and method if applicable).
ssenese19 ssenese19

2016/6/6

#
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
import greenfoot.*;
public class TimerActor extends Actor {
    private boolean running = false;
    private int millisElapsed = 0;
    private long lastTime = 0;     
     
   public TimerActor() {
       updateImage();
   }
     
   public void start() {
       millisElapsed = 0;
       lastTime = 0;
   }
     
   public void gamePaused() {
       lastTime = 0;
    }
     
    public void act() {
        long time = System.currentTimeMillis();
        if(lastTime != 0) {
            long diff = time - lastTime;
            millisElapsed += diff;
        }
        lastTime = time;
         
        updateImage();
        // add world instance field
    }
        
        public void updateImage() {
        // Calculate minutes & seconds elapsed
       int millis = millisElapsed % 1000;
       int secs = (millisElapsed / 1000) % 60;
       int mins = millisElapsed / 60000;
       // Convert these into text
       String millisText = String.format("%03d", millis);
       String secsText = String.format("%02d", secs);
       String minsText = "" + mins;  
       String text = minsText + ":" + secsText + "." + millisText;
       // Update the image
      GreenfootImage img = new GreenfootImage(text, 25, null, null);
      img.setColor(java.awt.Color.white);
      setImage(img);
        
    }
}
This is the timer actor
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
public class World1 extends World
{
    startButton play = new startButton();
    /**
     * Constructor for objects of class World1.
     *
     */
    public World1()
    {   
         
        super(800, 600, 1);
        populateWorld();
         
    }
         
    public void populateWorld()
        {
        addObject (new Waldo(), 30, 105);
        addObject (new Whitebeard(), 320, 225);
        addObject (new Woof(), 600, 90);
        addObject (new Odlaw(),160, 300);
        addObject (new Wenda(), 615, 275);
        TimerActor timer = new TimerActor();
        addObject(timer,200,550);
        addObject(play,300,550);
         
         
         
        for (int i = 0; i < 100; i++) {
            addObject (new Ladybug(), (Greenfoot.getRandomNumber(801)), (Greenfoot.getRandomNumber(401)));
        }
        for (int i = 0; i < 100; i++) {
            addObject (new Sheep(), (Greenfoot.getRandomNumber(801)), (Greenfoot.getRandomNumber(401)));
        }
        for (int i = 0; i < 100; i++) {
            addObject (new LightHouse(), (Greenfoot.getRandomNumber(801)), (Greenfoot.getRandomNumber(401)));
    }
     for (int i = 0; i < 100; i++) {
            addObject (new moreLightHouse(), (Greenfoot.getRandomNumber(801)), (Greenfoot.getRandomNumber(401)));
    }
    
}
    public void act()
    {
        start();
         
    }
    public void start() {
     
    if(Greenfoot.mouseClicked(play)) {
        removeObject(play);
        Greenfoot.setWorld(new World2());
         
    }
    if ( timer >= 30)
        {
            Greenfoot.setWorld(new waldoWorld());
        }
}
     
     
}
This is my world
danpost danpost

2016/6/6

#
In the TimerActor class, remove the 'boolean running' (it is not being used). Then, I would move everything in the act method inside the 'if' block. There is no need to do anything unless the timer is in a running state. This would make this:
1
2
3
4
5
6
7
8
9
10
public void act()
{
    if (lastTime != 0)
    {
        long time = System.currentTimeMillis();
        long diff = time-lastTime;
        millisElapsed += diff;
        lastTime = time;
    }
}
Now, in the 'start' method, I do not understand why 'lastTime' is set to zero there. I would think that setting it to the current time would be what is wanted. Change line 13 in the TimerActor class to this:
1
lastTime = System.currentTimeMillis();
Finally, there are several problems and curiosities with the World1 class code. First, 'timer' on line 55 is being treated as an 'int' type variable which is nowhere declared and initialized. In fact there is no current valid variable with that name of any type. The 'TimerActor timer' variable in the 'populateWorld' method only lasts for the duration that the method executes. The reference is lost when the method complete its execution. Not only that, but 'timer' is an Object reference to a TimerActor object, not an 'int' value; so, comparing it to '30' makes no sense on line 55. To make the reference valid for the entire existence of the World1 world, you would need to move line 23 (where the 'TimerActor timer' variable is declared and initialized) to outside the method. Then, the timer would need to be started; so, you could, at line 23, add the following line:
1
timer.start();
The next problem is getting the value of 'millisElapsed' from the TimerActor object. You can add the following method to the TimerActor class to facilitate this:
1
2
3
4
public long getMillisElapsed()
{
    return millisElapsed;
}
Lastly, to test for 30 seconds on that timer, you can change line 55 of the World1 class to this:
1
if (timer.getMillisElapsed() >= 30000)
ssenese19 ssenese19

2016/6/7

#
Okay, thanks! However, when I made these changes, an error of "cannot find symbol" appeared with the class "timer" as in "timer.start();" Is this because my timer is actually called TimerActor, or is there another problem? @danpost
danpost danpost

2016/6/7

#
ssenese19 wrote...
Okay, thanks! However, when I made these changes, an error of "cannot find symbol" appeared with the class "timer" as in "timer.start();" Is this because my timer is actually called TimerActor, or is there another problem? @danpost
You will have to show the revised code for us to see what you did.
ssenese19 ssenese19

2016/6/7

#
I tried declaring TimerActor outside of the method and that worked, but now the same keeps happening to "diff." Sorry if I'm being difficult! Thanks for the help!
ssenese19 ssenese19

2016/6/7

#
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
import greenfoot.*;
public class TimerActor extends Actor {
    private int millisElapsed = 0;
    private long lastTime = 0;  
     TimerActor timer = new TimerActor();
    public long getMillisElapsed()
{
    return millisElapsed;
}
   public TimerActor() {
       updateImage();
   }
     
   public void start() {
       millisElapsed = 0;
       lastTime = System.currentTimeMillis();
   }
     
   public void gamePaused() {
       lastTime = 0;
    }
     
    public void act() {
{
    if (lastTime != 0)
    {
        long time = System.currentTimeMillis();
        timer.start();
        millisElapsed += diff;
        lastTime = time;
    }
}
    }
        
        public void updateImage() {
        // Calculate minutes & seconds elapsed
       int millis = millisElapsed % 1000;
       int secs = (millisElapsed / 1000) % 60;
       int mins = millisElapsed / 60000;
       // Convert these into text
       String millisText = String.format("%03d", millis);
       String secsText = String.format("%02d", secs);
       String minsText = "" + mins;  
       String text = minsText + ":" + secsText + "." + millisText;
       // Update the image
      GreenfootImage img = new GreenfootImage(text, 25, null, null);
      img.setColor(java.awt.Color.white);
      setImage(img);
        
    }
}
This is my world method
ssenese19 ssenese19

2016/6/7

#
Sorry, that is my Timer code
danpost danpost

2016/6/7

#
You apparently placed the code on line 28 at the wrong location in you project. Line 28 should be line 6 of my last code post (that will fix the "diff" problem). The starting of the timer ('timer.start();') should be in your World1 class at line 23.
ssenese19 ssenese19

2016/6/7

#
Everything compiles but when I play my game, the terminal window comes up. It says java.lang.StackOverflowError at greenfoot.Actor.getClassImage(Actor.java:646) at greenfoot.Actor.<init>(Actor.java:124) at TimerActor.<init>(TimerActor.java:12) at TimerActor.<init>(TimerActor.java:5)...
ssenese19 ssenese19

2016/6/7

#
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
startButton play = new startButton();
     TimerActor timer = new TimerActor();
    /**
     * Constructor for objects of class World1.
     *
     */
    public World1()
    {   
 
         
        super(800, 600, 1);
        populateWorld();
         
    }
         
    public void populateWorld()
        {
        addObject (new Waldo(), 30, 105);
        addObject (new Whitebeard(), 320, 225);
        addObject (new Woof(), 600, 90);
        addObject (new Odlaw(),160, 300);
        addObject (new Wenda(), 615, 275);
        addObject(timer,200,550);
        timer.start();
        addObject(play,300,550);
         
         
         
        for (int i = 0; i < 100; i++) {
            addObject (new Ladybug(), (Greenfoot.getRandomNumber(801)), (Greenfoot.getRandomNumber(401)));
        }
        for (int i = 0; i < 100; i++) {
            addObject (new Sheep(), (Greenfoot.getRandomNumber(801)), (Greenfoot.getRandomNumber(401)));
        }
        for (int i = 0; i < 100; i++) {
            addObject (new LightHouse(), (Greenfoot.getRandomNumber(801)), (Greenfoot.getRandomNumber(401)));
    }
     for (int i = 0; i < 100; i++) {
            addObject (new moreLightHouse(), (Greenfoot.getRandomNumber(801)), (Greenfoot.getRandomNumber(401)));
    }
    
}
    public void act()
    {
        start();
         
    }
    public void start() {
     
    if(Greenfoot.mouseClicked(play)) {
        removeObject(play);
        Greenfoot.setWorld(new World2());
        timer.start();
    }
    if (timer.getMillisElapsed() >= 30000){
    }
}
}
Here is my world
ssenese19 ssenese19

2016/6/7

#
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
import greenfoot.*;
public class TimerActor extends Actor {
    private int millisElapsed = 0;
    private long lastTime = 0;  
     TimerActor timer = new TimerActor();
       
       
    public long getMillisElapsed()
{
    return millisElapsed;
}
   public TimerActor() {
       updateImage();
   }
     
   public void start() {
       millisElapsed = 0;
       lastTime = System.currentTimeMillis();
   }
     
   public void gamePaused() {
       lastTime = 0;
    }
     
    public void act() {
{
    if (lastTime != 0)
    {
        long time = System.currentTimeMillis();
        long diff = time-lastTime;
        timer.start();
        millisElapsed += diff;
        lastTime = time;
    }
}
    }
        
        public void updateImage() {
        // Calculate minutes & seconds elapsed
       int millis = millisElapsed % 1000;
       int secs = (millisElapsed / 1000) % 60;
       int mins = millisElapsed / 60000;
       // Convert these into text
       String millisText = String.format("%03d", millis);
       String secsText = String.format("%02d", secs);
       String minsText = "" + mins;  
       String text = minsText + ":" + secsText + "." + millisText;
       // Update the image
      GreenfootImage img = new GreenfootImage(text, 25, null, null);
      img.setColor(java.awt.Color.white);
      setImage(img);
        
    }
}
Here is my timer actor
danpost danpost

2016/6/7

#
Please remove line 31 from the TimerActor class. The stack overflow is something that just happened to occur during the getting of the TimerActor image. It is not the actual cause of overflowing the stack. It is probably due to the addition of the 400 objects into your world (see lines 29 through 40 of your World1 class). If any of these are not needed (which I believe might be the case, since you are placing them overtop of each other) to not add them.
You need to login to post a reply.