Afficher des images avec double-buffering [Résolu]

Messages postés
37
Date d'inscription
vendredi 14 mars 2008
Dernière intervention
27 mai 2013
- - Dernière réponse : deli2025
Messages postés
37
Date d'inscription
vendredi 14 mars 2008
Dernière intervention
27 mai 2013
- 12 nov. 2012 à 00:26
Bonjour,

je suis entrain de créer une plateforme en 2D isométrique et je rencontre quelques problème pour afficher la map.

Pour commencer, j'avais créer une class qui héritait de JPanel et je dessinais dessus avec paintComponent. Cela fonctionnait très bien, jusqu’au moment ou j'ai voulu déplacer cette map... (Il y avait des écarts entre mes cases...)

Après avoir effectuer quelques recherches, la solution parait être le double-buffering hardware. J'ai donc voulu adapter ma class JPanel mais je n'y suis pas arrivé et tous les exemples que j'ai trouvé, héritait non pas de JPanel mais de JFrame.

J'ai donc créer une nouvelle Class JFrame pour faire des testes et effectivement le problème est résolu mais un autre est apparu... Maintenant, quand je déplace la map, je vois toujours son ancienne position !



Je souhaiterais donc avoir votre avis sur la bonne manière de procéder... Sachant que j'aurais préférer avoir une Class scene héritant de JPanel e contenant le desin de la map...

Mais je galère ;) (Je débute en Java et en orienté object)

Merci d'avance pour votre aide !

PS: je vous joins les Class et n'hésitez pas à me conseiller sur le reste aussi ;)

Ma nouvelle Class héritant de JFrame
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package game;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;

/**
 *
 * @author D3L1
 */
public class Game extends JFrame implements MouseListener, MouseMotionListener, KeyListener
{
    private Map map;
    
    // boucle d'affichage
    RafraichissementThread rafraichissement = new RafraichissementThread(); 
    // variable permettant d'utiliser la mémoire VRAM
    BufferStrategy strategy; 
    // buffer mémoire où les images et les textes sont appliqués
    Graphics buffer; 
  

    
    public Game()
    {
        creerFenetre();
        
        map = new Map();

        this.addMouseListener(this);
        this.addMouseMotionListener(this);
        this.addKeyListener(this);

        createBufferStrategy(2); 

        strategy =getBufferStrategy();
        
        buffer =strategy.getDrawGraphics();
        
        rafraichissement.start();

        Thread deplacementMap = new Thread(map);
        deplacementMap.start();
    }
    
    private void creerFenetre()
    {
        this.setTitle("Mon Jeu");
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setSize(1024, 600);
        this.setLocationRelativeTo(null);
        this.setBackground(Color.DARK_GRAY);
        this.setIgnoreRepaint(true);
        this.setVisible(true);
    }
    
    public class RafraichissementThread extends Thread
    {
        @Override
        public void run()
        {
            while(true)
            {
                try  
                {
                    graphicalRender();
                    this.sleep( 5);
                   
                } 
                catch( Exception e){}
            }
        }
    }

    
    public void graphicalRender()
    {
        for(int x = 0; x < Constantes.LARGEUR_MAP; x++)
        {
            for(int y = 0; y < Constantes.HAUTEUR_MAP; y++)
            {
                Point coordonneeEcran = new Point(0, 0);

                coordonneeEcran.x = ((x - y) * Constantes.LARGEUR_DEMI_TILE) - map.getMap()[x][y].getDemiWidth();
                coordonneeEcran.y = ((x + y) * Constantes.HAUTEUR_DEMI_TILE) - map.getMap()[x][y].getHeight();
                
                buffer.drawImage(map.getMap()[x][y].getImage(), coordonneeEcran.x + Constantes.POSITION_DEPART_X, coordonneeEcran.y + Constantes.POSITION_DEPART_Y, this);
            }
        }
        
        strategy.show(); 
    }
    
    @Override
    public void mouseClicked(MouseEvent e) 
    {
        Constantes.Mx = e.getX();
        Constantes.My = e.getY(); 
        
        System.out.println(map.coordEcranEnCoordTile());

        System.out.println(map.infoTile());
    } 

    @Override
    public void mouseReleased(MouseEvent e){}
    
    @Override
    public void mousePressed(MouseEvent e)
    {
        Constantes.Mx = e.getX();
        Constantes.My = e.getY(); 
    }
    
    @Override
    public void mouseMoved(MouseEvent e){}
   
    @Override
    public void mouseExited(MouseEvent e){}

    @Override
    public void mouseEntered(MouseEvent e){}

    @Override
    public void mouseDragged(MouseEvent e)
    {
        Constantes.Mx = e.getX();
        Constantes.My = e.getY(); 
        map.getMap()[map.coordEcranEnCoordTile().x][map.coordEcranEnCoordTile().y] = map.herbe;
 
    } 

    @Override
    public void keyTyped(KeyEvent e) {}

    @Override
    public void keyPressed(KeyEvent e) 
    {
        int KeyCode = e.getKeyCode();

        switch(KeyCode)
        {
            case KeyEvent.VK_UP: map.KeyPressed(e);
                break;
            case KeyEvent.VK_DOWN: map.KeyPressed(e);
                break;
            case KeyEvent.VK_LEFT: map.KeyPressed(e);
                break;
            case KeyEvent.VK_RIGHT: map.KeyPressed(e);
                break;
        }
    }

    @Override
    public void keyReleased(KeyEvent e) 
    {
        int KeyCode = e.getKeyCode();

        switch(KeyCode)
        {
            case KeyEvent.VK_UP: map.KeyRelease(e);
                break;
            case KeyEvent.VK_DOWN: map.KeyRelease(e);
                break;
            case KeyEvent.VK_LEFT: map.KeyRelease(e);
                break;
            case KeyEvent.VK_RIGHT: map.KeyRelease(e);
                break;
        }
    }
}



Mon ancienne Class héritant de JPanel
package game;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JPanel;
import javax.swing.Timer;


/**
 *
 * @author D3L1
 */
public class Scene extends JPanel implements MouseListener, MouseMotionListener, KeyListener, ActionListener
{
    public Map map;
    Timer temps;
    
    
    RenderingThread renderingThread = new RenderingThread();
    Graphics buffer;
    Image image;

    
    public Scene()
    {
        map = new Map();
        
        this.setLayout(null);
        this.setFocusable(true);
    
        /*
         * Ajoute les listener sur le JPanel
         */
        this.addMouseListener(this);
        this.addMouseMotionListener(this);
        this.addKeyListener(this);
        
        
        Thread deplacementMap = new Thread(map);
        deplacementMap.start();
        
        temps = new Timer(0, this);
        temps.start();  
    }
    
    /*
     * Dessine la map
     */
    @Override
    public void paintComponent(Graphics g)
    {   
       super.paintComponent(g);
       
       image = createImage(1024,600);
       
       buffer = image.getGraphics();
        
        for(int x = 0; x < Constantes.LARGEUR_MAP; x++)
        {
            for(int y = 0; y < Constantes.HAUTEUR_MAP; y++)
            {
                Point coordonneeEcran = new Point(0, 0);

                coordonneeEcran.x = ((x - y) * Constantes.LARGEUR_DEMI_TILE) - map.getMap()[x][y].getDemiWidth();
                coordonneeEcran.y = ((x + y) * Constantes.HAUTEUR_DEMI_TILE) - map.getMap()[x][y].getHeight();
                
                buffer.drawImage(map.getMap()[x][y].getImage(), coordonneeEcran.x + Constantes.POSITION_DEPART_X, coordonneeEcran.y + Constantes.POSITION_DEPART_Y, this);
            }
        } 
        
        g.drawImage(image, 0, 0, this);
    }
    
    @Override
    public void mouseClicked(MouseEvent e) 
    {
        Constantes.Mx = e.getX();
        Constantes.My = e.getY(); 
        
        System.out.println(map.coordEcranEnCoordTile());

        System.out.println(map.infoTile());
    } 

    @Override
    public void mouseReleased(MouseEvent e){}
    
    @Override
    public void mousePressed(MouseEvent e)
    {
        Constantes.Mx = e.getX();
        Constantes.My = e.getY(); 
    }
    
    @Override
    public void mouseMoved(MouseEvent e){}
   
    @Override
    public void mouseExited(MouseEvent e){}

    @Override
    public void mouseEntered(MouseEvent e){}

    @Override
    public void mouseDragged(MouseEvent e)
    {
        Constantes.Mx = e.getX();
        Constantes.My = e.getY(); 
        map.getMap()[map.coordEcranEnCoordTile().x][map.coordEcranEnCoordTile().y] = map.herbe;
        repaint();
    } 

    @Override
    public void keyTyped(KeyEvent e) {}

    @Override
    public void keyPressed(KeyEvent e) 
    {
        int KeyCode = e.getKeyCode();

        switch(KeyCode)
        {
            case KeyEvent.VK_UP: map.KeyPressed(e);
                break;
            case KeyEvent.VK_DOWN: map.KeyPressed(e);
                break;
            case KeyEvent.VK_LEFT: map.KeyPressed(e);
                break;
            case KeyEvent.VK_RIGHT: map.KeyPressed(e);
                break;
        }
    }

    @Override
    public void keyReleased(KeyEvent e) 
    {
        int KeyCode = e.getKeyCode();

        switch(KeyCode)
        {
            case KeyEvent.VK_UP: map.KeyRelease(e);
                break;
            case KeyEvent.VK_DOWN: map.KeyRelease(e);
                break;
            case KeyEvent.VK_LEFT: map.KeyRelease(e);
                break;
            case KeyEvent.VK_RIGHT: map.KeyRelease(e);
                break;
        }
    } 

    @Override
    public void actionPerformed(ActionEvent e) 
    {
        repaint();  
    }
}        
  


Et ma Class map au cas ou ^^
package game;

import java.awt.Point;
import java.awt.event.KeyEvent;
import java.io.File;
import java.util.Scanner;
import tiles.*;


/**
 *
 * @author D3L1
 */
public final class Map implements Runnable
{
    public final static Tile[][] mapTile = new Tile[Constantes.LARGEUR_MAP][Constantes.HAUTEUR_MAP];
    private final static String[] mapLettre = new String[Constantes.LARGEUR_MAP * Constantes.HAUTEUR_MAP];
    private Scanner fichierMap;

    int xDirection;
    int yDirection;

    /*
     * On défini les tiles constituant la map
     */
    public Eau eau = new Eau();
    public Herbe herbe = new Herbe();
    public Pave pave = new Pave();
    public Arbre arbre = new Arbre();
    public Terre terre = new Terre();
    public Bat batiment = new Bat();
    
    /*
     * Constructeur
     */
    public Map()
    {
        this.ouvrirFichierMap();
        this.lireFichierMap();
        this.fermerFichierMap();
    }
    
    /*
     * Ouvre le fichier
     */
    public void ouvrirFichierMap()
    {
        try
        {
            fichierMap = new Scanner(new File(Constantes.dossierMap));
        }
        catch(Exception e)
        {
            System.out.println("Erreur pendant le chargement de la map.");
        }
    }
    
    /*
     * Lit le fichier et constitue la map
     */
    public void lireFichierMap()
    {
        int j = 0;
        
        for(int x = 0; x < Constantes.LARGEUR_MAP ; x++)
        {
            for(int y = 0; y < Constantes.HAUTEUR_MAP ; y++)
            {
                mapLettre[j] = fichierMap.next();

                String index = mapLettre[j].substring(j, j + 1);
                
                switch(index)
                {
                    case "A": mapTile[x][y] = arbre;
                        break;
                    case "B": mapTile[x][y] = batiment;
                        break;
                    case "E": mapTile[x][y] = eau;
                        break;
                    case "H": mapTile[x][y] = herbe;
                        break;
                    case "P": mapTile[x][y] = pave;
                        break;
                    case "T": mapTile[x][y] = terre;
                        break;
                    default: mapTile[x][y] = herbe;;
                }
            }
        }
    }
    
    /*
     * Ferme le fichier
     */
    public void fermerFichierMap()
    {
        fichierMap.close();
    }
    
    /*
     * Envoi la map
     */
    public Tile[][] getMap()
    {
        return mapTile;
    }
    
    /*
     * ToString de Tile
     */
    public String infoTile()
    {
        return this.getMap()[coordEcranEnCoordTile().x][coordEcranEnCoordTile().y].toString();    
    }
    
    /*
     * Transforme une position écran en position d'une tile
     */
    public Point coordEcranEnCoordTile()
    {
        float x =  Constantes.Mx - Constantes.POSITION_DEPART_X;
        float y =  Constantes.My - Constantes.POSITION_DEPART_Y;
 
        Point position = new Point();
 
        position.x = (int)((float)Math.floor((y / Constantes.HAUTEUR_TILE) + (x / Constantes.LARGEUR_TILE +1)));
        // Math.floor : Arrondi à l'entier inférieur | +1 : 
            
        position.y = (int)((float)(int)Math.ceil((y / Constantes.HAUTEUR_TILE) - (x / Constantes.LARGEUR_TILE))); 
        // Math.ceil : Arrondi à l'entier supérieur
            
        return position;
    }
    
    /*
     * Main de test
     */
    public static void main(String[] args)
    {
        Map map = new Map();
        map.getMap();
        System.out.println(map.infoTile());
    }

    public void deplacement()
    {
        Constantes.POSITION_DEPART_X += xDirection;
        Constantes.POSITION_DEPART_Y += yDirection;
    }
    
    public void setDirectionX(int dX)
    {
        xDirection = dX;
    }
    
    public void setDirectionY(int dY)
    {
        yDirection = dY;
    }
    
    public void KeyPressed(KeyEvent e)
    {
        int KeyCode = e.getKeyCode();

        switch(KeyCode)
        {
            case KeyEvent.VK_UP: setDirectionY(+2);
                break;
            case KeyEvent.VK_DOWN: setDirectionY(-2);
                break;
            case KeyEvent.VK_LEFT: setDirectionX(+2);
                break;
            case KeyEvent.VK_RIGHT: setDirectionX(-2);
                break;
        }
    }
    
    public void KeyRelease(KeyEvent e)
    {
        int KeyCode = e.getKeyCode();

        switch(KeyCode)
        {
            case KeyEvent.VK_UP: setDirectionY(0);
                break;
            case KeyEvent.VK_DOWN: setDirectionY(0);
                break;
            case KeyEvent.VK_LEFT: setDirectionX(0);
                break;
            case KeyEvent.VK_RIGHT: setDirectionX(0);;
                break;
        }
    }
    
    @Override
    public void run()
    {
        try
        {
            while(true)
            {
                deplacement();
                Thread.sleep(5);
            }
        }
        catch(Exception e)
        {
            System.out.println(e.getMessage());
        }
    }
}

Afficher la suite 

Votre réponse

4 réponses

Meilleure réponse
Messages postés
37
Date d'inscription
vendredi 14 mars 2008
Dernière intervention
27 mai 2013
3
Merci
Bon... avant de redessiner la map, je dessine un rectangle de fond et la plus de trace de la map mais le problème que j'avais avec JPanel est de nouveau présent (écart entre les tiles quand je déplace la map)...


Je vois pas ce que je peux faire...

Dire « Merci » 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources 96 internautes nous ont dit merci ce mois-ci

Commenter la réponse de deli2025
0
Merci
Bonsoir

Je n'ai rien trouvé mais je pense que si vous posez votre question sur Java-Gaming, vous aurez très rapidement une réponse. J'utilise peu Java2D pour les jeux bien que ce soit tout à fait possible. Je pense que vous utilisez mal la BufferStrategy et une instance de java.awt.Canvas suffirait pour dessiner tout ça, libre à vous de la mettre dans un JPanel par la suite. Jetez un coup d'oeil ici et ici.















T.U.E.R (First Person Shooter créé par Julien Gouesse)
Commenter la réponse de Utilisateur anonyme
Messages postés
37
Date d'inscription
vendredi 14 mars 2008
Dernière intervention
27 mai 2013
0
Merci
Merci pour ta réponse.

Sinon j'ai utilisé BufferStrategy comme l'exemple montré dans les FAQ de ce site...

Je vais allé voir un peu sur java-gaming mais mon anglais risque de me poser problème ^^
Commenter la réponse de deli2025
Messages postés
37
Date d'inscription
vendredi 14 mars 2008
Dernière intervention
27 mai 2013
0
Merci
... Je viens de le faire avec Canvas plutôt qu'un JPanel mais toujours le même problème, on voit encore l'ancienne position de la map. Il y aurait t'il moyen d'éffacer le canvas avant de redessiner dessus ?

package game;

import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;


/**
 *
 * @author D3L1
 */
public class GameCanvas extends Canvas implements Runnable, MouseListener, MouseMotionListener, KeyListener
{
    private BufferedImage image = new BufferedImage(Constantes.LARGEUR_MAP, Constantes.HAUTEUR_MAP, BufferedImage.TYPE_INT_RGB);
    private BufferStrategy bufferStrategy;
    private boolean running = false;

    
    private Map map;

    public GameCanvas()
    {
        map = new Map();
        
        this.addMouseListener(this);
        this.addMouseMotionListener(this);
        this.addKeyListener(this);

        Thread deplacementMap = new Thread(map);
        deplacementMap.start();
    }
    
    private void start()
    {
        running = true;
        new Thread(this).start();
    }
    
    @Override
    public void run()
    {
        while(running)
        {
            render();
        }
    }
    
    public void stop()
    {
        running = false;
    }
    
    /*
     * Dessine la map
     */
    public void render()
    {
        bufferStrategy = getBufferStrategy();
        
        if(bufferStrategy == null)
        {
            createBufferStrategy(3);
            requestFocus();
            return;
        }
        
        Graphics g = bufferStrategy.getDrawGraphics();
        
        for(int x = 0; x < Constantes.LARGEUR_MAP; x++)
        {
            for(int y = 0; y < Constantes.HAUTEUR_MAP; y++)
            {
                Point coordonneeEcran = new Point(0, 0);

                coordonneeEcran.x = ((x - y) * Constantes.LARGEUR_DEMI_TILE) - map.getMap()[x][y].getDemiWidth();
                coordonneeEcran.y = ((x + y) * Constantes.HAUTEUR_DEMI_TILE) - map.getMap()[x][y].getHeight();
                
                g.drawImage(map.getMap()[x][y].getImage(), coordonneeEcran.x + Constantes.POSITION_DEPART_X, coordonneeEcran.y + Constantes.POSITION_DEPART_Y, this);
            }
        }
        
        g.dispose();
        
        bufferStrategy.show();
    }
    
    @Override
    public void mouseClicked(MouseEvent e) 
    {
        Constantes.Mx = e.getX();
        Constantes.My = e.getY(); 
        
        System.out.println(map.coordEcranEnCoordTile());

        System.out.println(map.infoTile());
    } 

    @Override
    public void mouseReleased(MouseEvent e){}
    
    @Override
    public void mousePressed(MouseEvent e)
    {
        Constantes.Mx = e.getX();
        Constantes.My = e.getY(); 
    }
    
    @Override
    public void mouseMoved(MouseEvent e){}
   
    @Override
    public void mouseExited(MouseEvent e){}

    @Override
    public void mouseEntered(MouseEvent e){}

    @Override
    public void mouseDragged(MouseEvent e)
    {
        Constantes.Mx = e.getX();
        Constantes.My = e.getY(); 
        map.getMap()[map.coordEcranEnCoordTile().x][map.coordEcranEnCoordTile().y] = map.herbe;
 
    } 

    @Override
    public void keyTyped(KeyEvent e) {}

    @Override
    public void keyPressed(KeyEvent e) 
    {
        int KeyCode = e.getKeyCode();

        switch(KeyCode)
        {
            case KeyEvent.VK_UP: map.KeyPressed(e);
                break;
            case KeyEvent.VK_DOWN: map.KeyPressed(e);
                break;
            case KeyEvent.VK_LEFT: map.KeyPressed(e);
                break;
            case KeyEvent.VK_RIGHT: map.KeyPressed(e);
                break;
        }
    }

    @Override
    public void keyReleased(KeyEvent e) 
    {
        int KeyCode = e.getKeyCode();

        switch(KeyCode)
        {
            case KeyEvent.VK_UP: map.KeyRelease(e);
                break;
            case KeyEvent.VK_DOWN: map.KeyRelease(e);
                break;
            case KeyEvent.VK_LEFT: map.KeyRelease(e);
                break;
            case KeyEvent.VK_RIGHT: map.KeyRelease(e);
                break;
        }
    }
    
    public static void main(String[] args) 
    {
        GameCanvas game = new GameCanvas();
        
        JFrame frame = new JFrame();
        frame.add(game);
        
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   
        frame.setSize(1024, 600);
        frame.setLocationRelativeTo(null);
        frame.setResizable(true);
        frame.setVisible(true);

        game.start();
    }
}        
  
Commenter la réponse de deli2025

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.