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

2014/12/15

Problems with Greenfoot.delay()

1
2
olenz olenz

2014/12/15

#
Hi everybody! I have an Actor that is supposed to move around in the world, and I would like to be able to see the movement on the screen. The actor has a method, and inside the method, I'm moving the object several times and call "Greenfoot.delay(1)" in between so that I can see the movement. Often, when I execute the method, I can see the actor moving, as it is intended. Unfortunately, sometimes the method is executed instantaniously, i.e. the single steps are not visible. Still the method runs and gives the correct output, so apparently, Greenfoot.delay() does not always seem to work. Does anyone have an idea, why? Olaf
olenz olenz

2014/12/15

#
Note that usually the speed of the movement is influenced by setting the speed slider, but in the instantanious case has no influence.
Super_Hippo Super_Hippo

2014/12/15

#
You could call 'getWorld().repaint();' to repaint the world. If you can, try not to move several times in one act cycle. Instead, move one step each act cycle, then you don't need to call the 'delay' method.
danpost danpost

2014/12/15

#
FYI, the speed slider only regulates the timing of complete act cycles (where the active world and all actors in it act) -- it tries to have successive act cycle start with a constant time interval between them. The higher the slider is set, the smaller the time interval between act cycles. It does not influence the time one act method runs. Also, be aware that when using 'Greenfoot.delay', no other actor will be acting during the execution of the act method the line is in. In other words, the whole scenario will freeze while this actor is taking several steps in its movement. There are circumstances where this kind of behavior may be preferred; so I am not saying you need to change this -- just wanted you to be aware of this.
olenz olenz

2014/12/15

#
Thanks for the replies! The behaviour is somehow wanted. The code is used for teaching 16 year old pupils. I would prefer if I can let them implement a method that moves an actor in a sequence of steps, instead of having to write an act() cycle that needs to implement a state machine.... Or is there a better way to do that? Can I somehow use Threads such that each call to act() makes the thread advance one step? That would be really the most useful thing...
olenz olenz

2014/12/15

#
Ideally, one would have something like Coroutines, but I guess as they are almost impossible to implement in Java, you won't have them Greenfoot.
Super_Hippo Super_Hippo

2014/12/15

#
If you are trying to teach Java+Greenfoot, I think you shouldn't use the delay method for that. This will limit your pupils being creative with code.
Olaf Lenz wrote...
Can I somehow use Threads such that each call to act() makes the thread advance one step? That would be really the most useful thing...
Well, you could use a counter which you increment by 1 every act and then use a switch in the act method to decide what to do.
danpost danpost

2014/12/15

#
@Olaf, maybe you do not realize this: the act method of the World and Actor classes are called repeatedly by the greenfoot framework when the scenario is running. You only need to code that which needs to be done in a single step within the act method. If you had this:
1
2
3
4
public void act()
{
    move(1);
}
as the act method of a subclass of Actor, the actor will move slowly across the screen one pixel at a time (one pixel per act cycle).
olenz olenz

2014/12/16

#
I have written an extensive reply to this. Unfortunately, it was detected to look like spam... *embarassed* I hope the admins will approve it at some time...
danpost danpost

2014/12/16

#
Olaf Lenz wrote...
I have written an extensive reply to this. Unfortunately, it was detected to look like spam... *embarassed* I hope the admins will approve it at some time...
You probably attempted to make your first post that included an image which, in itself, will be flagged for further scrutiny.
olenz olenz

2014/12/16

#
I do understand the idea of "act()". The trouble with it is that to use it I have to split an action and implement a so-called state machine (http://en.wikipedia.org/wiki/Finite-state_machine). That is actually a generalized version of the "counter" that @Super_Hippo proposes. What would be much nicer and easier to read would be to write the sequence of actions in a method, like:
1
2
3
4
5
6
7
8
9
10
11
12
void walkAroundRocks()
{
    while (! isRockInFront()) {
        step();
    
    turnLeft();
    while (isRockRight()) {
        step();
    }
   step();
   turnRight();
}
In an "ideal" Greenfoot world, each step() would require one "act()" cycle. This would make it significantly easier for the pupils to put their ideas into code. Otherwise they first have to think how to formulate their algorithm to match the current semantics of act(). But I understand that this doesn't seem to be possible easily. I guess one could probably make up a mechanism using threads, however. If I find one, I will post it (or even make it part of Greenfoot, if nobody disagrees).
Super_Hippo Super_Hippo

2014/12/16

#
You could try to change 'while' to 'if' and call the method from the act method.
davmac davmac

2014/12/16

#
Olaf, you might be interested in my 'threadact' scenario. Be aware that, in general, the Greenfoot API is not thread-safe. Also, in Greenfoot 2.4.0 there is a bug whereby the Greenfoot.delay() method does not always work in interactive method calls immediately after a compile (or reset). Perhaps this is what you are seeing.
danpost danpost

2014/12/16

#
I do not know if that is the best way to start your students off. Would not that put them in the wrong frame of mind? I would think that you need to get them to think on the basis of one instance of time. That is, to ask the question 'What exactly do I want the actor to do at any given instance in time?' which would then lead them to coding what you have above as something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void walkAroundRock()
{
    if (! isrockRight()) {
        turnRight();
        step();
    }
    else {
        if (! isRockInFront()) {
            step();
        }
        else {
            turnLeft();
        }
    }
}
olenz olenz

2014/12/17

#
@davmac: Thanks for the hint, I'll have a look! I hadn't seen this yet. @danpost: I would see it exactly the other way round. I find it much more natural if one thinks about an Actor in a sequence of actions that he does, instead of having to remember what state it is in and make a decision base upon that. The above example was incomplete - that was why you could very easily put it into an "act()". The idea was a method that makes a creature walk around a block of rocks, measure the side lengths of the block, and finally return the number of rocks in the block. Let me put the full code here:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public int walkAroundTheBlock() {
    int x = 0;
    int y = 0;
    while (! isRockInFront()) {
        step();
    }
    turnLeft();
    while (isRockRight() {
        step();
    }
    turnRight();
    step();
    while (isRockRight()) {
        step();
        x++;
    }
    turnRight();
    step();
    while (isRockRight()) {
        step();
        y++;
    }
    return x*y;
}
Of course it is possible to implement this in an act(), but it requires to store in what state the actor is (e.g. walkting towards block, walking along the block to get to a corner, measuring x, measuring y). Still I believe it is much more natural to express this in a sequence of steps...
There are more replies on the next page.
1
2