""" This piano program lets you click any key and hear the correct note! It also plays Jingle Bells automatically! Check out the comments to see how this piano works. Also, edit lines 231 and 233 to automatically play any song you want! """ ### Create all the click events for each piano key - ### twelve in total! We won't assign them until we create ### the actual keys on the stage (see lines 131, 138) ### Each event does 2 things: ### 1) Update the sheet music to show the correct notation ### 2) Play the correct note def play_c(): sharp_or_flat.hide() note.go_to(0, keys.get("C")[1]) stage.play_sound('piano_c4') def play_db(): global sharp if sharp: sharp_or_flat.go_to(-20, keys.get("C#")[1]) note.go_to(0, keys.get("C#")[1]) else: sharp_or_flat.go_to(-20, keys.get("D")[1]) note.go_to(0, keys.get("D")[1]) sharp_or_flat.show() stage.play_sound('piano_db4') def play_d(): sharp_or_flat.hide() note.go_to(0, keys.get("D")[1]) stage.play_sound('piano_d4') def play_eb(): global sharp if sharp: sharp_or_flat.go_to(-20, keys.get("D#")[1]) note.go_to(0, keys.get("D#")[1]) else: sharp_or_flat.go_to(-20, keys.get("E")[1]) note.go_to(0, keys.get("E")[1]) sharp_or_flat.show() sharp_or_flat.show() stage.play_sound('piano_eb4') def play_e(): sharp_or_flat.hide() note.go_to(0, keys.get("E")[1]) stage.play_sound('piano_e4') def play_f(): sharp_or_flat.hide() note.go_to(0, keys.get("F")[1]) stage.play_sound('piano_f4') def play_gb(): global sharp if sharp: sharp_or_flat.go_to(-20, keys.get("F#")[1]) note.go_to(0, keys.get("F#")[1]) else: sharp_or_flat.go_to(-20, keys.get("G")[1]) note.go_to(0, keys.get("G")[1]) sharp_or_flat.show() sharp_or_flat.show() stage.play_sound('piano_gb4') def play_g(): sharp_or_flat.hide() note.go_to(0, keys.get("G")[1]) stage.play_sound('piano_g4') def play_ab(): global sharp if sharp: sharp_or_flat.go_to(-20, keys.get("G#")[1]) note.go_to(0, keys.get("G#")[1]) else: sharp_or_flat.go_to(-20, keys.get("A")[1]) note.go_to(0, keys.get("A")[1]) sharp_or_flat.show() sharp_or_flat.show() stage.play_sound('piano_ab4') def play_a(): sharp_or_flat.hide() note.go_to(0, keys.get("A")[1]) stage.play_sound('piano_a4') def play_bb(): if sharp: sharp_or_flat.go_to(-20, keys.get("A#")[1]) note.go_to(0, keys.get("A#")[1]) else: sharp_or_flat.go_to(-20, keys.get("B")[1]) note.go_to(0, keys.get("B")[1]) sharp_or_flat.show() sharp_or_flat.show() stage.play_sound('piano_bb4') def play_b(): sharp_or_flat.hide() note.go_to(0, keys.get("B")[1]) stage.play_sound('piano_b4') ### Set up the variables that will be used to create the 12 piano keys white_x = -210 black_x = -175 width = 70 height = 170 y = 150 # This dictionary stores the string for the piano key label, # and the key event and the y-coordinate for the note keys = {"C": [play_c, -90], "D": [play_d, -80], "E": [play_e, -70], "F": [play_f, -60], "G": [play_g, -50], "A": [play_a, -40], "B": [play_b, -30], "C#": [play_db, -90], "D#": [play_eb, -80], "F#": [play_gb, -60], "G#": [play_ab, -50], "A#": [play_bb, -40] } # We loop through the dictionary to create the piano keys, # label them with the correct note, and assign the click event for label, values in keys.items(): # First we create seven white keys white_key = codesters.Rectangle(white_x, y, width, height, 'white', 'black') white_key.event_click(values[0]) key_label = codesters.Text(label, white_x, y-(height/2)+20) white_x += width # If the dictionary key contains a '#', # we need to create a black key! if '#' in label: black_key = codesters.Rectangle(black_x, y+35, width-20, height-70, 'black') black_key.event_click(values[0]) key_label = codesters.Text(label, black_x, y+10, "white") black_x += width if black_x == -35: black_x = 35 # No matter which key we created, add the key label to the list values.append(key_label) def labels_off(sprite): """ This function hides the text sprites that label each key """ for label, values in keys.items(): values[2].hide() # Since we've hidden the labels, the button should now say # 'Turn Key Labels On', and a new click event should be assigned turn_key_labels_on.set_text("Turn Key Labels On") turn_key_labels_on.set_text_background("silver", "black", .5) turn_key_labels_on.event_click(labels_on) def labels_on(sprite): """ This function shows the text sprites that label each key """ for label, values in keys.items(): values[2].show() # Since we've shown the labels, the button should now say # 'Turn Key Labels Off', and a new click event should be assigned turn_key_labels_on.set_text("Turn Key Labels Off") turn_key_labels_on.set_text_background("silver", "black", 1) turn_key_labels_on.event_click(labels_off) # Create the button that turns the key labels on/off turn_key_labels_on = codesters.Text("Turn Key Labels Off", -225, -225) turn_key_labels_on.set_text_align("left") turn_key_labels_on.set_text_background("silver", "black", 1) turn_key_labels_on.event_click(labels_off) def sharps2flats(sprite): """ This function changes the sharp key labels to flats """ global sharp for label, values in keys.items(): if '#' in label: new_letter = chr(ord(label[0])+1) if new_letter == 'H': new_letter = 'A' values[2].set_text(new_letter+'b') sharp = False sharp_or_flat.set_text(u'♭') flats_to_sharps.set_text("Switch Flats to Sharps") flats_to_sharps.set_text_background("black", "black", .5) flats_to_sharps.event_click(flats2sharps) def flats2sharps(sprite): """ This function changes the flat key labels to sharps """ global sharp for label, values in keys.items(): values[2].set_text(label) sharp_or_flat.set_text(u'♯') sharp = True flats_to_sharps.set_text("Switch Sharps to Flats") flats_to_sharps.set_text_background("black", "black", 1) flats_to_sharps.event_click(sharps2flats) # Create the button that turns sharps to flats and vice versa flats_to_sharps = codesters.Text("Switch Sharps to Flats", 225, -225, "silver") flats_to_sharps.set_text_align("right") flats_to_sharps.set_text_background("black", "black", 1) flats_to_sharps.event_click(sharps2flats) # Create the music staff y = 10 for counter in range(5): #sprite = codesters.Line(x-start, y-start, x-end, y-end, "color") sprite = codesters.Line(-100, y, 100, y, "black") y -= 20 # image from https://upload.wikimedia.org/wikipedia/commons/thumb/f/ff/GClef.svg/800px-GClef.svg.png clef = codesters.Sprite("treble_clef_44a", -70, -38) clef.set_size(0.4) note = codesters.Ellipse(0, -90, 20, 15, "black") sharp = True sharp_or_flat = codesters.Text(u'♯', -20, -50) sharp_or_flat.hide() ### Automatically play a song! ### bouncer = codesters.Circle(-72, 120, 20, "red") ### The string and list need to be the same length! ### The string contains all the notes in the song jingle_bells = "EEEEEEEGCDEFFFFFEEEEEDDEDGEEEEEEEGCDEFFFFFEEEEGGFDC" ### The list contains how long we should pause after playing each note! rhythm = [.3, .3, .5, .3, .3, .5, .3, .4, .3, .3, 1, .3, .3, .3, .3, .3, .3, .4, .3, .3, .5, .3, .3, .5, .3, .4, .3, .3, .5, .3, .3, .5, .3, .4, .4, .4, 1, .3, .3, .3, .3, .3, .3, .4, .3, .3, .5, .3, .3, .5, .3] ### This loop moves the red ball to the correct note, gets the correct ### key functions, and plays the note! counter = 0 for text in jingle_bells: bouncer.hide() jingle_values = keys.get(text) label = jingle_values[2] bouncer.go_to(label.get_x(), label.get_y()+25) pause = rhythm [counter] play = jingle_values[0] bouncer.show() play() stage.wait(pause) counter += 1 bouncer.hide() stage.wait(1) note.set_say_position(0, -25, "absolute") note.say("Your turn!", 2, "black", 30)
  • Run Code
  • Show Console
  • Codesters How To (opens in a new tab)