"Rebuffen" - Messen der Zeit eines Timers

xyss

Aktives Mitglied
Hallo Javacommunity,

ich bin aktuell dabei ein Spiel zu programmieren, und so wie man es aus manchen Spielen kennt, kann der Spieler auch sogenannte Buffs erhalten, sprich, Fähigkeiten (z.B. erhöhte Laufgeschwindigkeit) über Zeit. Das tue ich aktuell über die in Java vorhandene Klasse Timer.

Nehmen wir Mal das Beispiel von oben: Erhöhte Laufgeschwindigkeit
Wenn der Buff aktiviert wird, passiert folgendes: Laufgeschwindigkeit wird erhöht, der Timer gestartet, und die Laufgeschwindigkeit wird danach wieder verringert.

Code:
[Java]
private void runBuffTimer(){
if (activate && !buffActive){
buffActive = true;
handleBuffActivation(); //Aktiviert die Fähigkeit des Buffs
buffTimer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
handleBuffDeactivation(); //Deaktiviert die Fähigkeit des Buffs
activate = false;
buffActive = false;
}
};
buffTimer.schedule(task, duration);
}
}
[/Java]

Die boolean-Variablen dienen dazu, dass nicht ein und der selbe Buff mehrmals aktiviert wird (und dann "gleichzeitig" wirkt).

Mein Problem ist nun das sogenannte "rebuffen", also das überschreiben des Buffs, durch einen besseren.
Beispiel:
Wenn es nun nur den Buff gibt:
- Laufgeschwindigkeit +5 für 5 Sekunden

Der Spieler hat den Buff (5 Sekunden), dieser läuft aber schon seit 3 Sekunden, also sind nur noch 2 Sekunden übrig. Wenn der Spieler nun den Buff nochmal erhält, soll der alte überschrieben werden, also wieder bei 5 Sekunden Laufzeit sein.

Ein etwas komplexeres Beispiel:
- Laufgeschwindigkeit +5 für 3 Sekunden
- Laufgeschwindigkeit +5 für 5 Sekunden
- Laufgeschwindigkeit +5 für 7 Sekunden

Der Spieler hat den 2. Buff (5 Sekunden), erhält nun den 1. Buff (3 Sekunden). Falls der 2. Buff nur noch weniger als 3 Sekunden Laufzeit hat, wird der 2. Buff durch den 1. überschrieben, ansonsten nicht. Danach erhält er den 3. Buff (7 Sekunden). Da dieser länger anhält als die anderen, überschreibt er den aktuellen Buff.

Mein Problem ist also konkret, dass ich nicht weiß, wie ich bei einem Timer überprüfen kann, wie lange dieser schon läuft, da ich bei den Buffs entscheiden muss, welcher der beiden zu dem aktuellen Zeitpunkt länger aktiv ist.
 

turtle

Top Contributor
wird der 2. Buff durch den 1. überschrieben,
Das ist ein Problem, denn meines Wissens kannst du einen Thread nicht überschreiben.

Der Thread startet und beendet sich irgendwann. Dazwischen ist es ja so, das du da nicht eingreifen kannst. Selbst stoppen kannst du ihn nicht, es sei denn, der Thread "überwacht" das und reagiert entsprechend.

Am Beispiel des Abbrechens sieht der Code in der Run-Methode dann meistens so aus:
Java:
public void run() {
 while ( ! isInterrupted() ) {
}
}

So könntest du Variable von aussen setzen, die der Thread ebenfalls überwacht und entsprechend reagiert. Dies ist aber komplex weil du ja mehrere paralelle laufende Threads hast und die Zugriffe synchronisiert werden müssen.
 

Joose

Top Contributor
Was wäre du für jeden Spieler einen Thread zur Verfügung stellst.
Dieser Thread macht nichts anderes als zu überwachen ob ein neuer Buff einen alten überschreiben soll, soll ein Buff auslaufen/deaktiviert werden usw.
Und dieser Thread prüft einfach jede Sekunde die Liste an Buffs durch (bzw. auch neue)
 

xyss

Aktives Mitglied
Das mit dem überwachen habe ich implementiert, funktioniert gut :)

Für das "unterbrechen" bzw überschreiben eines Buffs, habe ich die in Java vorhandene Klasse Timer verwendet, und mit hilfe von timer.cancel() und timer.purge() den Timer unterbrochen, und danach einen neuen gestartet.

Danke euch beiden :)
 

Ähnliche Java Themen


Oben