Ursprungsmitteilung
Thema Problem mit delay() 
Autor Paul Mo 
Eingangsdatum 2019-10-09 09:58:23.0 
Mitteilung Lieber Herr Plüss,

ich verzweifle gerade an der Methode delay(), sie macht einfach nicht das, was ich will: In einem Spiel soll es ganz einfach darum gehen, fallendes Obst mit einer Schüssel aufzufangen. Wenn ein Obst gefangen ist, sollen zwei weitere Obst-Objekte initialisiert werden ? so weit kein Problem.

Wenn ich aber die Obstobjekte mit einer Verzögerung (delay(zufallszahl)) auftauchen lassen will, dann funktioniert das beim ersten Objekt am Spielanfang, sobald das aber gefangen ist und zwei weitere initialisiert werden, stoppt delay() alle (Actor?-)Objekte des Spiels. Zudem ist die Zufallszahl für beide neuen Objekte dieselbe. Vielleicht hat es etwas mit den Threads zu tun? Können Sie mir bitte weiterhelfen?

Beste Grüße,
Paul Mo

--------------

import ch.aplu.jgamegrid.*;
import java.util.concurrent.ThreadLocalRandom;

public class Obst extends Actor implements GGActorCollisionListener {

/*---------*/
/*Attribute*/
/*---------*/

//Verweis auf die GameGrid-Klasse
private Fallobst spielmechanik;
//sorgt dafür, dass die act()-Methode nur ausgeführt wird, wenn das Objekt fallen soll
private boolean aktiv;

/*--------*/
/*Methoden*/
/*--------*/

//KONSTRUKTOR
public Obst(Fallobst f) {
super("img/apple.gif");
spielmechanik = f;
aktiv = false;
}

//Hier wird das Fallen initialisiert
public void fallen() {
//hide();
setDirection(90);
//Ausrichtung an einer horizontalen Zufallsposition
setX(ThreadLocalRandom.current().nextInt(50, Fallobst.BREITE-49));


delay(ThreadLocalRandom.current().nextInt(0, 3000)); //PROBLEMATISCHER BEFEHL


//show();
aktiv = true;
}

//Fallschleife
public void act() {
if (aktiv) {
move(1);
if(getY() >= Fallobst.HOEHE) {
//wenn der Apfel den unteren Spielfeldrand berührt
removeSelf();
spielmechanik.gameOver();
}
}
}

//Wenn das Obst die Schüssel berührt
public int collide(Actor actor1, Actor actor2) {
removeSelf();
//aktiv = false;
spielmechanik.gefangen();
return 10;
}
}

-------------------
und hier noch der Auszug aus der GameGrid-Klasse
-------------------

//wenn ein neues Obst dem Spiel hinzugefügt werden soll
public void obstHinzufuegen() {
Obst obst = new Obst(this);
//obst.hide();
//Bandelt die Kollisionserkennung an
obst.addCollisionActor(schuessel);
obst.addActorCollisionListener(obst);
//Fügt das Fallobst dem Spiel hinzu
addActor(obst, new Location(0,0));
obst.fallen();
}

//Wenn ein Obst von der Schüssel berührt wird:
public void gefangen() {
punkte++;
punkteanzeige.setText(String.valueOf(punkte));
obstHinzufuegen();
obstHinzufuegen();
 
      
Antworten
Thema Threads 
Autor Paul Mo 
Eingangsdatum 2019-10-11 11:43:41.0 
Mitteilung Ich habe das Problem jetzt so gelöst, dass ich statt delay() einfach den LoResTimer bemüht habe. Dadurch ist es zwar nicht mehr so objektorientiert, wie ich mir das erhofft hatte, aber es funktioniert.

Beste Grüße,
Paul Mo 
 
Thema Verwendung von delay() 
Autor Aegidius Plüss 
Eingangsdatum 2019-10-12 09:12:04.0 
Mitteilung Guten Tag,

In JGameGrid ist die Verwendung von delay() sehr problematisch, da die act() der Aktoren in einem internen Timerthread periodisch aufgerufen werden und damit kooperieren. Beim Aufruf von delay() wird aber das ganze System abgebremst. Wenn irgend ein act() nicht rechtzeitig zurückkehrt, verhält sich das ganze Spiel sehr schlecht. Um einen Actor zu verlangsamen, muss man beispielsweise Actor.setSlowDown() verwenden oder mit einem Zähler einfach nur in allen n-Aufrufen von act() tatsächlich etwas machen.

Die Verwendung von LoResTimer ist da schon besser, da dieser in sofort zurückkehrt.

Also grundsätzlich: In JGameGrid keine Methoden verwenden, die nicht sofort zurückkehren.

MfG und viel Spass. 
 
Thema Problem mit delay() 
Autor Paul Mo 
Eingangsdatum 2019-10-15 10:55:52.0 
Mitteilung Vielen Dank für die Erklärung. Ich hatte mir schon gedacht, dass irgendwo der falsche Thread ausgebremst wird, bin aber froh, dass es so besser funktioniert.

Gruß,
Paul Mo