Ho scritto un giochino in java che consiste nel correre e saltare su alcuni "piani" orizzontali in movimento. Il gioco funziona perfettamente ma vorrei che dopo il "game over" la partita ricominciasse.
Ho provato a risolvere così ma l'istruzione
this.init(30);
nel metodo run() della classe mi da la seguente eccezione
Exception in thread "Timer-0" java.lang.IllegalStateException: Task already scheduled or cancelled
at java.util.Timer.sched(Timer.java:401)
at java.util.Timer.schedule(Timer.java:248)
at JOGL.games.Personaggio.init(Personaggio.java:78)
at JOGL.games.Personaggio.run(Personaggio.java:183)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)
Come posso risolvere? Ci sono altri tipi di timer più adatti?
classe che gestisce il personaggio e il movimento
package JOGL.games;
import java.awt.Canvas;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.LinkedList;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JOptionPane;
public class Personaggio extends TimerTask implements KeyListener {
LinkedList<Layer> layers;
int movimento;
int xpos, ypos;
long zpos;
final int gravita = 1, salto = 25, sLaterale = 20;
int forzay, forzax;
Timer t;
Canvas canvas;
final int numLayer = 30;
long maxZLayer;
int numLayerDist;
boolean[][] matrix;
Random random;
public Personaggio(Canvas canvas) {
random = new Random();
t = new Timer();
this.canvas = canvas;
}
public synchronized void init(long framerate) {
matrix = new boolean[10][50];
xpos = 0;
ypos = 0;
zpos = 1;
forzax = 0;
forzay = 0;
numLayerDist = 0;
this.layers = new LinkedList<Layer>();
layers.add(new Layer(xpos - 100, xpos + 100, zpos - 1, zpos + 500));
maxZLayer = (int) (zpos + 500);
for (int i = 0; i < numLayer; i++) {
long a, b, c, d;
a = abs(random.nextInt(650)) - 450;
b = abs(random.nextInt(200)) + 50;
c = abs((long) random.nextInt(80)) + maxZLayer;
d = abs(random.nextInt(500)) + 200;
layers.add(new Layer(a, a + b, c, c + d));
maxZLayer = c + d;
}
t.schedule(this, 0, 1000 / framerate);
}
public void stop() {
this.cancel();
t.purge();
}
public synchronized void keyTyped(KeyEvent e) {
}
public synchronized void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 37) { //sinistra
movimento = 1;
} else if (e.getKeyCode() == 39) { //destra
movimento = 2;
} else if (e.getKeyCode() == 38) { //sopra
movimento = 3;
}
}
public synchronized void keyReleased(KeyEvent e) {
movimento = -1;
}
@Override
public synchronized void run() {
if (movimento == 1 && xpos > -400) {
forzax = -sLaterale;
System.out.println("sinistra");
} else if (movimento == 2 && ypos <= 400) {
forzax = sLaterale;
System.out.println("destra");
} else if (movimento == 3 && (ypos == 0 || (forzay>0 && ypos<400))) {
forzay = salto;
System.out.println("salto");
} else if (movimento == -1) {
forzax = 0;
}
if (forzax != 0 && xpos >= -400 && xpos <= 400) {
xpos += forzax;
if (xpos < -400) {
xpos = -400;
}
if (xpos > 400) {
xpos = 400;
}
}
if (ypos >= 0) {
forzay -= gravita;
ypos += (forzay);
if (ypos < 0) {
ypos = 0;
forzay = 0;
}
}
boolean isOnLayer = false;
if(ypos!=0){
isOnLayer = true;
}
synchronized (layers) {
Layer layerToRemove = null;
for (Layer l : layers) {
if (l.translate(0, -2, zpos)) {
layerToRemove = l;
System.out.println("Elimino un piano");
}
}
if(layerToRemove!=null){
layers.remove(layerToRemove);
numLayerDist++;
long a, b, c, d;
a = abs(random.nextInt(650)) - 450;
b = abs(random.nextInt(200)) + 50;
c = abs((long) random.nextInt(80)) + maxZLayer;
d = abs(random.nextInt(500)) + 200;
layers.add(new Layer(a, a + b, c, c + d));
}
if(!isOnLayer){
for (Layer l : layers){
if (l.isIn(xpos, zpos)) {
isOnLayer = true;
break;
}
}
}
}
if (!isOnLayer) {
this.stop();
JOptionPane.showMessageDialog(canvas, "Hai superato "+numLayerDist+" layers!");
this.init(30);
System.err.println("Sto' cadendo");
}
System.out.println("xpos="+xpos);
System.out.println("ypos="+ypos);
movimento = 0;
}
static long abs(long x){
return (x>0) ? x : -x;
}
}