IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

2D Java Discussion :

Succession d'images avec paint


Sujet :

2D Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Inscrit en
    Février 2010
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 12
    Par défaut Succession d'images avec paint
    Bonjour à tous,

    je sais que le sujet à déjà été abordé, mais il est assez difficile de se repérer dans des codes sources étrangers, c'est pourquoi j'aimerai vous présenter mon code source pour que vous puissiez m'aider directement sur celui-ci.

    Voici le problème : je souhaite donc afficher plusieurs images successives lorsque l'utilisateur appuie sur une touche particulière du clavier.

    Voici mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    import java.awt.*;
    import javax.swing.*;
    import java.awt.event.*;
     
     
    public class BubblePlay extends JFrame {
     
    	public Image im = null;
    	public MediaTracker mt = null;
    	private Container cont = new Container();
    	private PanRoundButton pan = new PanRoundButton();
    	private PersoManager perso = new PersoManager("perso.png");
     
    	public BubblePlay() {
    		super("Déplacer le personnage");
    		setDefaultCloseOperation(EXIT_ON_CLOSE);
    		setSize(800,600);
    		setLocationRelativeTo(null);
     
    		cont = getContentPane();
    		cont.setLayout(null);
    		cont.add(perso);
    		cont.add(pan);
    		pan.setBounds(0,0,800,600);
    		perso.setBounds(200,200,40,40);
     
    		addKeyListener(new KeyListener() {
    			public void keyPressed(KeyEvent e) {
    				if(e.getKeyChar() == 'z') { 
    					perso.setLocation(perso.getX(),perso.getY()-3); // a modif
    				}
     
    				else if(e.getKeyChar() == 'q') { 								   // a modif
    					perso.setLocation(perso.getX()-3,perso.getY());
    					perso.persoRepaint("persoLeft1.png");
    					perso.persoRepaint("persoLeft2.png");
    				}
     
    				else if(e.getKeyChar() == 's') { 
    					perso.setLocation(perso.getX(),perso.getY()+3); // a modif
    				}
     
    				else if(e.getKeyChar() == 'd') { 
    					perso.setLocation(perso.getX()+3,perso.getY()); // a modif
     
    				}	
     
    			}
     
    			public void keyReleased(KeyEvent e) { 
     
    			}
     
    			public void keyTyped(KeyEvent e) {
     
    			}
    		});
     
    		setVisible(true);
    	}
     
    	public class PersoManager extends JLabel {
     
    		public PersoManager(String str) {
    			im = Toolkit.getDefaultToolkit().getImage(str);
    			mt = new MediaTracker(this);
    			mt.addImage(im,0);
    			try {
    				mt.waitForID(0);
    			}
    			catch(InterruptedException e) {
    				System.out.println("Erreur MediaTracker"); 
    			}
    		}
     
    		public void paint(Graphics gg) {
    			Graphics2D g = (Graphics2D) gg;
    			g.drawImage(im,0,0,this);
    		}
     
    		public void persoRepaint(String str) {
    			if(str.equals("persoLeft1.png")) {str = "persoLeft2.png";}
    			else if(str.equals("persoLeft2.png")) {str = "persoLeft1.png";}
    			im = Toolkit.getDefaultToolkit().getImage(str);
    			mt = new MediaTracker(this);
    			mt.addImage(im,0);
    			try {
    				mt.waitForID(0);
    			}
    			catch(InterruptedException e) {
    				System.out.println("Erreur MediaTracker"); 
    			}
    		}
    	}
     
    	public static void main(String[] args) {
    		new BubblePlay();
    	}
    }
    Ici, la classe PersoManager me permet 'normalement' de gérer le 'perso' à déplacer lors de l'appui sur une touche particulière.

    Pour simplifier, je me suis principalement axée sur la touche 'q' qui permet de déplacer le personnage vers la gauche.

    Par défaut, le personnage est de face ( ce qui correspond à l'image "perso.png" )
    Lors de l'appui sur 'q', je souhaiterai que le personnage se déplace ( graĉe à cette ligne qui fonctionne : perso.setLocation(perso.getX()-3,perso.getY()); ) et que simultanément, deux images s'alternent : "heroLeft1.png" et "heroLeft2.png"

    Dans le cas du code source ci-joint, le personnage en position repos est bien affiché et se déplace correctement lorsque j'appui sur 'q', mais de plus, j'ai la première image qui s'affiche, soit "heroLeft1.png".
    (l'autre n'apparait jamais)

    J'ai aussi essayer en utilisant des booleans, en utilisant le méthode repaint(); et d'autres petits tatonnage, mais rien n'y fait, j'ai toujours le même problème.
    D'ailleurs, les conditions if/else if de la méthode persoRepaint() sont assez catastrophiques et très mal programmées (je crois qu'il s'agit d'une certaine marque de désespoir )

    Je voudrais donc savoir d'où vient le problème dans mon code (ou plutôt, ce qu'il manque)

    Merci d'avance et bonne soirée

  2. #2
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Bon pour commencer, tu devrais plutôt charger toutes tes images au démarrage plutôt que les recharger à chaque fois. Le chargement d'image étant une opération couteuse.

    Vu que tu cherche à charger les images de façon synchrone je te conseille d'utiliser ImageIO.read plutôt que le couple Toolkit/MediaTracker qui est bien lourdingue.

    Secondement, pour faire un jeu il ne faut utiliser qu'un et un seul composant sur lequel sera dessiné l'intégralité du jeu, et non pas commencer à mélanger des composants qui à la base ne sont pas prévus pour ça.

    Ensuite pour ta gestion des états de l'image. Il faut que tu gère l'état par rapport à un instant T plutôt qu'en réaction directe par rapport à l'appui sur un bouton. Grosso modo tu dois avoir une horloge qui ticke toutes les n milisecondes, décide de ce qui doit être fait à ce moment là en fonction des conditions actuelles et ensuite déclenche le dessin de l'état du jeu.

    Le code de dessin n'a juste pas à s'occuper de logique, il affiche juste le jeu au moment présent.

    Les conditions sont mises en place par l'utilisateur via l'écoute des IO. Chaque action sur un IO modifie une variable, variable qui sera utilisée lors des calculs réalisés à chaque tick de l'horloge.

    Bref ça donne un truc dans ce genre à base de JComponent dont on redéfinit la méthode paintComponent pour le dessin, de Timer Swing pour l'horloge et de KeyListener.

    Exemple commenté, si tu veux le faire tourner il faudra fournir tes propores images
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
     
     
    package swing.tests;
     
    import java.awt.AlphaComposite;
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.awt.geom.AffineTransform;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
     
    import javax.imageio.ImageIO;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.SwingUtilities;
    import javax.swing.Timer;
     
    public class GamePane extends JComponent implements ActionListener, KeyListener {
     
        //l'horloge
        private Timer timer;
        //position horizontale du perso
        private int hPosition = 20;
        //Position verticale du perso
        private int vPosition = 100;
        //Direction du perso
        private int direction = 1;
        //Index de l'image selectionnee
        private int currentImage = 0;
        //Image a afficher
        private BufferedImage selectedImage;
        //Liste des etats de course
        private List<BufferedImage> runningImages;
        //les etats de course dans l'autre sens
        private List<BufferedImage> reverseRunningImages;
        //Image a l'arrêt
        private BufferedImage standingImage;
        //Combien de ticks avant un changement d'image
        private int changeImageCount = 5;
        //Compte de ticks
        private int countTicks = 0;
        //Savoir si le personnage est en mouvement
        private boolean moving = false;
     
        public GamePane() {
            timer = new Timer(20, this);
            //Recuperation des images de courses
            runningImages = importRunningImages();
            //Recuperation de l'image a l'arret
            standingImage = importStandingImage();
            //On selectionne par defaut l'image a l'arret
            selectedImage = standingImage;
            //On retourne les images de course
            reverseRunningImages = new ArrayList<BufferedImage>();
            for(BufferedImage im : runningImages) {
                reverseRunningImages.add(reverseImage(im));
            }
            //Ajout du keyListener
            this.addKeyListener(this);
            //On recupere le focus
            requestFocus();
     
        }
     
        @Override
        public void actionPerformed(ActionEvent arg0) {
            //On verifie que le perso bouge bien
            if (moving) {
                //On verifie si l'on doit changer l'image
                if (countTicks == changeImageCount) {
                    countTicks = 0;
                    //On verifie que l'on arrive a la fin des images ou pas
                    if (currentImage == runningImages.size() - 1) {
                        currentImage = 0;
                    } else {
                        currentImage++;
                    }
                    //On selectionne la bonne image selon la direction
                    if(direction>0) {
                        selectedImage = runningImages.get(currentImage);
                    } else {
                        selectedImage = reverseRunningImages.get(currentImage);
                    }
                } else {
                    countTicks++;
                }
                //On change la position horizontale
                hPosition += 2 * direction;
            } else {
                //on selection l'image a l'arret
                selectedImage = standingImage;
            }
     
            //On demande le repaint du composant
            repaint();    
        }
     
        @Override
        protected void paintComponent(Graphics arg0) {
            // TODO Module de remplacement de méthode auto-généré
            super.paintComponent(arg0);
            Graphics2D g = (Graphics2D) arg0.create();
            //Dessin du backGround
            g.setPaint(new Color(95, 151, 255));
            g.fillRect(0, 0, getWidth(), getHeight());
     
            g.setPaint(new Color(203, 79, 15));
            g.fillRect(0, getHeight() - vPosition, getWidth(), getHeight());
            //Dessin du perso si celui ci est dans la fenetre
            if (hPosition + selectedImage.getWidth() >= 0 && hPosition - selectedImage.getWidth() <= getWidth()) {
     
                g.drawImage(selectedImage, hPosition, getHeight() - vPosition - selectedImage.getHeight(), null);
            }
     
        }
     
        /**
         * Sert a charger les images des differents etats du deplacement
         * @return
         */
        private List<BufferedImage> importRunningImages() {
     
            List<BufferedImage> images = new ArrayList<BufferedImage>();
            try {
                images.add(ImageIO.read(getClass().getResource("/mRunning1.png")));
                images.add(ImageIO.read(getClass().getResource("/mRunning2.png")));
                images.add(ImageIO.read(getClass().getResource("/mRunning3.png")));
                images.add(ImageIO.read(getClass().getResource("/mRunning4.png")));
            } catch (Exception e) {
                e.printStackTrace();
            }
            return images;
        }
     
        /**
         * Sert a charger l'image de l'etat arrete
         * @return
         */
        private BufferedImage importStandingImage() {
            BufferedImage im = null;
            try {
                im = ImageIO.read(getClass().getResource("/mStill.png"));
            } catch (IOException e) {
                // TODO Bloc catch auto-généré
                e.printStackTrace();
            }
            return im;
        }
     
        @Override
        public void keyPressed(KeyEvent arg0) {        
            if (arg0.getKeyCode() == KeyEvent.VK_LEFT || arg0.getKeyCode() == KeyEvent.VK_RIGHT) {
                //On active le deplacement
                moving = true;
                //Choix de la direction
                if (arg0.getKeyCode() == KeyEvent.VK_LEFT) {
     
                    direction = -1;
                } else {
                    direction = 1;
                }
     
            }
        }
     
        @Override
        public void keyReleased(KeyEvent arg0) {        
            if (arg0.getKeyCode() == KeyEvent.VK_LEFT || arg0.getKeyCode() == KeyEvent.VK_RIGHT) {
                //on arrete le déplacement
                moving = false;
            }
        }
     
        @Override
        public void keyTyped(KeyEvent arg0) {
     
        }
     
        //Lance le jeu
        public void startGame() {
            timer.start();
        }
     
        //arrete le jeu
        public void stoptGame() {
            timer.stop();
        }
     
        @Override
        public boolean isFocusTraversable() {
            // Pour que le composant puisse avoir le focus
            return true;
        }
     
        /**Cree le flip horizontal d'une image
         * 
         * @param img
         * @return
         */
        private BufferedImage reverseImage(BufferedImage img) {
            int w = img.getWidth();
            int h = img.getHeight();
            BufferedImage dimg = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g = dimg.createGraphics();
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
            g.drawImage(img, 0, 0, w, h, w, 0, 0, h, null);
            g.dispose();
            return dimg;
        }
     
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
     
                @Override
                public void run() {
                    final GamePane pane = new GamePane();
                    final JFrame f = new JFrame();
                    f.add(pane);
                    pane.requestFocus();
                    f.setSize(800, 600);
                    f.setLocationRelativeTo(null);
                    f.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
                    f.addWindowListener(new WindowAdapter() {
                        @Override
                        public void windowClosing(WindowEvent arg0) {
                            pane.stoptGame();
                            f.dispose();
                        }
                    });
     
                    f.setVisible(true);
                    pane.startGame();
     
                }
            });
     
        }
     
     
    }

  3. #3
    Membre habitué
    Inscrit en
    Février 2010
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 12
    Par défaut
    Merci pour ces explications !

    En ce qui concerne l'exemple, je ne suis pas sur d'avoir les compétences requises pour le comprendre entièrement, et donc l'utiliser. Mais je m'y penche lourdement !
    Existe-t-il cependant une méthode alternative?

    Merci d'avance

  4. #4
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Si tu as des questions spécifiques à poser sur l'exemple n'hésite pas, Dans l'ensemble il est relativement simple et bien commenté. Le concept à bien saisir est celui du timer qui va déclencher la méthode actionPerformed toutes les 20 millisecondes.

  5. #5
    Membre habitué
    Inscrit en
    Février 2010
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 12
    Par défaut
    En fait, c'est surtout au niveau listes, ImageIO, ... que je bloque, c'est-à-dire que je n'en ai jamais "vu" et encore moins utilisé, donc je risque de mettre un petit peu de temps avant de ma familiariser avec ces nouvelles notions.
    Merci en tout cas pour l'exemple, ce qui me permet de m'appuyer dessus pour comprendre.

    A bientôt et encore merci

Discussions similaires

  1. [AC-2007] Retoucher une image avec Paint.NET
    Par souloverride dans le forum Access
    Réponses: 2
    Dernier message: 19/04/2011, 14h17
  2. [XL-2007] ouvrir une image avec paint
    Par patricktoulon dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 06/03/2011, 21h48
  3. Ouvrir une image avec paint depuis un formulaire
    Par gui38 dans le forum Access
    Réponses: 3
    Dernier message: 14/11/2005, 16h40
  4. PB affichage d'image avec IE
    Par arturo dans le forum Modules
    Réponses: 6
    Dernier message: 25/09/2003, 17h28
  5. [VB6] Affichage d'image avec qlq contraintes
    Par youri dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 21/11/2002, 14h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo