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

2012/9/12

Need help with Greenfoot book exercise

Basman Basman

2012/9/12

#
Hi guys, I'm having a bit of trouble with 5.18. Here's the question:
Using fixed numbers in your code, such as the 140 or 63 in the statement above, is usually not the best solution, since it makes your code vulnerable to breaking when things change. For example, if we replace the key images with nicer images that have a different size, our code would not place them correctly. We can avoid using those numbers directly by calling the getWidth() and getHeight() methods of the key’s image. To do this, first assign the key object to a local variable of type Key when you create it, and then use key.getImage().getWidth() in place of the 63. Do a similar thing with the height. Replacing the 54 requires you to also use the getWidth() method ofthe piano’s image. After doing this,our code will always place the keys nicely,even if their size changes.
Now, my idea in pseudo code was this: getImage from Key object Store that image in new local variable within the method for making keys use getWidth and getHeight on local variable replace magic numbers in the current method with the getWidth and getHeight method However, I can't figure out how to extract the image file from the Key object. Does anyone with the book know what to do? Here's the code for both classes:
public class Key extends Actor
{

    private boolean isDown; 
    private String key;
    private String sound;
        
    /**
     * Create a new key.
     */
    public Key(String keyName, String soundFile)
    {
        key = keyName;
        sound = soundFile;
    }

    /**
     * Do the action for this key.
     */
    public void act()
    {
        keyPress();
    }
    
    public void keyPress()
    {
        if (!isDown && Greenfoot.isKeyDown(key))
        {
            setImage ("white-key-down.png");
            isDown = true;
            play();
        }
        if (isDown && !Greenfoot.isKeyDown(key))
        {
            setImage ("white-key.png");
            isDown = false;
        }
    }
    
    public void play()
    {
        Greenfoot.playSound(sound);
    }
}
public class Piano extends World
{
    /**
     * Make the piano.
     */
    public Piano() 
    {
        super(800, 340, 1);
        makeKeys();
    }
    
     
    public void makeKeys() 
    {  
        for(int i = 0; i<12; i++)
        {
            addObject (new Key ("g", "3a.wav"), i*63 + 54, 140);
        }
    }
}
davmac davmac

2012/9/12

#
It's in the very text that you posted: key.getImage().getWidth() I.e. getImage() retrieves the image.
Basman Basman

2012/9/12

#
Thanks for taking the time to answer me! Here's the current makeKeys method that I have:
      public void makeKeys() 
    {  
        int keyWidth = Key.getImage().getWidth();
        int keyHeight = Key.getImage().getHeigth();
        
        for(int i = 0; i<12; i++)
        {
            addObject (new Key (whiteKeys[i], whiteNotes[i] + ".wav"), i*keyWidth + 54, keyHeigth);
        }
    }
However, the reason I made this post in the first place was that I keep getting this compiling error:
Non-static method getImage() cannot be referenced from a static context.
I'm a beginning student, so please bear with me. A static method means a method that is only used within a class, but isn't used by any other class. But why would it matter if the result of key.getImage().getWidth() is used in a static method? I'm sorry if I'm looking at this from the wrong angle and confusing you, but I hope you (or anyone else!) can help.
danpost danpost

2012/9/12

#
The code you wrote is trying to get an image from a class (not an object). You need to create a Key object first; then get the width and height of the image of that object. Actually, a 'static' field is one that belong to the class; the objects of that class do not each have an instance of that field, but all objects of that class share that same field. Methods that are 'static' usually either work with the 'static' fields or work with all the objects of that class at once. Field and methods that are 'static' can be accessed and used whether there are objects of the type present or not; and ANY class can work with them. You have two options available to get the image width and height. The first is to create a sample Key set to a white key and get its width and height before the for loop. The other is to get the width and height of each key object after creating them, and then add them to the world, all in the 'for' loop.
davmac davmac

2012/9/13

#
As danpost says, you need to call getImage() on a key object, not the Key class; as it happens, you are already creating a key object that you can use for that purpose (line 08 in your posted code): addObject (new Key (whiteKeys, whiteNotes + ".wav"), i*keyWidth + 54, keyHeigth); If you first break this line into two steps (two lines): 1. Create the "new Key(....)" and store it in a variable of type Key 2. add the newly created key to the world ... then it should be trivial to calculate the key width and height just after step 1 above.
Basman Basman

2012/9/14

#
Thanks to your help guys, I have figured it out. What I was doing wrong was trying to get the image size from outside the for loops, while it should have been a local method (inside the loops). I will post it here, as I couldn't find the answer anywhere else on google, so hopefully some other student will find this page and also find this helpful in the future. code removed - see below - davmac.
davmac davmac

2012/9/14

#
I will post it here, as I couldn't find the answer anywhere else on google, so hopefully some other student will find this page and also find this helpful in the future
Please don't do that - the book is used in classes and the exercises are given to students to work out for themselves. It's ok to ask for help but not for solutions! the point is to code it yourself. I've removed your code.
Basman Basman

2012/9/14

#
Sorry, I didn't mean to offend. People finding this thread through google will be frustrated. :-)
davmac davmac

2012/9/15

#
They can still read the help here and write the code for themselves, and learn something in the process :)
You need to login to post a reply.