Code Sketch
yadnesh shahare made ai
// --- FULL REAL MOUSE-CLICK PIANO IN KOJO ---
clear()
setBackground(Color(12, 16, 26))
// ????? ?????????? ? ???????? (Octaves) ???? ?? ???????? ??????? (Notes & Names)
val whiteNotes = Array(
60, 62, 64, 65, 67, 69, 71, // Octave 1: C4 - B4
72, 74, 76, 77, 79, 81, 83, 84, 86 // Octave 2: C5 - D6
)
val noteNames = Array(
"C4", "D4", "E4", "F4", "G4", "A4", "B4",
"C5", "D5", "E5", "F5", "G5", "A5", "B5", "C6", "D6"
)
// ?????? ???????????? ???? (?? ?????? ??????? - Black Sharp Keys)
val blackNoteIndices = Array(0, 1, 3, 4, 5, 7, 8, 10, 11, 12)
val blackNotes = Array(
61, 63, 66, 68, 70, // C#4, D#4, F#4, G#4, A#4
73, 75, 78, 80, 82 // C#5, D#5, F#5, G#5, A#5
)
var activeWhite = -1
var activeBlack = -1
val startX = -280
val keyWidth = 35
val keyHeight = 220
val blackWidth = 22
val blackHeight = 130
def drawRealPiano(): Unit = {
erasePictures()
// 1. ???????? ????? ????? ???? (Wooden Piano Frame)
val frame = Picture.rectangle(590, 270)
frame.setFillColor(Color(30, 20, 15))
frame.setPenColor(Color(255, 215, 0))
frame.setPenThickness(3)
frame.setPosition(-295, -135)
draw(frame)
// 2. ???? ???????? ??????? (White Piano Keys)
for (i <- 0 until whiteNotes.length) {
val xPos = startX + (i * keyWidth)
val key = Picture.rectangle(keyWidth - 3, keyHeight)
if (activeWhite == i) {
key.setFillColor(Color(255, 215, 0)) // ?????? ????? ?? ????? ???
} else {
key.setFillColor(Color(248, 248, 252))
}
key.setPenColor(Color(70, 70, 70))
key.setPosition(xPos.toDouble, -120)
draw(key)
// ??????? ??? (C4, D4, E4...)
val label = Picture.text(noteNames(i), 8)
label.setPenColor(Color(80, 80, 80))
label.setPosition(xPos + 6, -110)
draw(label)
}
// 3. ???? ?????? ??????? (Black Piano Keys)
for (b <- 0 until blackNoteIndices.length) {
val idx = blackNoteIndices(b)
val bxPos = startX + (idx * keyWidth) + (keyWidth - (blackWidth / 2))
val bKey = Picture.rectangle(blackWidth, blackHeight)
if (activeBlack == b) {
bKey.setFillColor(Color(255, 80, 50)) // ?????? ????? ?? ??? ???
} else {
bKey.setFillColor(Color(15, 15, 20))
}
bKey.setPosition(bxPos.toDouble, -30)
draw(bKey)
}
// 4. ????? ??? ?????
val title = Picture.text("? REAL MOUSE-CLICK INTERACTIVE PIANO ?", 18)
title.setPenColor(Color(0, 255, 200))
title.setPosition(-220, 175)
draw(title)
val subtitle = Picture.text("[ ???? ?????????? ?????????? ????????? ??????? ?????? ????? ???! ]", 11)
subtitle.setPenColor(Color(255, 215, 0))
subtitle.setPosition(-210, 148)
draw(subtitle)
}
drawRealPiano()
// ??????? ????? ??????? ?????????? ????????? ???
animateWithState(0.0) { frame =>
if (activeWhite != -1 || activeBlack != -1) {
activeWhite = -1
activeBlack = -1
drawRealPiano()
}
frame + 1.0
}
// 5. ???? ????? ??????? (Mouse Click Detection)
onMouseClick { (x, y) =>
var played = false
// ?????? ?????????? ????? ???? ?? ?? ?????? (Check Black Keys)
if (y >= -30 && y <= 100) {
for (b <- 0 until blackNoteIndices.length) {
val idx = blackNoteIndices(b)
val bxPos = startX + (idx * keyWidth) + (keyWidth - (blackWidth / 2))
if (x >= bxPos && x <= (bxPos + blackWidth)) {
activeBlack = b
playNote(blackNotes(b), 300) // ?????? ??????? ???
played = true
}
}
}
// ???????? ?????????? ????? ???? ?? ?? ?????? (Check White Keys)
if (!played && y >= -120 && y <= 100) {
for (i <- 0 until whiteNotes.length) {
val xPos = startX + (i * keyWidth)
if (x >= xPos && x <= (xPos + keyWidth)) {
activeWhite = i
playNote(whiteNotes(i), 300) // ???????? ??????? ???
}
}
}
drawRealPiano()
}