Visualizzazione dei risultati da 1 a 2 su 2
  1. #1

    Movimento in frame utilizzando Thread

    Salve, forse questa non è la sezione giusta non so, sono un programmatore principiante e per passare il tempo durante la quarantena ho deciso di provare a fare un miniprogetto con i thread (per capirli meglio) dove andavo a disegnare con il paint i 4 fantasmini di pacman, facendoli muovere random. Sembra funzionare ma non so come risolvere il problema causato dal continuo disegnare senza pulire la finestra. Ho letto di un repaint ma non so proprio dove e come metterlo.
    Se qualcuno mi potesse aiutare gliene sarei veramente grato. Di seguito il codice:

    codice:
    import java.awt.image.*;
    import javax.imageio.*;
    import java.io.*;
    public class Carica_immagini
    {
        BufferedImage image;
        public BufferedImage carica(String percorso){
         
         try{
          image = ImageIO.read(getClass().getResource(percorso));//carica immagine da percorso
          System.out.println("Immagine caricata"); 
         }catch(IOException e){}
         
         return image;
        }
    }
    
    
    import javax.swing.*;
    import java.awt.*; 
    import java.awt.image.*;
    import javax.imageio.*;
    import java.awt.event.*;
    /*
     * Implementare Runnable o estendere Thread è quasi la stessa cosa solo che implementando l'interfaccia
     * devo creare un oggetto Thread a cui passo come parametro l' oggetto della classe che implementa l'interfaccia (ultime 2 righe del main)
     * Estendere la classe  Thread invece non richiede la creazione di un oggetto ma posso
     * chiamare direttamente il metodo .start()
     */
    public class Finestra extends Canvas implements Runnable  // canvas rende possibile disegnare
    {
      private static final int larghezza = 1280;
      private static final int altezza = 720;
      private static String nome = "Pacman";
      private Ghost blinky,inky,pinky,clyde;
      private int x_ghost,y_ghost;
    
      private BufferedImage ghost1,ghost2,ghost3,ghost4,ghost5,ghost6,ghost7,ghost8;
      private BufferedImage ghost9,ghost10,ghost11,ghost12,ghost13,ghost14,ghost15,ghost16;
      
      private boolean giocoAttivo = false;//per vedere se il thread è attivo
      
      public  Finestra(){
       carica_risorse();
       inizia_gioco();
      }
      
      public static void main(String args[]){
        Finestra game = new Finestra();   //qui verrà disegnato tutto
        Dimension dim = new Dimension();
        JFrame finestra = new JFrame(nome);
        
        finestra.setSize(larghezza,altezza);
        finestra.setPreferredSize(dim);
        finestra.setMaximumSize(dim);
        finestra.setBackground(Color.WHITE);
        finestra.setResizable(false);
        
        finestra.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        finestra.add(game);
        
        finestra.setVisible(true);
        
        Thread thread_game = new Thread(game); // creazione thread
        thread_game.start(); //questístruzione mette il thread in una coda e quando arriva il turno viene eseguito
      }
      private void inizia_gioco(){
       blinky = new Ghost(ghost1,ghost2,ghost3,ghost4,25,25,100,100);
       pinky = new Ghost(ghost5,ghost6,ghost7,ghost8,25,25,1200,100);
       inky = new Ghost(ghost9,ghost10,ghost11,ghost12,25,25,100,500);
       clyde = new Ghost(ghost13,ghost14,ghost15,ghost16,25,25,1200,500);
       blinky.start();
       pinky.start();
       inky.start();
       clyde.start();
      }
      //utilizzato per caricare tutte le risorse necessarie all'app
      private void carica_risorse(){
        Carica_immagini loader = new Carica_immagini();
        
        ghost1 = loader.carica("/Immagini/blinky_1.png");
        ghost2 = loader.carica("/Immagini/blinky_2.png");
        ghost3 = loader.carica("/Immagini/blinky_3.png");
        ghost4 = loader.carica("/Immagini/blinky_4.png");
        
        ghost5 = loader.carica("/Immagini/pinky_1.png");
        ghost6 = loader.carica("/Immagini/pinky_2.png");
        ghost7 = loader.carica("/Immagini/pinky_3.png");
        ghost8 = loader.carica("/Immagini/pinky_4.png");
        
        ghost9 = loader.carica("/Immagini/inky_1.png");
        ghost10 = loader.carica("/Immagini/inky_2.png");
        ghost11 = loader.carica("/Immagini/inky_3.png");
        ghost12 = loader.carica("/Immagini/inky_4.png");
        
        ghost13 = loader.carica("/Immagini/clyde_1.png");
        ghost14 = loader.carica("/Immagini/clyde_2.png");
        ghost15 = loader.carica("/Immagini/clyde_3.png");
        ghost16 = loader.carica("/Immagini/clyde_4.png");
      }
      //metodo per disegnare nella finestra
      private void disegna(){
       BufferStrategy buffer = this.getBufferStrategy();
       if(buffer == null){
        createBufferStrategy(2);
        return;
       }
       Graphics g = buffer.getDrawGraphics(); // Quest' istruzione è per dire che è un oggetto
       //Canvas sul quale si può disegnare
       
       blinky.paint(g);//chiamo il metodo per disegnare blinky
       pinky.paint(g);
       inky.paint(g);
       clyde.paint(g);
       g.dispose();
       buffer.show();
      }
      /*
      Run è il metodo eseguito dai Thread
      */
      public void run(){
        giocoAttivo = true;
        while(giocoAttivo){     
            disegna();  //carica sempre
        }
      }
    }
    
    
     import javax.swing.*;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.awt.Graphics;
    import java.util.Timer;
    import java.util.TimerTask;
    
    public class Ghost extends Thread
    {
       private int larghezza;
       private int altezza;
       private int direzione;
       private boolean attivo; //per thread
       private int x;   //per posizione del fantasma
       private int y;
       private BufferedImage image1,image2,image3,image4;
      public Ghost(BufferedImage image1,BufferedImage image2,BufferedImage image3,BufferedImage image4,int larghezza,int altezza,int x,int y){
       this.x = x;
       this.y = y;
       this.larghezza = larghezza;
       this.altezza = altezza;
       this.image1 = image1;
       this.image2 = image2;
       this.image3 = image3;
       this.image4 = image4;
      }
      @Override
      public void run(){
       attivo = true;
       direzione = genera();
       while(attivo)
       {
        aggiorna();
        try{
         Thread.sleep(25);  //si ferma per 25 millisecondi
        }catch(InterruptedException e){}
       }
      }
      //qui il fastasma si sposta
      private void aggiorna(){ 
        
        switch(direzione){
        case 1:if(x<1280)
               x++;             //destra 
               break;
        case 2:if(y<720)
               y++;              //giù       
               break;
        case 3:if(x>0)
               x--;             //sinistra
               break;
        case 4:if(y>0)
               y--;             //su
               break;
               
        default:break;
        }
      }
      
      public int genera(){
           Timer timer = new Timer();
           timer.scheduleAtFixedRate(new TimerTask() {
               @Override
               public void run() {
                   direzione=(int)(Math.random()*4)+1;
               }
           },0, 6000);
           return direzione;
      }
      
      public void paint(Graphics g){
        switch(direzione){
        case 1: g.drawImage(image1,x,y,larghezza,altezza,null);    
                break;
        case 2: g.drawImage(image2,x,y,larghezza,altezza,null);    
                break;
        case 3: g.drawImage(image3,x,y,larghezza,altezza,null);    
                break;   
        case 4: g.drawImage(image4,x,y,larghezza,altezza,null);    
                break; 
        default:break;
       }   
           
      }
    }
    Ultima modifica di LeleFT; 12-06-2020 a 12:49 Motivo: Aggiunti i tag CODE

  2. #2
    Utente di HTML.it L'avatar di linoma
    Registrato dal
    Mar 2010
    Messaggi
    1,292
    ... piuttosto che evento repaint cercherei di implementare qualcosa di double buffer o v-sync. Cerca di rendere leggibile il codice
    Per gli Spartani e Sparta usa spartan

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2020 vBulletin Solutions, Inc. All rights reserved.