Afficher des images sur une images de fond (Pour jeu point'n'click)

Résolu
Lastea Messages postés 16 Date d'inscription lundi 31 janvier 2011 Statut Membre Dernière intervention 19 février 2012 - 12 févr. 2012 à 06:10
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 - 19 févr. 2012 à 18:36
Bonjour,

J'ai chercher un peu partout pour afficher des images, par dessus une autre image, mais je n'ai pas trouver. Je vous explique ce que j'aimerais faire :

Je voudrais créer un jeu de point'n'click, où a chaque changement de piece, on charge : l'image de la piece générale, puis chaque images des objets clickable (que l'utilisateur n'as pas encore trouver), et on affiche le tout. De maniere a pouvoir afficher que les objets que l'utilisateur n'as pas trouver (si il a clicker sur un objet, on affiche plus l'image de l'objet).

Je sais comment afficher une image (par exemple avec getClass.getResource() puis dans un jLabel ou ImageIcon), bien que je ne sache pas comment l'afficher a une coordonée (x,y)), mais par contre je ne sais pas comment afficher l'image de mes objets dessus. Est ce que Swing permet de faire ca ? Ou est ce qu'il faut utiliser des librairies type Java 2D/Java Fx ?

Merci d'avance pour toutes vos réponses, j'espere avoir été clair (sinon n'hesitez pas a demander des eclaircissements ^^)

Lastea

33 réponses

cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
17 févr. 2012 à 10:15
Voilà :

public class PanelImage extends JPanel {

    private static final long serialVersionUID = -6350324456764768311L;

    private Image image;

    public PanelImage(Image image) {
        this.image = image;
    }
       
    @Override
    public void paintComponent(Graphics g){
        if(image!=null){
            Graphics2D g2d = (Graphics2D)g;
            g2d.drawImage(image, 0, 0, getWidth(), getHeight(), null);
        }
    }
}

public class GroupeImages extends JPanel {

    public GroupeImages(){
        setLayout(null);
    }

    public void ajouterPanelImage(PanelImage image, int x, int y, int w, int h){
        image.setBounds(x, y, w, h);
        add(image);
    }
}


J'ai enlevé les setImage qui ne servent à rien, il vaut mieux passer par le constructeur, j'ai également créé une classe GroupeImages qui contiendra plusieurs images, il faudra que tu les ajoutes dans le bon ordre pour les superpositions.

Si tu veux pouvoir jouer sur les passages au premier plan, il faudra utiliser des layerpane.
3
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
17 févr. 2012 à 10:52
Non, ce n'est pas plus compliqué qu'en C/C++, crois moi sur parole, le code que je te donne est simple, très simple.

Pour détecter le clic sur une image, il te suffit d'ajouter un Listener sur PanelImage :

public class PanelImage extends JPanel {

    private static final long serialVersionUID = -6350324456764768311L;

    private Image image;

    public PanelImage(Image image) {
        this.image = image;
        addMouseListener(new MouseListener(){
            public void mouseClicked(MouseEvent e){
                // Ecris ton code ici
            }
            public void mouseEntered(MouseEvent e){}

            public void mouseExited(MouseEvent e) {}

            public void mousePressed(MouseEvent e){}

            public void mouseReleased(MouseEvent e){}
        });
    }
       
    @Override
    public void paintComponent(Graphics g){
        if(image!=null){
            Graphics2D g2d = (Graphics2D)g;
            g2d.drawImage(image, 0, 0, getWidth(), getHeight(), null);
        }
    }
}
3
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
12 févr. 2012 à 19:39
Bonjour,

Tu peux utiliser la méthode drawImage en surchargeant paintComponent sur un JPanel pour dessiner à la main une image

Par exemple :

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;

import javax.swing.JPanel;

public class PanelImage extends JPanel {

private static final long serialVersionUID = -6350324456764768311L;

private Image image;

public void setImage(Image image) {
this.image = image;
}

public Image getImage() {
return image;
}

@Override
public void paintComponent(Graphics g){
if(image!=null){
Graphics2D g2d = (Graphics2D)g;
//x, y, w, h représentent la position et la taille de l'image à dessiner
g2d.drawImage(image, x, y, w, h, null);
}
}
}
0
Lastea Messages postés 16 Date d'inscription lundi 31 janvier 2011 Statut Membre Dernière intervention 19 février 2012
13 févr. 2012 à 00:38
Bonsoir,

Ce code a l'air très bien mais je ne sais pas comment l'utiliser ^^ (Je vous avouerais que ca va faire un an que j'ai pas coder ..) :

-Comment créer on un fichier de type 'Image' ? Par exemple, mon image se trouve en C:/Documents, comment la charger en 'Image'. Sachant que ( URL imageURL this.getClass().getClassLoader().getResource(X:/y/z/etc/image.jpg);) donne un résultat de type URL> je le passe comment en Image ?

-Comment utiliser paintComponent une fois l'image charger dans 'image' ? paintComponent(Graphics g ? C'est quoi un Objet de type Graphics ?)


Donc pourriez vous me faire un petit exemple illustrant le chargement d'une image a l'URL 'X:/y/z/etc/image.jpg' puis l'affichage de celle ci par la methode paintComponent ?
J'aurez penser a un code (juste la logique, pas la syntaxe entiere) dans le genre :

private PanelImage panel;
URL imageURL = this.getClass().getClassLoader().getResource(X:/y/z/etc/image.jpg);
panel.setImage(imageURL);
panel.paintComponent ?

Vous remerciant d'avance,

Lastea.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
13 févr. 2012 à 07:56
Pour créer un objet de type Image, tu as plusieurs solutions :

Tu peux accéder aux images contenues dans le package de ton projet en utilisant getClass().getResource() de la manière suivante : ImageIO.read(getClass().getResource("image.JPG")). A ce sujet, je te conseil de lire ceci : http://www.javafr.com/codes/INSERER-IMAGES-DANS-JAR-EXECUTABLE-ECLIPSE_51904.aspx

Sinon, tu as la méthode read() de la classe ImageIO qui peut prendre une URL en parametre.
0
Lastea Messages postés 16 Date d'inscription lundi 31 janvier 2011 Statut Membre Dernière intervention 19 février 2012
13 févr. 2012 à 15:52
Une fois que j'ai fait:

try{Image image = ImageIO.read(getClass().getResource("image.jpg"));}
catch{IOException e) {}


Comment je fait pour afficher l'image ?

Je fait
private PanelImage panel;
panel.setImage(image);


Et après ? Comment fait on pour lui dire de dessiner l'image ? Car paintcomponent prend un objet de type Graphics en parametre. De meme, il faut que je fasse un JFrame dans lequel je fait add.panel() si je veux voir le resultat non ?

Voila voila, je sais que ca peut paraitre un peu basique comme explications demandées, mais j'ai du mal a comprendre la théorie pure. Je comprend beaucoup mieux avec des exemples (d'habitude je prend un code déja fait, j'essayes d'en comprendre les principes et de les refaire, mais la j'ai pas trouver d'exemple de code de jeu point'n'click en java, ni même d'exemples de code affichant des images l'une par-dessus l'autre ^^
0
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
13 févr. 2012 à 16:19
Bonjour,

Tu n'as rien besoin de lui dire pour qu'il dessine l'image. paintcomponent ne s'appelle jamais
directement. Mais est appelé avec la méthode repaint.

Pour que ton image apparaisse, il suffit donc que tu appelles la fonction : panelImage.repaint();

Si tu avais passé l'image dans le constructeur du panel, tu n'aurais pas eu besoin de faire ce repaint.
0
Lastea Messages postés 16 Date d'inscription lundi 31 janvier 2011 Statut Membre Dernière intervention 19 février 2012
15 févr. 2012 à 07:24
Je suis désolé, mais je n'arrive vraiment pas a utiliser ce code, je n'arrive même pas a afficher une image avec, et c'est pas faute d'essayer pourtant ...

Merci quand même pour tes réponses rapides Julien39, je vais continuer a essayer de l'utiliser ou a trouver des exemples simples :)

Lastea.
0
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
15 févr. 2012 à 08:54
Pour utiliser ce code, tu n'as qu'à modifier g2d.drawImage(image, x, y, w, h, null); pour entrer les bonnes valeurs de x, y, w et h.

Le code fonctionne, c'est certain
.

Après, tu as peut être mal appelé ton image. Fais un sysout pour voir si elle est null ou pas.
0
Lastea Messages postés 16 Date d'inscription lundi 31 janvier 2011 Statut Membre Dernière intervention 19 février 2012
15 févr. 2012 à 10:26
Quand je fais :

try{Image image = ImageIO.read(getClass().getResource("image.jpg"));}
catch{IOException e) {}



il me retourne image == null, et je ne comprend pas pourquoi, c'est un de mes plus gros probleme pour tester ce code, au dela de bien comprendre comment l'utiliser ...
Sachant que j'ai bien un fichier image.jpg a la racine de mon projet Java.
0
Lastea Messages postés 16 Date d'inscription lundi 31 janvier 2011 Statut Membre Dernière intervention 19 février 2012
15 févr. 2012 à 10:30
En fait, j'essayes d'écrire un classe Test, qui me permettrait de tester ce code, mais je n'y arrive pas, c'est peut etre un peu beaucoup demander, mais pourriez vous me donner un exemple d'une classe Test, qui utilise cette classe PanelImage, et qui affiche une image, tout simplement ?

Merci d'avance.
0
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
15 févr. 2012 à 11:05
L'image n'a pas été trouvée et tu ne l'as pas vu du fait de la mauvaise gestion des exceptions :
try{Image image = ImageIO.read(getClass().getResource("image.jpg"));}
catch{IOException e) {
e.printStackTrace();
}


De cette facon, tu verras l'erreur.

Ensuite, dans quel package se trouve la classe qui appelle l'image ? Dans le même package que l'image. Si ce n'est pas le cas, il le faut.
0
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
15 févr. 2012 à 11:06
Ensuite, pour ta classe Test, je n'ai rien compris, c'est un test unitaire de ta classe ? Avec JUnit ?

On ne teste pas la partie ihm normalement ...
0
Lastea Messages postés 16 Date d'inscription lundi 31 janvier 2011 Statut Membre Dernière intervention 19 février 2012
15 févr. 2012 à 12:34
Pour ma classe Test, c'est pas un Test vraiment au sens premier du terme, c'est juste une classe, qui utilise PanelImage pour afficher une image (par une methode showImage, ou quelque chose dans le genre)

Un truc de ce genre la :

public class Test
{
    // instance variables - replace the example below with your own
    
    private PanelImage panel;
    private Image image;
    private Image image1;
    private JFrame myFrame;
    /**
     * Constructor for objects of class Test
     */
    public void Test(Image image, Image image1,PanelImage panel)
    {
       this.panel=panel;
       this.image=image;
       this.image1=image1;
       myFrame = new JFrame();
       
    }

   
    public Image getImage()
    {
         try{Image image = ImageIO.read(getClass().getResource("image.jpg"));}
         catch (IOException e) {}
         return image;
        }
        
    public void exemple()
    { panel.setImage(getImage(),50,50);
      panel.repaint();
      myFrame.getContentPane().add(panel);
         }
        }



Mais bon ... Je pense pas du tout que ca soit un bon code ca ..
0
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
15 févr. 2012 à 13:22
Tu n'as pas ajouté le printStackTrace, tu ne peux donc pas voir ton erreur : Traitons d'abord ton erreur et ensuite, nous verrons pour la classe Test.

Est ce que la classe Test est dans le même package que ton image ?
0
Lastea Messages postés 16 Date d'inscription lundi 31 janvier 2011 Statut Membre Dernière intervention 19 février 2012
15 févr. 2012 à 13:50
Voila l'etat du dossier de mon projet, j'ai pas fait de package encore. J'ai essayer le printStackTrace, et ca ne me met rien.
0
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
15 févr. 2012 à 13:54
Tu ne fais pas un setVisible(true) sur la fenêtre ?
0
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
15 févr. 2012 à 13:55
Alors, une classe Test comme ca, ca ne sert à rien, il faut mieux directement utiliser une main :

public static void main(String[] args){
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// image est à définir
f.add(new PanelImage(image));
f.setSize(500, 500);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
0
Lastea Messages postés 16 Date d'inscription lundi 31 janvier 2011 Statut Membre Dernière intervention 19 février 2012
15 févr. 2012 à 15:16
En fait j'avais a peu pres compris comment utiliser ce code, l'erreur principale venais bien du chargement de mon image.

Avec ce code j'arrive a afficher une image :

public class Test
{
public Image image;


public Image getImage(){
 try{image = ImageIO.read(getClass().getResource("image.jpg"));}
         catch (IOException e) {}
         
         return image;
 }
 
    public void main(String[] args){
    JFrame f = new JFrame();
    PanelImage p = new PanelImage();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    p.setImage(getImage(),50,50);
    p.repaint();
    f.add(p);
    f.setSize(500, 500);
    f.setLocationRelativeTo(null);
    f.setVisible(true);
}
}



Mais comment en afficher une grande, puis ensuite en afficher d'autres plus petites, par dessus cette grande image ? Car repaint() fait l'equivalent d'un clear, je n'arrive pas a afficher plusieurs image en meme temps ...
0
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
15 févr. 2012 à 15:41
Je dirais que tu ne dois presque jamais utiliser la méthode repaint.

Dans la méthode paintComponent, tu peux appeler plusieurs fois la méthode drawImage avec des images et des coordonnées différentes.

Ou alors, tu peux superposer des panelImage.
0
Rejoignez-nous