Ripetizione TimerTask in un Timer

di Anonimizzato13826 il
3 risposte
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;
    }

}

3 Risposte

  • Codice aggiornato, ma il problema rimane identico
    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 = 15;
        int forzay, forzax;
    
        Timer t;
    
        Canvas canvas;
    
        final int numLayer = 35;
        long maxZLayer;
        int numLayerDist;
    
        static Random random;
    
        public Personaggio(Canvas canvas) {
            random = new Random();
            t = new Timer();
            this.canvas = canvas;
        }
    
        public synchronized void init(long framerate) {
            xpos = 0;
            ypos = 100;
            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, 0));
    
            maxZLayer = (int) (zpos + 500);
    
            for (int i = 0; i < numLayer; i++) {
                long a, b, c, d, e;
                a = abs(random.nextInt(650)) - 450;
                b = abs(random.nextInt(200)) + 50;
                c = abs((long) random.nextInt(400)) - 300 + maxZLayer;
                d = abs(random.nextInt(500)) + 200;
                e = abs(random.nextInt(200) - 100);
    
                //System.out.println("Nuovo layer   y="+e);
                layers.add(new Layer(a, a + b, c, c + d, e));
    
                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;
                //System.out.println("Sinistra clicked");
            } else if (e.getKeyCode() == 39) {     //destra
                movimento = 2;
                //System.out.println("Destra clicked");
            } else if (e.getKeyCode() == 38) {      //sopra
                movimento = 3;
                //System.out.println("Salto clicked");
            }
        }
    
        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 && xpos <= 400) {
                forzax = sLaterale;
                //System.out.println("destra");
            } else if (movimento == 3) {
                boolean test = false;
                for (Layer l : layers) {
                    if (l.isIn(xpos, ypos, zpos)) {
                        test = true;
                        break;
                    }
                }
                
                if(test)
                    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;
                }
            }
    
            forzay -= gravita;
    
            if (forzay < -30) {
                forzay = -30;
            }
    
            /*System.out.println("Forza y="+forzay);
             System.out.println("ypos="+ypos);*/
            long unit = (forzay > 0) ? 1 : -1;
            boolean conti = true;
    
            if (forzay > 0) {
                ypos++;
            }
    
            for (long ytg = 0; ytg < abs(forzay) && conti == true; ytg++) {
                //System.out.println("ytg="+ytg);
                for (Layer l : layers) {
                    //System.out.println("Layer "+l.toString()+" y="+l.ypos);
                    if (l.isIn(xpos, ypos, zpos)) {
                        //System.out.println("IsIn=true");
                        conti = false;
                        break;
                    }
                }
    
                if (conti) {
                    ypos += unit;
                }
            }
    
            if (ypos < -200) {
                this.stop();
                JOptionPane.showMessageDialog(canvas, "Hai superato "+numLayerDist+" layers!");
                this.init(40);
                System.err.println("Sto' cadendo");
            }
    
            synchronized (layers) {
                Layer layerToRemove = null;
    
                for (Layer l : layers) {
                    if (l.translate(0, 0, -2 + (numLayerDist / 20), zpos)) {
                        layerToRemove = l;
                        System.out.println("Elimino un piano");
                    }
                }
    
                maxZLayer -= (-2 + (numLayerDist / 20));
    
                if (layerToRemove != null) {
                    layers.remove(layerToRemove);
                    numLayerDist++;
    
                    long a, b, c, d, e;
                    a = abs(random.nextInt(650)) - 450;
                    b = abs(random.nextInt(200)) + 50;
                    c = abs((long) random.nextInt(400)) - 300 + maxZLayer;
                    d = abs(random.nextInt(500)) + 200;
                    e = abs(random.nextInt(200) - 100);
    
                    System.out.println("Nuovo layer   y=" + e);
    
                    layers.add(new Layer(a, a + b, c, c + d, e));
                }
    
            }
    
            /*System.out.println("xpos="+xpos);
             System.out.println("ypos="+ypos);*/
            movimento = 0;
        }
    
        static long abs(long x) {
            return (x > 0) ? x : -x;
        }
    
    }
    
  • Ciao,
    io ho fatto un applicazione per monitorare i movimenti in una stanza con una webcam.
    tutta questa app l ho inserita in un thread che viene lanciata dal main che in loop, rimane in attesa della risposta e nel caso, la resetta.
    potrebbe essere una cosa simile?!
  • Si potrebbe...

    Non ho più questo problema perché poi ho optato per una nuova classe istanziata ad ogni partita. Cmq sarebbe un dubbio che mi piacerebbe risolvere...
Devi accedere o registrarti per scrivere nel forum
3 risposte