implemented single note practice
This commit is contained in:
parent
6204637d0e
commit
637edb0302
5 changed files with 243 additions and 57 deletions
167
html/assets/scripts/practice.js
Normal file
167
html/assets/scripts/practice.js
Normal file
|
@ -0,0 +1,167 @@
|
|||
class Task {
|
||||
/**
|
||||
*
|
||||
* @param {Array} keysig list of keysignatures to use (int 0-11) where 0 = C || a, 1 = G || e ...
|
||||
* @param {boolean} natural enable/disable naturals
|
||||
* @param {boolean} sharp enable/disable sharps
|
||||
* @param {boolean} flat enable/disable flats
|
||||
* @param {boolean} chord enable/disable chords (it's either chords or single notes)
|
||||
* @param {boolean} extend enable/disable notes above C6 and below C2
|
||||
*/
|
||||
constructor() {
|
||||
this.render = new Notation();
|
||||
this.retrieve_settings();
|
||||
|
||||
this.solution = []; // keys to solve current problem
|
||||
this.activeKeys = []; // currently pressed keys
|
||||
this.active = true; // true while task can be solved
|
||||
this.success = false;
|
||||
|
||||
this.generateTask();
|
||||
}
|
||||
|
||||
generateTask() {
|
||||
this.retrieve_settings();
|
||||
if (this.chord) {
|
||||
this.generateChord();
|
||||
} else {
|
||||
this.generateNote();
|
||||
}
|
||||
}
|
||||
|
||||
generateNote() {
|
||||
let pickFrom = [];
|
||||
|
||||
// TODO: choose signature
|
||||
|
||||
// TODO: maybe weight note likelyhood
|
||||
|
||||
if (this.natural) {
|
||||
pickFrom.push(...nat_values);
|
||||
if (this.extend) {
|
||||
pickFrom.push(...nat_values_ex);
|
||||
}
|
||||
}
|
||||
if (this.sharp) {
|
||||
pickFrom.push(...shp_values);
|
||||
if (this.extend) {
|
||||
pickFrom.push(...shp_values_ex);
|
||||
}
|
||||
}
|
||||
if (this.flat) {
|
||||
pickFrom.push(...flt_values);
|
||||
if (this.extend) {
|
||||
pickFrom.push(...flt_values_ex);
|
||||
}
|
||||
}
|
||||
|
||||
// pick from generated pool
|
||||
var randomResult = Math.floor(Math.random() * pickFrom.length);
|
||||
let chosenNote = pickFrom[randomResult];
|
||||
this.solution = [chosenNote[1]];
|
||||
|
||||
let clef = "";
|
||||
|
||||
// choose clef
|
||||
if (chosenNote[1] == 40) {
|
||||
Math.random() < 0.5 ? clef = "bass" : clef = "treble";
|
||||
} else if (chosenNote[1] < 40) {
|
||||
clef = "bass";
|
||||
} else {
|
||||
clef = "treble";
|
||||
}
|
||||
|
||||
this.solution = [chosenNote[1]];
|
||||
this.render.set_notes([new Noteset(clef, [chosenNote[0]])]);
|
||||
}
|
||||
|
||||
generateChord() {
|
||||
|
||||
}
|
||||
|
||||
on_keyStateChange() {
|
||||
if (this.active) {
|
||||
this.checkActiveKeys();
|
||||
} else {
|
||||
console.log("Can't continue, still keys pressed.");
|
||||
return;
|
||||
}
|
||||
if (this.success) {
|
||||
this.generateTask();
|
||||
} else if (this.activeKeys.length == 0) {
|
||||
this.active = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Keeps Track of pressed keys
|
||||
* @param {number} key
|
||||
* @param {boolean} state
|
||||
*/
|
||||
changeKeyState(key, state) {
|
||||
if (state) {
|
||||
// start new timer
|
||||
if (this.activeKeys.length == 0) {
|
||||
this.active = true;
|
||||
this.starttime = Date.now();
|
||||
}
|
||||
this.activeKeys.push(key);
|
||||
} else {
|
||||
let index = this.activeKeys.indexOf(key);
|
||||
if (index != -1) {
|
||||
this.activeKeys.splice(index, 1);
|
||||
}
|
||||
}
|
||||
this.on_keyStateChange()
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if activeKeys fulfill current task
|
||||
*/
|
||||
checkActiveKeys() {
|
||||
this.activeKeys.forEach( key => {
|
||||
if (!(key in this.solution)) {
|
||||
this.result_fail();
|
||||
return;
|
||||
}
|
||||
});
|
||||
if (this.activeKeys.length == this.solution.length) {
|
||||
if (Date.now() - this.starttime <= 500) {
|
||||
this.result_success();
|
||||
return;
|
||||
} else {
|
||||
this.result_fail();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result_fail() {
|
||||
console.log("Wrong!");
|
||||
this.active = false;
|
||||
}
|
||||
|
||||
result_success() {
|
||||
console.log("Correct!");
|
||||
this.solution = [];
|
||||
this.active = false;
|
||||
this.success = true;
|
||||
}
|
||||
|
||||
retrieve_settings() {
|
||||
let cbx_naturals = document.getElementById("naturals");
|
||||
let cbx_sharps = document.getElementById("sharps");
|
||||
let cbx_flats = document.getElementById("flats");
|
||||
let cbx_extended = document.getElementById("extended");
|
||||
|
||||
this.keysig = [0];
|
||||
this.natural = cbx_naturals.checked;
|
||||
this.sharp = cbx_sharps.checked;
|
||||
this.flat = cbx_flats.checked;
|
||||
this.chord = false;
|
||||
this.extend = cbx_extended.checked;
|
||||
}
|
||||
}
|
||||
|
||||
// Starts the task loop
|
||||
var task = new Task();
|
Loading…
Add table
Add a link
Reference in a new issue