Reactivision processing loop issue

hi i am making a math game targeted at kids using reactivision and processing.
i want there to be several questions generated randomly and once they have answered correctly a new question is generated. i have tried using this loop but the program keeps looping the for loop and it never actually exits the loop. the code is below.

////////Level 1 Game State
public void easyMode(){
float obj_size = object_size*scale_factor; 
 // float cur_size = cursor_size*scale_factor; 
   
  ArrayList<TuioObject> tuioObjectList = tuioClient.getTuioObjectList();
  for (int i=0;i<tuioObjectList.size();i++) {
     TuioObject tobj = tuioObjectList.get(i);
     
background(255);     
//int eNum1 = (int)(Math.random() *10);
int q=0;
int eAnswer;
int countE= 2;

//text("Time in secs: "+str(s.time()/1000.0), 50, 100);
//fill(0);
eAnswer = eNum1 + eNum2;
for (q = 0; q < countE; q++){
 //while(q<countE){
   
  fill(200);
  text("what is " + eNum1 + " + " + eNum2 + " ? ", 500, 500);

  if (tobj.getSymbolID()==eAnswer){
   
    print(q);

  text("great, the answer is " + eAnswer, 100,100);
  fill(255);
 //  q= q+1;
  
  eNum1 = (int)(Math.random() *10);
  eNum2 = (int)(Math.random() *10);
}
  
  else if(tobj.getSymbolID()!=eAnswer){
    text("That is the incorrect answer, please try again",100,100 );
  }
 else if(q==countE){
   background(#E04848);
   text("finished", 800, 900);
 }

  }

}
}
1 Like

You are doing a LOT inside this loop. Do you really need to do all those steps for each TuioObject? Probably not.

I would highly suggest breaking your code down into smaller functions. For example, you might have one that generates the values for a new question:

void new_question(){
  eNum1 = (int)(Math.random() *10);
  eNum2 = (int)(Math.random() *10);
  eAnswer = eNum1 + eNum2;
  // Maybe more code that generates answer choices...
}

Then you might have a function that displays the question and choices.

void draw_question(){
  text("What is " + eNum1 + " + " + eNum2 + "?", 20, 20);
  // Maybe more code to draw answer choices here...
}

Then you might have a function that looks to see if a touch has happened on a choice:

void check_for_touches(){
  // Get the list of touches.
  // See if any of them are on an answer.
  // If it's the right answer, go to the "show correct message" state.
  // If not, go to the "show wrong answer message" state.
}

Then your main loop code is much easier to write:

void draw(){
  if( state == show_question ){
    draw_question();
    check_for_touches();
  }
  if( state == show_correct_message ){
    show_correct_message();
  }
  if( state == show_wrong_message ){
    show_wrong_message();
  }
}

If you have different states for “show question”, and “show correct answer message” and “show wrong answer message”, then it’s easier to work out how to transition between them.

1 Like

hi thanks for the comprehensive and rather helpful answer. however, i have created gamestates for my levels in the draw method. i have"homescreen", “level1”, “level2” “controls” etc. the code that i have uploaded is in itself already in a function.

If your game already has states, great! You can also have states WITHIN states. Your game might be in
it’s “level1” state, but within that state, you could have even more sub-states!

Example:

int main_state = 0;
int sub_state = 0;
int a, b, c, d;

void setup() {
  size(400, 400);
  textAlign(CENTER);
  textSize(32);
  fill(255);
}

void draw() {
  switch(main_state) {
  case 0: // title screen
    background(0);
    text("MATH QUESTIONS", 200, 200);
    text("Click to start.", 200, 300);
    break;
  case 1: // The first level.
    switch(sub_state) {
    case 0: // Unanswered.
      background(64);
      text("What is " + a + " + " + b + "?", 200, 100);
      line(0,200,400,200);
      line(200,200,200,400);
      text(c, 100, 300);
      text(d,300,300);
      break;
    case 1: // Right answer.
      background(0, 128, 0);
      text("Yes!", 200, 200);
      break;
    case 2: // Wrong answer.
      background(128,0, 0);
      text("No!", 200, 200);
      break;
    }
    break;
  case 2:
    background(0,0,128);
    text("The end!", 200, 200);
  }
}

void mousePressed() {
  switch(main_state) {
  case 0:
    random_question();
    main_state = 1;
    sub_state = 0;
    break;
  case 1:
    if( sub_state == 0 && mouseY > 200 ){
      if( mouseX < 200 ){ // left side, right answer!
        sub_state = 1;
      } else { // right side, wrong answer!
        sub_state = 2;
      }
    } else if( sub_state != 0 ){
      main_state = 2;
      sub_state = 0;
    }
  }
}

void random_question() {
  a = int(random(20));
  b = int(random(20));
  c = a + b;
  d = int(random(40));
  while ( d == c ) {
    d = int(random(40));
  }
}

See how, even in the main_state of 1 (“doing level 1”), there are sub-states of 0, 1, and 2 (for unanswered, right, and wrong)?

2 Likes

Thanks for the insight! im pretty new to coding so i wasnt really aware of this. i managed to get my program to work the original way. the loop works however there is an issue with the draw section. i can see that in the console however it works perfectly.
is it possible if you can provide me with your e-mail so i can send you the full program? it works but as soon as i choose the gamestate “easy mode” the visual representation disappears however everything works in the background as i am using the console to track it.

@Tonym – You can also feel free to post the full program to the forum if you wish to share – or to upload it to a free github.com repository and share a link to it.

If you have a lot of states, you can also save them in an array. For example, say you have eight worlds, and four levels per world.

supermario-nes-8x4

You need to know what world and level you are currently on, you want to know whether each one has been completed and if so what the score was for each of those 32 levels. Instead of creating 34 variables, you can just create two, like this:

int[] currentLevel = new int[2];          // 1x2 list of current location, e.g. world 7, level 1 
int[][] worldLevelScores = new int[8][4]; // 8x4 list of scores

Now you can change the current level:

currentLevel = { 3, 4 };

And get the score when you enter a level:

print(worldLevelScores[currentLevel[0]][currentLevel[1]]);

and update the score when you finish your current level:

worldLevelScores[currentLevel[0]][currentLevel[1]] = newScore;
1 Like