In this exercise you will build a piano with 69 notes - that's more than 5 octaves! Many Scratchers would begin by making a sprite for each note and then adding scripts to each sprite, generating a project with at least 69 sprites and at least 69 scripts - there must be a better way! With a bit of clever maths and a few brain cells it is possible to make the piano with no sprites at all - the project below just contains a background image showing the piano keyboard and one short script.
However piano keyboards do have a layout that's almost as crazy and weird as the QWERTY keyboard layout. The keys on a piano have different sizes and shapes and even the steps between the white keys are not constant (sometimes consecutive white keys represent consecutive notes and sometimes they represent notes that are two notes apart). So don't be surprised if the maths that converts each mouse-click into a specific note is hard to follow! Here's an image that you can use as a background in your project. Each white key is 12 pixels wide at the bottom.
Now take a deep breath and read these hints about the maths involved in converting mouse-click locations to the corresponding notes...
The mouse x coordinates are first converted to coordinates relative to the left of the stage (left edge = 0). The x coordinates are then converted to 'key_quarts' - each white key is four key_quarts wide at the bottom. The octave number of the clicked key is calculated - the leftmost octave is octave 0. The extreme left key will be note 24 and 12 notes are added for each additional octave. Then the number of additional notesneeded is calculated by calculating the position of the key within the octave and then looking up in a list the corresponding number of notes to add. There are two lists, one for the top of the keys and one for the bottom. The position of the note within the octave is found by finding the 'modulus' of the note number divided by 12 (the number of notes in an octave). The modulus is just the remainder when one number is divided by another. For example 14 mod 5 = 4 and 8 mod 3 = 2
Once the position of the note within the octave is known the number of 'notes to add' is obtained from a list. The image to the right shows the beginning of my list - you will have to complete it for yourself. The complete list will consist of 28 items since each octave contains 28 'key_quarts' (note that each octave contains 7 white notes each 4 'key_quarts' wide at the bottom).
As you can see, I've hidden part of my script - it's the part that does the bottom parts of the keys. I'll leave it to you to figure out the code - it won't be easy! But the bottoms of the keys are probably easier than the tops since the bottoms of the keys are all the same width. You could start by calculating a 'key number' by dividing the key_quarts number by 4 (there will often be a remainder - is this a problem?). But you will still need to convert the key number to the corresponding note
To understand what the variables and lists do in this or any other project it is a good idea to turn on all their monitors so that their values are visible on the stage. To be clear about the variables and lists used in this project, here they are with their meanings:
- ' instrument ' holds the number of the instrument which can have any value between 1 and 128. The spaces in the name of the variable force the monitor on the stage to be wider than it would otherwise be.
- 'Beats' is the number of beats that each note will play for. The slider allows this number to be adjusted between 0 and 1 (in steps of 0.1 since the upper limit was set to be 1.0 and not 1).
- 'key_quarts' is the position of the mouse click relative to the left of the stage in units of 3 pixels which is one quarter of the full width of a white key. For example, clicking 22 pixels from the left would give key_quarts a value of 5 since 22/4 = 5 (ignore the remainder). Doing a division and ignoring the remainder is called 'integer division' or 'div', by the way, so I could have written 22 div 4 = 5.
- 'octaves' contains the number of the octave that has been clicked. in my program each octave starts with the note 'C' which is the note that you see at the extreme left. The leftmost octave in my image is called octave zero.
- 'note' is first set to 24 plus 12 times the octave number and then adjusted to be the correct note ready to be played by the 'play note' block.
- 'mod' is the position of the clicked key_quart in its octave. So if I click on the fifth key_quart in the third octave then mod will contain a 4. (Since Mod gives values beginning with a zero, the fifth value will be a 4, as in 0,1,2,3,4...)
- 'white_key' is the number of the white key that has been clicked, starting at key 0 on the left. This variable is used only for the bottom parts of the keys, which are all white.
- 'x' is the horizontal position of the mouse-click, measured in pixels from the left edge.
- 'y' is the vertical position of the mouse-click (the same as mouse y)
The program also uses 2 lists:
- 'add_notes' is a list of numbers that indicate how many notes have to be added due to the position of the mouse-click within its octave
- 'add_notes_white' is similar but much shorter since the bottom of the white notes are all the same width so there are only 7 'positions' to look up in the list corresponding to the seven white notes in each octave.
One last thing. You might be wondering what is the purpose of the line 'set y to mouse y'. Why not just use 'mouse y' all through the script? Why copy it into a variable? The answer is that I have the impression that if mouse x or mouse y is used in several places in a script then it can conceivably change while the script is running, with unpredictable results. By copying it into a variable I make sure the number is fixed while the script runs. Ironic, isn't it?
Other musical Scratch projects
If you are a music-loving Scratcher then check out also the Christmas project at www.learnscratch.org. It's unit 6, lesson 29.
Check out also the 7 Ocean Music Box project.
If you're a real musician then you might be able to make sense of this.