Download presentation
Presentation is loading. Please wait.
Published bySarah Barber Modified over 6 years ago
1
Chapter 5 – Making Music: An On-Screen Piano (Part 1 – Using Loops)
2
topics: sound concepts: abstraction, loops, arrays, OO structure
Start on a new scenario: a piano that can play with our computer Opening a scenario from the book scenarios: piano-1. Need (the images and the sound files)
3
Creating a Music Simulation:
4
The Piano Scenario: piano1
On the world classes, Right click on the World and add wood.jpg as your background. Then compile.
5
Animating the Key
6
The Piano World Code Click on the Open editor Take a look at the Piano
Specifies the size and resolution of the World Square (800,340, 1)
7
Open editor on the Key actor.
The Key Code Open editor on the Key actor. The Code is only Stubs
8
Creating Multiple Keys
Hold the shift key on the key Actor and bring in a few keys
9
Methods that do nothing
The object of class Key and placing it into the world that we see a simple white key, and it does nothing anything when we run the scenario import greenfoot.*; // (World, Actor, GreenfootImage, and Greenfoot) public class Key extends Actor { /* * Create a new key. */ public Key() } * Do the action for this key. public void act()
10
Chapter05 under book-scenarios-piano1-there are images folder
11
Animate the piano key white-key.png and white-key-down.png
Animate the piano key: When we press a piano key on the keyboard, change color The scenario as it is already contains two image files white-key.png and white-key-down.png (which it shows two states) black-key.png and blackkey-down.png (which we shall use later for the black keys.)
12
Act method: changing image
Note: Both “g” and “white-key-down.png” are parameters of type String. A String is simply a sequence of chars. The sequence can be of any length, including 1.
13
Animating the Keys
14
Improving the Code private boolean isDown;
We add a boolean field to our class to remember whether the key is currently down or not. We call this field isDown, and its declaration looks as follows: private boolean isDown; We will store true in this field while the piano key is down, and false while it isn’t.
15
Handling Repetition Issues
There is a repetition problem because the act() method is called repeatedly while we hold down the "g" key. To fix this problem we need a variable to tell us if we already reacted to the key being down, so we do not play the note more than once: private boolean isDown = false; Once the input has been handled, we set isDown is true. If the key is released we set isDown to false, so the next time the key is pressed we can react again. How can we now use this variable?
16
Comparison Operators < less than <= less than or equal == equal
ex: if (a < b) { <= less than or equal ex: if (a <= b) { == equal ex: if (a == b) { != not equal ex: if (a != b) { >= greater than or equal ex: if (a >= b) { > greater than ex: if (a > b) { (all are used with numerical values)
17
Logical Operators && AND || OR ! NOT
Ex: if (a < b && b < c) { Note: both a < b and b < c must be true || OR Ex: if (a < b || b < c) { Note: either a < b or b < c must be true ! NOT Ex: if ( ! a ) { Note: if a is false, then !a is true, if a is true, then !a is false (all are used with boolean values)
18
Logical Operators (Truth Table)
The logical NOT is a unary operator, meaning it is applied to one boolean value, not two. This changes its Truth Table. Inputs Results NOT a !a true false
19
Add Boolean field
20
This isDown boolean logic:
public void act () { if ( !isDown && Greenfoot.isKeyDown("g")) setImage("white-key-down.png"); play(); isDown = true; } if ( isDown && !Greenfoot.isKeyDown("g")) setImage("white-key.png"); isDown = false;
21
Logical Operations AND and NOT
if (isDown is set to false AND “g” is down ) if ( !isDown && Greenfoot.isKeyDown("g")) { setImage("white-key-down.png"); play(); isDown = true; } if ( isDown && !Greenfoot.isKeyDown("g")) setImage("white-key.png"); isDown = false; if ( isDown is set to true AND “g” is not down)
22
Animation + Sound Now the Key is animated and plays a note.
But there is a Repetition Problem
23
Producing the Sound The sounds folder has a collection of sound files each of which contains the sounds for a single piano key with an octave number followed by the note name for the file’s name.
24
Producing the Sound /** * Play the note of this key. */
public void play() { Greenfoot.playSound("3a.wav"); }
25
Producing the Sound Right Click on the Object Click play
26
Producing the Sound The Keys all play the same note!
27
Abstraction: Coding Classes, not Objects
The current iteration of our Key class ultimately only implements ONE specific Key object (a Key that plays the “3a.wav” file and reacts to the “g” key). What we actually want is a “generic” Key class that can be used to implement any Key object. Abstraction (for our purposes): Solving an entire range of problems, instead of one specific problem. This requires the use of Constructors with Parameters
28
Using Parameters in Constructors
public class Key extends Actor { private boolean isDown = false; private String key; private String sound; /** * Create a new key linked to a given keyboard key, and * with a given sound. */ public Key(String keyName, String soundFile) key = keyName; sound = soundFile; } // methods omitted. Two new Instance Variables of type String A Constructor that receives and handles Parameters
29
The new act() method Change the “g” to key
Change the “3a.wav” to sound
30
The new play() method /** * Play the note of this key. */
public void play() { Greenfoot.playSound(sound); }
31
The new act() method public void act() {
if ( !isDown && Greenfoot.isKeyDown(key)) setImage("white-key-down.png"); isDown = true; } if ( isDown && !Greenfoot.isKeyDown(key)) setImage("white-key.png"); isDown = false;
32
Creating two different Keys: the sounds Folder
We Will Use Sound Files 3a.wav and 3b.wav
33
Abstraction: Creating multiple keys
34
Creating two different Keys
Right Click Key Select new Key Add the First Key
35
Creating two different Keys
Add the Second Key
36
Creating two different Keys
We now Have a Piano with Two Keys
37
Building the piano: Using addObject()
Reminder: the expression new Key( "a", "3a.wav" ) creates a new Key object with a specific key and a sound file. We can use this for the addObject() method: addObject( new Key( "a", "3a.wav" ), 300, 180 );
38
Using the Piano Constructor
import greenfoot.*; // (World, Actor, GreenfootImage, and Greenfoot) /** * A piano that can be played with the computer keyboard. * M. Kolling 1.0 */ public class Piano extends World { * Make the piano. public Piano() super(800, 340, 1); addObject( new Key( "a", "3a.wav" ), 300, 180 ); } Call addObject to Create a Key
39
Using the Piano Constructor
The image is 280*63 pixels. The (x, y) parameters given to the addObject() method refer to the MIDDLE of the image. If we want the image to be align with the upper border, we have to place it at (x, 140)
40
Placing keys next to each other
import greenfoot.*; // (World, Actor, GreenfootImage, and Greenfoot) public class Piano extends World { /** * Make the piano. */ public Piano() super(800, 340, 1); addObject( new Key( "g", "3g.wav" ), 300, 140 ); addObject( new Key( "f", "3f.wav" ), 237, 140 ); }
41
A Method for Making the keys
public class Piano extends World { /** * Make the piano. */ public Piano() super(800, 340, 1); makeKeys(); } * Create the Piano Keys. public void makeKeys() addObject (new Key ("g", "3g.wav"), 300, 140); addObject (new Key ("f", "3f.wav"), 237, 140);
42
Handling Repetition: The while-loop
while ( condition ) { statement1; statement2; statement3; } The while-loop in words: Execute statement1, statement2 and statement3 as long as the condition evaluates to true.
43
A while-loop using a counter
Counter variable is initialized int i = 0; while ( i < 5) { statement1; statement2; i = i + 1; } Counter variables is used as a condition Counter variable is incremented How often are the statements inside the loop executed? Or: How often does the loop iterate?
44
Another while-loop int a = 20; while ( a => 10) { statement1;
a = a - 1; } How often does the loop iterate?
45
Another while-loop int a = 3; while ( a < 31) { statement1;
a = a; } How often does the loop iterate?
46
Another while-loop int i = 0; while ( i > 30 && i < 100 ) {
statement1; statement2; i = i + 1; } How often does the loop iterate?
47
Handling Repetition: The for-loop
Counter variable is incremented (happens AFTER an iteration) Counter variable is initialized Counter variables is used as a condition for ( int i = 0; i < 100; i++/i = i + 1) { statement1; statement2; }
48
Comparison: for- and while-loops
Counter variable is initialized int i = 0; while ( i < 100 ) { statement1; statement2; i = i + 1; } for ( int i = 0; i < 100; i++) { statement1; statement2; }
49
Counter variables is used as a condition
Comparison: for- and while-loops Counter variables is used as a condition int i = 0; while ( i < 100 ) { statement1; statement2 i = i + 1; } for ( int i = 0; i < 100; i++) { statement1; statement2; }
50
Comparison: for- and while-loops
Counter variable is incremented int i = 0; while ( i < 100 ) { statement1; statement2; i = i + 1; } for ( int i = 0; i < 100; i++) { statement1; statement2; }
51
Creating Multiple keys using a while-loop
/** * Create the Piano Keys */ public void makeKeys() { int i = 0; while ( i < 12 ) addObject (new Key ("g", "3g.wav"), 300, 140); i = i + 1; } Note how the Counter variable is created INSIDE the method. It is a “local” variable.
52
Creating Multiple keys using a for-loop
/** * Create the Piano Keys */ public void makeKeys() { for (int i = 0; i<12; i++) { addObject (new Key ("g", "3g.wav"), 300, 140); } Object to be placed y-coord x-coord
53
Creating Multiple keys using a while-loop
It Appears That There is Only One Key
54
Creating Multiple keys using a while-loop
But the keys are actually stacked. They are all crated in the same position!
55
Creating Multiple keys using a for-loop
The x-position has to increase by 63 with every iteration. This is due to the image being 63 pixels wide. /** * Create the Piano Keys */ public void makeKeys() { for (int i = 0; i<12; i++) { addObject (new Key ("g", "3g.wav"), i*63, 140); }
56
Creating Multiple keys using a for-loop
These keys are not centered
57
Creating Multiple keys using a for-loop
(0, 0) Y X (800, 0) Each Key is 280 * 63 pixels. The world is 800 pixels wide. When placing 12 keys, we have 44 pixels of “wiggle room” (22 to each side). This means that, for ideal placement, the first key should be placed at ( , 140) (0, 340)
58
Creating Multiple keys using a for-loop(with offset)
for (int i = 0; i<12; i++) { addObject (new Key ("g", "3g.wav"), i* , 140); } This value will move every key slightly to the right The for-loop Will Execute 12 Times. The y-position will remain fixed. The x-position are dependent on the value of i (0, 1, . . ., 11) plus an offset value of 54.
59
Creating Multiple keys using a for-loop(with offset)
/** * Create the Piano Keys */ public void makeKeys() { for (int i = 0; i<12; i++) { addObject (new Key ("g", "3g.wav"), i* , 140); }
60
Creating Multiple keys using a for-loop(with offset)
61
Advanced: Generic Centering with with calculated (x, y)-coord and offSet
public void makeKeys() { int keyWidth, keyHeight, worldWidth; int offSet; Key key = new Key(" ", " "); keyWidth = key.getImage().getWidth(); keyHeight = key.getImage().getHeight(); worldWidth = this.getWidth(); offSet = (worldWidth - keyWidth*12) / 2 + keyWidth/2; for (int i=0; i<12; i++) { addObject (new Key ("g", "3g.wav"), keyWidth*i + offSet, keyHeight / 2); }
62
Advanced: Generic Centering with with calculated (x, y)-coord and offSet
63
Arrays
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.