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

2017/4/29

Global Variable Issues

ConfusedCairns ConfusedCairns

2017/4/29

#
I'm creating a game where the user has to play the piano and questions are displayed asking for specific keys to be pressed. So far, I have a subclass of World called Piano which contains the questions and key bindings, and also have of Actor called Key which plays notes when the corresponding keys on the keyboard are pressed. How would I be able to make it so when a key is pressed, It registers it so that once all the keys have been pressed it asks the next question?.
import greenfoot.*;  // (World, Actor, GreenfootImage, and Greenfoot)

public class Piano extends World
{
    private String[] whiteKeys =
        { "A", "S", "D", "F", "G", "H", "J", "K", "L", ";", "'", "#" };
    private  String[] whiteNotes =
        { "3c", "3d", "3e", "3f", "3g", "3a", "3b", "4c", "4d", "4e", "4f", "4g" };
        
    private String[] blackKeys =
        { "W", "E", "", "T", "Y", "U", "", "O", "P", "", "]" }; 
    private String[] blackNotes =
        { "3c#", "3d#", "", "3f#", "3g#", "3a#", "", "4c#", "4d#", "", "4f#", "",}; 

    /**
     * Make the piano. This means mostly, apart from defining the size,
     * making the keys and placing them into the world.
     */
    public Piano() 
    {
        super(800, 450, 1);
        makeKeys();
        showMessage();
    }
    
    /**
     * Create the piano keys (white and black) and place them in the world.
     */
    private void makeKeys() 
    {
        // make the white keys
        for(int i = 0; i < whiteKeys.length; i++) {
            Key key = new Key(whiteKeys[i], whiteNotes[i]+".wav", "Red-key.png", "Red-key-down.png");
            addObject(key, 54 + (i*63), 140);
        }

        // make the black keys
        for(int i = 0; i < whiteKeys.length-1; i++) {
            if( ! blackKeys[i].equals("") ) {
                Key key = new Key(blackKeys[i], blackNotes[i]+".wav", "black-key.png", "black-key-down.png");
                addObject(key, 85 + (i*63), 86);
            }
        }
    }

    public void showMessage()
    {
        GreenfootImage bg = getBackground();
        bg.setColor(Color.WHITE);
        bg.drawString("Play notes", 25, 320);
    }

}
import greenfoot.*;  // (World, Actor, GreenfootImage, and Greenfoot)

public class Key extends Actor
{
    private boolean isDown;
    private String key;
    private String sound;
    private String upImage;
    private String downImage;
    
    /**
     * Create a new key linked to a given keyboard key, and
     * with a given sound.
     */
    public Key(String keyName, String soundFile, String img1, String img2)
    {
        sound = soundFile;
        key = keyName;
        upImage = img1;
        downImage = img2;
        setImage(upImage);
        isDown = false;  
    }

    /**
     * Do the action for this key.
     */
    public void act()
    {
        if (!isDown && Greenfoot.isKeyDown(key)) {
            play();
            setImage(downImage);
            isDown = true;
        }
        if (isDown && !Greenfoot.isKeyDown(key)) {
            setImage(upImage);
            isDown = false;
        }
    }
    
    /**
     * Play the note of this key.
     */
    public void play()
    {
        Greenfoot.playSound(sound);
    }
}
danpost danpost

2017/4/29

#
You could add a static String field to your world class and have the keys add their String value to that field if not already contained within its string. Then have the world act method continuously check the length of the string. If ever the length is 20 (I think that is the sum of the number of white and black keys), then the question needs to be asked. Make sure your Piano world constructor sets the field to an empty string.
ConfusedCairns ConfusedCairns

2017/5/6

#
Thankyou for this guidance. Would it be possible for you to provide example code as I am still struggling?.
danpost danpost

2017/5/6

#
ConfusedCairns wrote...
Thankyou for this guidance. Would it be possible for you to provide example code as I am still struggling?.
Hints: use the 'contains' method for checking for a key in the string:
public void addPressedKey(String key)
{
    if (!keysPressed.contains(key))
    {
        keysPressed += key;
        if (keysPressed.length() == 20)
        {
            keysPressed = "";
            // etc (ask question)
The method should be in your world class and should be called a Key object when played using:
((Piano)getWorld()).addPressedKey(key);
ConfusedCairns ConfusedCairns

2017/5/12

#
The code is accepted but I am still stuck regarding where the ((Piano)getWorld()).addPressedKey(key); is placed. I am thinking this line is vital in order for the rest of the code to work.
danpost danpost

2017/5/12

#
ConfusedCairns wrote...
The code is accepted but I am still stuck regarding where the ((Piano)getWorld()).addPressedKey(key); is placed. I am thinking this line is vital in order for the rest of the code to work.
A Key object needs to call the method when that key is played.
You need to login to post a reply.