llsol_sc-project-flute-app/maze_2_counter/maze_1.pde
//SOUND COMMUNICATION PROJECT

import oscP5.*;
import netP5.*;

float diameter = 20;
float posX;
float posY;
float initialPosX = 75;
float initialPosY = 275;
OscP5 oscP5;
OscP5 face;

boolean desiredInput = false;
boolean hasSurpassedThresholdOnce = true;

float speed = 3.0;
boolean succeeded = false;
boolean countingDown = false;
float angle = 0;
PVector targetPosition;

float face_value = 0;
float section = 1;
float nota = 0;

int countdownValue = 5; // Valor inicial del contador
int lastMoveTime; // Tiempo del último movimiento
int checkpointTime; // Tiempo en el checkpoint

int collisionCount = 0;
int maxCollisions = 25;

void setup() {
  size(800, 600);
  colorMode(RGB, 1.0);
  stroke(0.0);

  posX = initialPosX;
  posY = initialPosY;

  oscP5 = new OscP5(this, 12000);
  face = new OscP5(this, 12001);

  targetPosition = new PVector(posX, posY);
  lastMoveTime = millis();
}

void draw() {
  background(0.75);

  strokeWeight(2);

 // Dibuja los carriles del laberinto
  line(50, 250, 300, 250);
  line(50, 300, 350, 300);
  
  line(300, 250, 300, 100);
  line(350, 300, 350, 150);
  
  line(300, 100, 500, 100);
  line(350, 150, 450, 150);
  
  line(450, 150, 450, 300);
  line(500, 100, 500, 250);
  
  line(500, 250, 650, 250);
  line(450, 300, 600, 300);
  
  line(600, 300, 600, 450);
  line(650, 250, 650, 400);
  
  line(650, 400, 750, 400);
  line(600, 450, 750, 450);
  // Dibuja el círculo
  pushMatrix();
  translate(posX, posY);
  rotate(radians(angle));
  fill(0);
  ellipse(0, 0, diameter, diameter);
  popMatrix();

  moveEllipseTowardsTarget();
  checkCollision();

  // Mostrar el contador de tiempo y de colisiones
  fill(0);
  textSize(24);
  textAlign(LEFT, TOP);
  text("Time: " + countdownValue, 10, 10);
  text("Collisions: " + collisionCount, 10, 70);  // Añadido contador de colisiones
  textAlign(RIGHT, TOP);
  text("Face: " + face_value, width - 10, 10);

  if (succeeded) {
    fill(0);
    textSize(60);
    textAlign(RIGHT, TOP);
    text("Succeed!", width / 2, 450);
  }

  if (countingDown) {
    int currentTime = millis();
    if (currentTime - checkpointTime >= 1000) {
      countdownValue--;
      checkpointTime = currentTime;
    }
    if (countdownValue <= 0) {
      fill(0);
      textSize(60);
      textAlign(CENTER, CENTER);
      text("You Lost!", width / 2, 450);
      noLoop(); // Detener el loop de draw
    }
  }

  // Verificar si se ha alcanzado el límite de colisiones
  if (collisionCount >= maxCollisions) {
    fill(0);
    textSize(60);
    textAlign(CENTER, CENTER);
    text("You Lost!", width / 2, height / 2);
    noLoop(); // Detener el loop de draw
  }
}


void oscEvent(OscMessage theOscMessage) {
  if (theOscMessage.checkAddrPattern("/wek/outputs")) {
    float[] outputs = new float[2];
    for (int i = 0; i < 2; i++) {
      outputs[i] = theOscMessage.get(i).floatValue();
    }
    updateEllipse(outputs);
  }
  if (theOscMessage.checkAddrPattern("/wek/face")) {
    int oscArg = int(theOscMessage.get(0).floatValue());
    face_value = oscArg;
  }
}

void updateEllipse(float[] outputs) {
  desiredInput = false;

  if (face_value == 1) {
    if (section == 2 && outputs[0] > 0.90) {
      desiredInput = true;
      angle = 0;
      targetPosition = new PVector(posX, posY - 10);
    } else if (section == 3 && outputs[0] > 0.90) {
      desiredInput = true;
      angle = 0;
      targetPosition = new PVector(posX + 10, posY);
    } else if (section == 4 && outputs[0] > 0.90) {
      desiredInput = true;
      angle = 0;
      targetPosition = new PVector(posX, posY + 10);
    } else if (section == 5 && outputs[0] > 0.90) {
      desiredInput = true;
      angle = 0;
      targetPosition = new PVector(posX + 10, posY);
    } else if (section == 6 && outputs[0] > 0.90) {
      desiredInput = true;
      angle = 0;
      targetPosition = new PVector(posX, posY + 10);
    } else if (section == 7 && outputs[0] > 0.90) {
      desiredInput = true;
      angle = 0;
      targetPosition = new PVector(posX + 10, posY);
    } else if (outputs[0] > 0.90) {
      desiredInput = true;
      angle = 0;
      targetPosition = new PVector(posX + 10, posY);
    } else if (hasSurpassedThresholdOnce) {
      desiredInput = false;
      angle = 30;
      targetPosition = new PVector(posX + 10, posY + 10);
    }
  }

  if (desiredInput) {
    hasSurpassedThresholdOnce = true;
  }
}

void moveEllipseTowardsTarget() {
  if (targetPosition != null) {
    float dx = targetPosition.x - posX;
    float dy = targetPosition.y - posY;
    float distance = dist(posX, posY, targetPosition.x, targetPosition.y);
    if (distance > speed) {
      posX += dx / distance * speed;
      posY += dy / distance * speed;
      countingDown = false; // Reset countdown if the ellipse is moving
      countdownValue = 3; // Reset the countdown value
      lastMoveTime = millis(); // Update last move time
    } else {
      posX = targetPosition.x;
      posY = targetPosition.y;
      if (!countingDown) {
        countingDown = true;
        checkpointTime = millis(); // Start counting down
      }
    }
  }
}

void checkCollision() {
  boolean collision = false;

  switch ((int) section) {
    case 1:
      if (posY - diameter / 2 <= 250 && posX >= 50 && posX <= 300) {
        collision = true;
      }
      if (posY + diameter / 2 >= 300 && posX >= 50 && posX <= 350) {
        collision = true;
      }
      if (posX > 300) {
        section = 2;
      }
      break;
    case 2:
      if (posX - diameter / 2 <= 300 && posY >= 100 && posY <= 250) {
        collision = true;
      }
      if (posX + diameter / 2 >= 350 && posY >= 150 && posY <= 300) {
        collision = true;
      }
      if (posY < 100) {
        section = 3;
      }
      if (collision) {
        resetPosition(325, 275);
      }
      break;
    case 3:
      if (posY - diameter / 2 <= 100 && posX >= 300 && posX <= 500) {
        collision = true;
      }
      if (posY + diameter / 2 >= 150 && posX >= 350 && posX <= 450) {
        collision = true;
      }
      if (posX > 500) {
        section = 4;
      }
      if (collision) {
        resetPosition(325, 125);
      }
      break;
    case 4:
      if (posX - diameter / 2 <= 450 && posY >= 150 && posY <= 300) {
        collision = true;
      }
      if (posX + diameter / 2 >= 500 && posY >= 100 && posY <= 250) {
        collision = true;
      }
      if (posY > 250) {
        section = 5;
      }
      if (collision) {
        resetPosition(475, 125);
      }
      break;
    case 5:
      if (posY + diameter / 2 >= 300 && posX >= 450 && posX <= 600) {
        collision = true;
      }
      if (posY - diameter / 2 <= 250 && posX >= 500 && posX <= 650) {
        collision = true;
      }
      if (posX > 600) {
        section = 6;
      }
      if (collision) {
        resetPosition(475, 275);
      }
      break;
    case 6:
      if (posX - diameter / 2 <= 600 && posY >= 300 && posY <= 450) {
        collision = true;
      }
      if (posX + diameter / 2 >= 650 && posY >= 250 && posY <= 400) {
        collision = true;
      }
      if (posY > 450) {
        section = 7;
      }
      if (collision) {
        resetPosition(625, 275);
      }
      break;
    case 7:
      if (posY + diameter / 2 >= 450 && posX >= 600 && posX <= 750) {
        collision = true;
      }
      if (posY - diameter / 2 <= 400 && posX >= 650 && posX <= 750) {
        collision = true;
      }
      if (posX > 750) {
        succeeded = true;
      }
      if (collision) {
        resetPosition(625, 425);
      }
      break;
  }

  if (collision && section != 2 && section != 3 && section != 4 && section != 5 && section != 6 && section != 7) {
    resetPosition(initialPosX, initialPosY);
  }
   if (collision) {
    collisionCount++; // Incrementar el contador de colisiones
    if (collisionCount >= maxCollisions) {
      noLoop(); // Detener el loop de draw si se alcanza el límite de colisiones
    }
  }
}

void resetPosition(float newPosX, float newPosY) {
  posX = newPosX;
  posY = newPosY;
  targetPosition = new PVector(posX, posY);
  angle = 0;
  succeeded = false;
  hasSurpassedThresholdOnce = false;
  countingDown = false;
  countdownValue = 5; // Reset the countdown value
  lastMoveTime = millis(); // Update last move time
  // No reseteamos collisionCount aquí
}
