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

2014/4/1

Help with order of commands including while loop

wybrasr wybrasr

2014/4/1

#
Hello all, I am helping a student with a final project that is a matching game she has been making. She has decided to make a matching game that includes images and sounds to help some of her peers in a music theory class match up composers to the compositions that they created. The issue that she is running into is that the image on the cards connected to the mp3s of the compositions will not change until after the music has played even though the command to change the image for the card is before the while statement in the code. Below is an example of the code:
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
if (Greenfoot.mouseClicked(this) &&isClicked == false && cardOneValue == 0)
            {
                if(matchingValue.contains(".png"))
                {
                    setImage(matchingValue);
                }
                 if(matchingValue.contains(".mp3"))
                {
                    setImage(backCard);
                    GreenfootSound sound = new GreenfootSound(matchingValue);
                    sound.play();
                    while (sound.isPlaying())
                    {
                        isSoundPlaying = true;
                    }
                }
                isClicked = true;
                clickNumber = clickNumber + 1;
                cardOneValue = variableValue;
            }
 
if (Greenfoot.mouseClicked(this) && isClicked == false && cardOneValue != 0 && isSoundPlaying == false)
            {
                   if(matchingValue.contains(".png"))
                {
                    setImage(matchingValue);
                }
                 if(matchingValue.contains(".mp3"))
                {
                    setImage(backCard);
                    flip = true;
                    if(flip == true)
                    {
                        GreenfootSound sound = new GreenfootSound(matchingValue);
                        sound.play();
                        while(sound.isPlaying())
                        {
                            isSoundPlaying = true;
                        }
                    }
                }
                isClicked = true;
                clickNumber = clickNumber + 1;
                cardTwoValue = variableValue;
            }
She decided to use a while statement to ensure that only one music card could be clicked on at a time and that the user would not be able to select a different card before the selection from the composition was finished playing. The first part of the question is why would the loop execute before the image for the card is changed? The second part of the question, and I am sure it is a simple oversight on my part, is why would the image for the card eventually change when the music has stopped playing? The commands are not being executed in the order explicitly stated in the program, but all commands are being run through and successfully completing, just not as expected. Any help would be appreciated. Cheers! Sean
danpost danpost

2014/4/1

#
What is holding it up is the following code, which is in the given code multiple times:
1
2
3
4
while(sound.isPlaying())
{
    isSoundPlaying = true;
}
Just remove these 'while' block and the 'isSoundPlaying' field. If you need to see if the sound is playing, then just use 'sound.isPlaying()'. There is an abundance of fields in the class that are not really needed. Actually, you only need one -- a static Card field. Set it to null to start (no cards chosen yet). If a card is clicked and the value is null, it is the first card -- set the field to that card. If a card is clicked and the value is a card (and not the same card), it is the second card -- compare and finalize the matching (remove if matched or flip back over if not). Then reset the field back to null for another try.
danpost danpost

2014/4/1

#
Just add before both 'while' statements the following line:
1
Greenfoot.delay(1);
That should do what you want.
wybrasr wybrasr

2014/4/3

#
Thanks danpost. You are correct that she could simplify the code and that is something she is working on. Does the while statement in this case take precedence over the rest of the commands in her if statement though? The while command seems to execute before the card flip even though the flip is in the code first. That is what I was confused about. Do all commands in the if statement have to wait until the while statement is finished to execute? Thanks for your help. I used to be an English teacher and am fairly new to coding myself. :-)
danpost danpost

2014/4/3

#
Actually, it is more about the act cycle and display frames. Usually, no changes in the display are made until one (or more) complete act cycles have been executed (lag due to various programming techniques and extensive processes can mess with this). The system is executing the act cycle and not refreshing the display. Adding the 'delay' gives the system a chance to refresh the display. I believe that 'getWorld().repaint()' may be the proper call, however. Normally, all visual changes in an 'act' method are shown after the 'act' method has completed. You can move an actor back and forth from one place to another during the execution an 'act' method, and all you will see is where it ends up. As an example -- code to have an actor orbit around a point could be this:
1
2
3
setLocation(circleCenterX, circleCenterY);
turn(1);
move(100);
The first and last statements both cause the actor to be relocated; however, all you will see is that the actor has moved 1 degree around its orbital path. Or, try this:
1
2
3
4
5
6
7
8
9
public void act()
{
    for (int n=0; n<100; n++)
    {
        move(5);
        long start = System.currentTimeMillis();
        while (start+100 > System.currentTimeMillis()) continue;
    }
}
Manually perform the act method on an actor and you will have to wait one second before the actor all of sudden appear 500 cells to the right of where it started (or at the right edge of the screen, if a bounded world prevented further progress). The code appears to have the actor move 5 pixels every tenth of a second; but, that is not what will happen (visually). All in all, the 'while' statement is just like any other statement -- when the program pointer get to that statement, it is executed. The only difference, is that the 'while' statement is one of the looping commands and can take many more ticks to execute than a non-looping command (I am not talking methods here; I am talking basic java keyword commands). When checking for a state to change in a 'while' loop (like for the sound to stop), it will executed until the sound stops (a long time in computer terms). It will be virtually 'stuck' in this act method and not other object will act in the duration I hope this helped.
You need to login to post a reply.