Ripetizione TimerTask in un Timer

di il
3 risposte

Ripetizione TimerTask in un Timer

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

  • Re: Ripetizione TimerTask in un Timer

    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;
        }
    
    }
    
  • Re: Ripetizione TimerTask in un Timer

    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?!
  • Re: Ripetizione TimerTask in un Timer

    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