0

Im Currently developing a game with Processing and Fiducials. Basically this game consists of asking questions related to certain countries. Each ANS of each question is a Country. Example where is the Tower of Pisa, and the ASN italy. the user must show a Fiducial that represents the Italian Flag

I got the count down timer to run but i cant ge it to reset when a new level is started. we have each level in a switch.

Thanks A lot guys for your help!!

here is the code:

        import ddf.minim.*;
    import TUIO.*;
    TuioProcessing tuioClient;

    HashMap<Integer, String> symbolWordMap=new HashMap<Integer, String>();

    //The below variables are used to show the background image
    PImage bg;
    PImage start;
    PImage q1;
    PImage q2;
    PImage correct;
    PImage wrong;

    //The following are the variables used fro playing the sounds
    AudioPlayer player;
    AudioPlayer playerfail;
    Minim minim;

    int level = 0;

    int objSize=50;

    //This variable will be reduced everytime the player gets the answer wrong
    int lives = 5;

    //This variable will keep track of the score of the player
    int score = 0;

    //Declaring the font variable so as to display text on the screen
    PFont font;

    //Declaring the variable to be used for the timer
    //Timer t;


    //Below is the timer that will be used  
    void time(){
      int c;
      int csec;
      int climit = 20; //defined for a 20 second countdown

      c = climit*1000 - millis();
      csec = (c/(1000));

      if (csec > 0){
        text("TIME: "+csec+" secs",1800,50);
      } else {
        background(bg);
        text("TIME: 0 secs",1800,50);
        text("Time is up!",950,488);
      }
    }



    void setup()
    {
      symbolWordMap.put(0, "Start");  
      symbolWordMap.put(1, "Italy");
      symbolWordMap.put(2, "France");
      symbolWordMap.put(3, "Spain");
      symbolWordMap.put(4, "UK");
      symbolWordMap.put(5, "USA");
      symbolWordMap.put(6, "Malta");
      symbolWordMap.put(7, "Australia");
      symbolWordMap.put(8, "Germany");

      size(1920,976);

      //This is an instance of Minim
      minim = new Minim(this);

      //Load the applause mp3 file
      player = minim.loadFile("applause.mp3",2048);
      //Load the fail mp3 file
      playerfail = minim.loadFile("fail.mp3",2048);

      //Creating an instance of the Timer class
      //t = new Timer(20000);

      //savedTime = millis();

      //The below statement will load the image to be placed as a background from the Data folder. This image must be the same size as the window in which the program will run
      bg = loadImage("map.png");
      //Load the image for correct answer
      correct = loadImage("correct.png");
      //Load image for the incorrect answer
      wrong = loadImage("wrong.jpg");
      //Load the image for Question 1
      q1 = loadImage("Question1.png");
      //Load the image for Question 2
      q2 = loadImage("question2.png");
      //Load the image for the welcome page
      start = loadImage("Intro.png");

      //Creating the font of text to be displayed on screen;
      font = createFont("Arial",24,true);

      rectMode(CENTER);
      textAlign(CENTER, CENTER);

      // an instance of the TuioProcessing
      // since we ad "this" class as an argument the TuioClient expects
      // an implementation of the TUIO callback methods 
      tuioClient  = new TuioProcessing(this);
    }

    void draw()
    {

      //The following command will present the background
      background(bg);

      //Specifying the font to be used for text that is displayed on screen
      textFont(font,24);
      //Specifying the colour of the text that will be displayed on screen
      fill(0);

      if (level>0){
        text("SCORE: "+score,100,50);
        //text("Lives: "+lives,100,100);
      }

      //Creating the different levels
      switch(level){
        case 0:
        //Welcome Screen

        // get all the tuio objects detected by reactivision
        Vector<TuioObject> tuioObjectList =tuioClient.getTuioObjects();

        image(start,550,160);
        // Process each fiducial in turn
        for (int i=0;i<tuioObjectList.size();i++) {
          TuioObject tobj = tuioObjectList.get(i);

          pushMatrix();
          // Move origin to location of TUI object and rotate
          translate(tobj.getScreenX(width), tobj.getScreenY(height));
          rotate(tobj.getAngle());

          // draw the box
          fill(255);
          rect(0, 0, objSize, objSize);

          // Write the text inside the box 
          fill(0);

          int id = tobj.getSymbolID();
          String txt;
          if (symbolWordMap.containsKey(id)) {
            // if ID is in symbolWordMap, then look it up to find word
            txt = symbolWordMap.get(id);
          } 
          else { // otherwise, we'll just display the id number with a dot after
            txt = id+".";
          }
          text(txt, 0, 0);
          popMatrix();

          if (id == 0){
           level = 1;
           delay(2000);
          }
        }   

    break;

    case 1:
    //Level 1

        //Start timer
        //time();
        //noLoop();

        // get all the tuio objects detected by reactivision
        Vector<TuioObject> tuioObjectList1 =tuioClient.getTuioObjects();

        image(q1,550,160);
        // Process each fiducial in turn
        for (int i=0;i<tuioObjectList1.size();i++) {
          TuioObject tobj = tuioObjectList1.get(i);

          pushMatrix();
          // Move origin to location of TUI object and rotate
          translate(tobj.getScreenX(width), tobj.getScreenY(height));
          rotate(tobj.getAngle());

          // draw the box
          fill(255);
          rect(0, 0, objSize, objSize);

          // Write the text inside the box 
          fill(0);

          int id = tobj.getSymbolID();
          String txt;
          if (symbolWordMap.containsKey(id)) {
            // if ID is in symbolWordMap, then look it up to find word
            txt = symbolWordMap.get(id);
          } 
          else { // otherwise, we'll just display the id number with a dot after
            txt = id+".";
          }
          text(txt, 0, 0);
          popMatrix();

          if (id == 1){
            //Displays the text Correct on screen
            //text("Correct",500,500);
            score=score+10;
            background(bg);
            image(correct,800,300);
            player.play();
            player.rewind();
            //Time delay before advancing to next level
            delay(5000);            
            //Advance to level 2
            level++;
          } else {
            //Display the text Wrong to the left of the screen
            //text("Wrong",500,500);
            lives=lives-1;
            background(bg);
            image(wrong,700,300);
            playerfail.play();
            playerfail.rewind();
          }
        }   

    break;

    case 2:
    //Level 2

        //Start timer
        //time();
        //noLoop();


        // get all the tuio objects detected by reactivision
        Vector<TuioObject> tuioObjectList2 =tuioClient.getTuioObjects();

        //Load image for question 2
        image(q2,550,160);
        // Process each fiducial in turn
        for (int i=0;i<tuioObjectList2.size();i++) {
          TuioObject tobj = tuioObjectList2.get(i);

          pushMatrix();
          // Move origin to location of TUI object and rotate
          translate(tobj.getScreenX(width), tobj.getScreenY(height));
          rotate(tobj.getAngle());

          // draw the box
          fill(255);
          rect(0, 0, objSize, objSize);

          // Write the text inside the box 
          fill(0);

          int id = tobj.getSymbolID();
          String txt;
          if (symbolWordMap.containsKey(id)) {
            // if ID is in symbolWordMap, then look it up to find word
            txt = symbolWordMap.get(id);
          } 
          else { // otherwise, we'll just display the id number with a dot after
            txt = id+".";
          }
          text(txt, 0, 0);
          popMatrix();

           if (id == 8){
           //Displays the text Correct on screen
           //text("Correct",500,500);
           score=score+10;
           background(bg);
           image(correct,900,500);
           player.play();
           player.rewind();
           //Time delay before advancing to next level
           delay(5000);            
           //Advance to level 2
           level++;
         } else {
           //Display the text Wrong to the left of the screen
           //text("Wrong",500,500);
           lives=lives-1;
           background(bg);
           image(wrong,700,300);
           playerfail.play();
           playerfail.rewind();
         }
       }  

    break;

    case 3:
    //Level 3
    break;

    case 4:
    //Level 4
    break;

    case 5:
    //Level 5
    break;

  }
  //End of switch
}


void stopSound()
{
  player.close();
  playerfail.close();
  minim.stop();

  super.stop();
}

2 Answers2

0

The implementation of your timer suggests that it is a busy timer. What this means is that it is dependant on getting called multiple times and checking if it is later than some other time. A naive implementation of a busy timer would the following:

while(getTime() < someTime) { do nothing; }

This type of timer is not good. You should try spawning a thread, and using sleep. This is kind of like javascript event handlers. The OS awakens the thread at the time when it is asked, and you can then alert the program that the timers is up. If you don't need to be doing anything in the mean time, you could just as easily sleep your main, but it looked to me like you were doing something while you were keeping track of time.

PS: It appears your using Java... based on your "imports". Is this correct? If so I can nail down some references for you.

MobA11y
  • 18,425
  • 3
  • 49
  • 76
  • @ChrisCM I thought I'd clarify to [your question](http://stackoverflow.com/questions/16423321/subtle-memory-leak-and-is-this-common-practice/16423475#comment23588408_16423475); FYI I used "your values". What made you assume that I used anything else is a mystery to me. (I told you exactly what I used, and how.) Have a nice day. – sehe May 08 '13 at 17:16
0

I'm not fulling understanding where the timer is happening in your program. I see a timer class:

//Declaring the variable to be used for the timer
//Timer t;

But I don't see the class in use in your code. Only a function for time:

//Below is the timer that will be used  
void time(){
  int c;
  int csec;
  int climit = 20; //defined for a 20 second countdown

  c = climit*1000 - millis();
  csec = (c/(1000));

  if (csec > 0){
    text("TIME: "+csec+" secs",1800,50);
  } else {
    background(bg);
    text("TIME: 0 secs",1800,50);
    text("Time is up!",950,488);
  }
}

I would advise against using delay() in a Processing sketch and instead use different timers for when you want different events to occur after a certain amount of time.

I find a Daniel Shiffman example to be really simple and helpful for understanding how to implement timers in Processing. Here is an object-oriented timer, which would be more helpful to you in this case. Below is the Timer class from the link:

class Timer {

  int savedTime; // When Timer started
  int totalTime; // How long Timer should last

  Timer(int tempTotalTime) {
    totalTime = tempTotalTime;
  }

  // Starting the timer
  void start() {
    // When the timer starts it stores the current time in milliseconds.
    savedTime = millis(); 
  }

  // The function isFinished() returns true if 5,000 ms have passed. 
  // The work of the timer is farmed out to this method.
  boolean isFinished() { 
    // Check how much time has passed
    int passedTime = millis()- savedTime;
    if (passedTime > totalTime) {
      return true;
    } else {
      return false;
    }
  }
}

How is the user switching between levels? Is there a key press or mouse press that will trigger the next level? Or is it completely based on a timer? If it was based on a keypress, you could incorporate the following code:

int level;
Timer levelTimer;

void setup() {
  levelTimer = new Timer(5000);
}

void draw() {
  println(levelTimer.isFinished());
}

void keyPressed() {
  switch(key) {
  case '1':
    level = 1;
    levelTimer.start();
    break;
  case '2':
    level = 2;
    levelTimer.start();
    break;
  case '3':
    level = 3;
    levelTimer.start();
    break;
  }
}

This way you start the level timer each time the user progresses to the level they choose. Just a thought.

macklinu
  • 142
  • 1
  • 6
  • I believe the Timer he's creating is [java Timer] (http://docs.oracle.com/javase/6/docs/api/java/util/Timer.html) – v.k. May 09 '13 at 00:07