Задержка логического значения от переключения обратно к ложному
Итак, я работаю над игрой, которая требует обнаружения ударов. На данный момент у меня есть работающий код обнаружения битов, но он находится в своем отдельном 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().