Delay boolean from switching back to false

709 views Asked by At

So, I am working on a game that requires beat detection. At this point, I have working beat detect code but it is in its own standalone java applet while I work on getting things ironed out so I don't cause any issues inside the game code. My issue is, when the code detects the beat, it switches back to not being a beat faster than the user could ever tap the screen.

I created a simple Boolean that switches isBeat from false to true whenever a beat happens and I am printing out the word "True" and "False". When the program runs, you can just barely see the word "True" because its only on the screen for a fraction of a second. Is there any way to delay the switching of isBeat from true to false?

Basically at this point, I would like the word "True" (meaning a beat just happened) to remain on the screen for 1 second. After 1 second has passed, it would switch to "False" and wait for the next beat. 1 second is a little long, but I would be able to test it better this way for now. It can not delay simply changing the drawing on the screen, but it needs to delay the whole Boolean from switching because I am going to use the isBeat Boolean in the final game. When a beat happens, isBeat will switch to true and give players a small window of time to tap the screen before switching back to false. No text will appear on the screen to let them know a beat happened like it does now.

Here is the code. This is using the minim library along with processing inside eclipse.

import processing.core.*;
import ddf.minim.*;
import ddf.minim.analysis.*;

public class MyProcessingSketch extends PApplet {

Minim minim;
AudioPlayer song;
BeatDetect beat;
BeatListener bl;

float kickSize, snareSize, hatSize;
float playPos, playLen, xpos;

int kickCount = 0;
int snareCount = 0;
int hatCount = 0;
int beatCount = 0;
boolean isBeat = false;

public void setup()
{
    size(600, 500);
    minim = new Minim(this);
    song = minim.loadFile("mainmenumusic.mp3");
    song.play();
    playPos = song.position();
    playLen = song.length();
    xpos = (playPos / playLen) * width;
    beat = new BeatDetect(song.bufferSize(), song.sampleRate());
    beat.setSensitivity(24);
    kickSize = snareSize = hatSize = 16;
    bl = new BeatListener(beat, song);
    textFont(createFont("Helvetica", 16));
    textAlign(CENTER);
}

public void draw()
{
    background(0);
    fill(255);
    beat.detect(song.mix);
    if(beat.isKick()) kickSize = 32;
    if(beat.isKick()) kickCount++;
    if(beat.isSnare()) snareSize = 32;
    if(beat.isSnare()) snareCount++;
    if(beat.isSnare() == true)
    {
        isBeat = true;      
        beatCount++;
    }
    else
    {
        isBeat = false;
    }
    if(beat.isHat()) hatSize = 32;
    if(beat.isHat()) hatCount++;
    textSize(kickSize);
    text("isBeat", width/4, height/4);
    if(isBeat == true)
        text("True", width/4, height/2);
    if(isBeat == false);
        text("False", width/4, height/2);
    textSize(snareSize);
    text("SNARE", width/2, height/4);
    text(snareCount, width/2, height/2);
    textSize(hatSize);
    text("HAT", 3*width/4, height/4);
    text(hatCount, 3*width/4, height/2);
    kickSize = constrain((int) (kickSize * 0.95), 16, 32);
    snareSize = constrain((int) (snareSize * 0.95), 16, 32);
    hatSize = constrain((int) (hatSize * 0.95), 16, 32);

}

public void stop()
{
    song.close();
    minim.stop();
    super.stop();
}

}

I have done some google searching and tried some things like wait() but either I am doing them all wrong, or it is not intended to work the way I want them too. Seems like a simple issue that I can't figure out...

2

There are 2 answers

0
jimjim On

A very simple approach would be this:

declare a member variable

private long lastBeatAt = 0;

then use it to store the timestamp of the last beat:

if (beat.isSnare() == true)
{
    isBeat = true;
    beatCount++;
    lastBeatAt = System.currentTimeMillis();
}
else if (System.currentTimeMillis() > lastBeatAt + 1000) 
{
    isBeat = false;
}

of course this will not result in exactly a second of isBeat being true, but it would be close depending on the frequecy at which draw() is called.

1
Makis Tsantekidis On

I think you have logical error in your code

if(isBeat == true)
        text("True", width/4, height/2);
    if(isBeat == false);    // <---- here you have ; so
        text("False", width/4, height/2); //<---- this will always be executed even if isBeat == true
    textSize(snareSize);
    text("SNARE", width/2, height/4);

Other than that I would not suggest using something like sleep or wait because it would hang the thread for the time it waited.

A suggestion i can give you is using an extra condition utilising current time

long previous_beat = System.currentTimeMillis(); //<--- class variable
.
.

public void draw()
   {
    .
    .
        textSize(kickSize);
        text("isBeat", width/4, height/4);
        if(isBeat == true || previous_beat+10*1000> System.currentTimeMillis())
        {
          text("True", width/4, height/2);
          previous_beat = System.currentTimeMillis();
        }
        else if(isBeat == false)
            text("False", width/4, height/2);
        textSize(snareSize);
        text("SNARE", width/2, height/4);
        .
        .
   }