Задержка логического значения от переключения обратно к ложному

Итак, я работаю над игрой, которая требует обнаружения ударов. На данный момент у меня есть работающий код обнаружения битов, но он находится в своем отдельном Java-апплете, пока я работаю над тем, чтобы все прояснить, чтобы не вызывать никаких проблем в игровом коде. Моя проблема в том, что когда код обнаруживает ритм, он переключается обратно на то, чтобы не быть тактом быстрее, чем пользователь мог когда-либо касаться экрана.

Я создал простой Boolean, который переключает isBeat с false на true при каждом ударе, и я печатаю слова "True" и "False". Когда программа запускается, вы едва видите слово "True", потому что оно только на экране в течение доли секунды. Есть ли способ отложить переключение isBeat с true на false?

По сути, на этом этапе мне бы хотелось, чтобы слово "True" (то есть только что случившийся удар) оставалось на экране в течение 1 секунды. По истечении 1 секунды он переключается в режим "Ложь" и ожидает следующего удара. 1 секунда - это немного долго, но сейчас я смогу проверить это лучше. Он не может задержать простое изменение рисунка на экране, но он должен задержать переключение всего логического значения, потому что я собираюсь использовать логическое значение isBeat в финальной игре. Когда случится удар, isBeat переключится на true и даст игрокам небольшое время, чтобы коснуться экрана, прежде чем вернуться к false. На экране не будет отображаться текст, чтобы сообщить им, что произошел удар, как сейчас.

Вот код Это использует библиотеку minim вместе с обработкой внутри 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();
}

}

Я провел поиск в Google и попробовал некоторые вещи, такие как wait(), но либо я делаю их все неправильно, либо он не предназначен для работы так, как я хочу. Похоже, простая проблема, которую я не могу понять...

2 ответа

Я думаю, что у вас есть логическая ошибка в вашем коде

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);

Кроме этого, я бы не советовал использовать что-то вроде сна или ожидания, потому что это повесит поток на время ожидания.

Совет, который я могу дать, использует дополнительное условие, использующее текущее время.

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);
        .
        .
   }

Очень простой подход будет следующим:

объявить переменную-член

private long lastBeatAt = 0;

затем используйте его, чтобы сохранить метку времени последнего удара:

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

конечно, это не приведет к тому, что isBeat будет точно равен секунде true, но это будет близко в зависимости от частоты, с которой вызывается draw().

Другие вопросы по тегам