class Note extends ScrollElement { // States protected final int STATE_IN_PLAY = 0; // regular state (including if off screen) protected final int STATE_FADING_OUT = 1; // note was correctly hit, so it fades away protected final int STATE_HIT_INCORRECTLY = 2; // note was incorrectly hit, so it should die protected final int STATE_HIT_BOUNDARY = 3; // note hit the left boundary, so it should explode protected final int STATE_FINISHED = 4; // note is ready to be removed protected final int TIME_TO_FADE = 15; protected final int TIME_HIT_INCORRECTLY = 10; protected final int TIME_HIT_BOUNDARY = 5; protected final int TEXT_X_OFFSET = -5; protected final int TEXT_Y_OFFSET = 50; protected int m_state; protected int m_timeLeftForFade; protected int m_timeLeftHitIncorrectly; protected int m_timeLeftHitBoundary; protected PImage noteImage, redNoteImage; protected char note; protected PFont helperFont; public Note(Staff staff, int x, int y, char note) { super(staff,x,y); this.note = note; noteImage = loadImage("8th-note.png"); redNoteImage = loadImage("8th-note-red.png"); helperFont = loadFont("Helvetica-20.vlw"); m_state = STATE_IN_PLAY; m_timeLeftForFade = 0; m_timeLeftHitIncorrectly = 0; m_timeLeftHitBoundary = 0; } public boolean isNote() { return true; } public boolean isSpeedChange() { return false; } public char getNote() { return note; } public void advance() { if (m_state == STATE_IN_PLAY || m_state == STATE_FADING_OUT) { if (m_x <= Config.boundaryX && m_state != STATE_FADING_OUT) { hitBoundary(); return; } m_x -= m_staff.getScrollSpeed(); } } public void hit() { super.hit(); staff.incrementPoints(); m_state = STATE_FADING_OUT; m_timeLeftForFade = TIME_TO_FADE; } public void miss() { super.miss(); staff.decrementPoints(); m_state = STATE_HIT_INCORRECTLY; m_timeLeftHitIncorrectly = TIME_HIT_INCORRECTLY; } public void hitBoundary() { super.hitBoundary(); staff.decrementPoints(); m_state = STATE_HIT_BOUNDARY; m_timeLeftHitBoundary = TIME_HIT_BOUNDARY; } public boolean removeMe() { return m_state == STATE_FINISHED; } public boolean inPlay() { return m_state == STATE_IN_PLAY; } public void draw() { if (offScreen()) { return; } if (m_state == STATE_FADING_OUT) { m_timeLeftForFade--; if (m_timeLeftForFade <= 0) { m_state = STATE_FINISHED; } else { float fade = (m_timeLeftForFade / (float)TIME_TO_FADE) * 255; tint(255, (int)fade); image(noteImage, m_x, m_y - 20, 50, Config.staffHeight / (m_staff.numberOfLines + m_staff.numberOfSpaces) + 50); noTint(); } } else if (m_state == STATE_HIT_INCORRECTLY) { m_timeLeftHitIncorrectly--; if (m_timeLeftHitIncorrectly <=0) { m_state = STATE_FINISHED; } else { image(redNoteImage, m_x, m_y - 20, 50, Config.staffHeight / (m_staff.numberOfLines + m_staff.numberOfSpaces) + 50); if (m_staff.showKeyPressHelpers()) { textFont(helperFont); text(note, m_x + TEXT_X_OFFSET, m_y + TEXT_Y_OFFSET); } } } else if (m_state == STATE_HIT_BOUNDARY) { m_timeLeftHitBoundary--; if (m_timeLeftHitBoundary <=0) { m_state = STATE_FINISHED; } else { image(redNoteImage, m_x, m_y - 20, 50, Config.staffHeight / (m_staff.numberOfLines + m_staff.numberOfSpaces) + 50); } } else if (m_state == STATE_FINISHED) { // do nothing } else if (m_state == STATE_IN_PLAY) { image(noteImage, m_x, m_y - 20, 50, Config.staffHeight / (m_staff.numberOfLines + m_staff.numberOfSpaces) + 50); if (m_staff.showKeyPressHelpers()) { textFont(helperFont); text(note, m_x + TEXT_X_OFFSET, m_y + TEXT_Y_OFFSET); } } } }