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 :

Peindre qu'une partie de ce qui est normallement dessiné dans un composant


Sujet :

2D Java

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2014
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2014
    Messages : 64
    Points : 36
    Points
    36
    Par défaut Peindre qu'une partie de ce qui est normallement dessiné dans un composant
    Bonsoir, je vous explique mon problème alors voila je sauvegarde la disposition de mes images dans un fichier texte et le repaint en le rechargant . Seulement j'aimerais faire en sorte de peindre seulement une partie et la découvrir au fur et à mesure que le joueur va déplacer son personnage . Par exemple il va à l extrémité droite et une partie du fichier se paint et inversement s'il se déplace .


    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
    public void paint(Graphics g){
    		super.paint(g);
    	Graphics2D graphics2d = (Graphics2D) g;
     
     
    	for(int i=0;i<Fleurs.size();i++){
     
    		fleur = Fleurs.get(i);
     
    		graphics2d.drawImage(fleur.getImage(), fleur.getX(), fleur.getY(), null);
     
    	}
     
    	for(int i=0;i<Maisons.size();i++){
    		maison = Maisons.get(i);
    		graphics2d.drawImage(maison.getImage(), maison.getX(), maison.getY(), null);
     
    	}
     
    	for(int i=0;i<Arbres.size();i++){
    		arbre = Arbres.get(i);
    		graphics2d.drawImage(arbre.getImage(), arbre.getX(), arbre.getY(), null);
     
    	}
     
    	for(int i=0;i<Fruits.size();i++){
    		fruit = Fruits.get(i);
    		graphics2d.drawImage(fruit.getImage(), fruit.getX(), fruit.getY(), null);
     
    	}
     
    			try{
    				graphics2d.drawImage(personnage.getImage(), personnage.getX(), personnage.getY(), null);
    			}
    			catch(Exception e){}
    		}
     
     
     
    	public void LoadMap() {
    		try{
    			filer= new FileReader("");
    			int i=0;
    			int x=0;
    			int y=0;
     
    			Fleurs = new ArrayList<Fleur>();
    			Maisons = new ArrayList<Maison>();
    			Arbres = new ArrayList<Arbre>();
    			Fruits = new ArrayList<Fruit>();
     
    		while((i = filer.read()) != -1){
    			char strImg = (char) i;
     
    			if(strImg == '0'){
    				EditeurJeu[x][y] = "FLEURS";
    				fleur = new Fleur(x*25, y*25);
    				Fleurs.add(fleur);
    			}
    			else if(strImg == '1'){
    				EditeurJeu[x][y] = "MAISON";
    				maison = new Maison(x*25, y*25);
    				Maisons.add(maison);
    			}
    			else if(strImg == '2'){
    				EditeurJeu[x][y] = "ARBRE";
    				arbre = new Arbre(x*25, y*25);
    				Arbres.add(arbre);
    			}
    			else if(strImg == '3'){
    				EditeurJeu[x][y] = "FRUIT";
    				fruit = new Fruit(x*25, y*25);
    				Fruits.addfruit);
    			}
    			else if(strImg == 'P'){
    				EditeurJeu[x][y] = "PERSONNAGE";
    				personnage= new Personnage(x*25,y*25);
    			}
     
    				else if(strImg == ' '){
    					EditeurJeu[x][y] = null;
    				}
     
    				// Si on depasse le tableau, on passe à la ligne suivante
    				else if(strImg == '\r' || strImg == '\n'){
    					x--;
    				}
     
    				if(x == 19){
    					y++;
    					x=0;
    				}
    				else{
    					x++;
    				}
     
    				}
    			}
    			catch(Exception ex){}
     
    		}
    Merci de votre aide

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    Je verrais 2 approches différentes pour faire ce que tu voudrais faire.

    1) Tu découpes la zone en rectangles (une grille). Au fur et à mesure du déplacement, dans la grille, tu ajoutes chaque rectangle dans lequel le personne se déplace (déterminer par intersection) dans une liste. Dans la méthode paint() tu ne dessines que les images qui sont en intersection avec un des rectangles de la liste. Tu peux éventuellement utiliser un QuadTree pour accélérer la recherche des intersections.
    Le défaut de cette méthode et que la partie qui apparaitra aura une forme qui sera un assemblage de rectangles, ce qui peut être assez moche, mais elle a l'avantage d'être assez rapide.

    2) Au fur et à mesure du déplacement, tu détermines une Shape qui correspond à l'emplacement de ton personnage (le plus simple étant un rectangle dont les dimesions sont celles du personnage, avec un défaut similaire à la première méthode, mais très amoindri, rendu qu'on peut améliorer en utilisant une Ellipse (inscrite dans le rectangle précédemment décrit), ou encore un secteur, correspondant par exemple à ce que le personnage peut voir, ou n'importe quelle forme qui t'arrange). Tu assembles chaque nouvelle shape dans un Area, par simple union (ajout). Cet Area constitue une Shape que tu peux utiliser pour faire du clipping dans ta méthode paint(). C'est à mon avis le plus simple à faire, mais selon la complexité de la zone, ça peut être moins performant que la première méthode (encore qu'il faudrait tester pour voir, car ça dépend de la taille de la zone à dessiner), mais tu auras un rendu beaucoup plus joli.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    3) plutôt que d'utiliser un clip (qui est tout a fait valide), utiliser une composite ce qui permet de faire des dégradés de transparence/une zone avec des contours adoucis. Cela permet de faire un masque de transparence.
    Voir SRC_IN.

    Et histoire d’éviter de manipuler des formes ou des images trop complexes ou grosses, je dirai une combinaison 1) + 2) ou 1) + 3).
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2014
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2014
    Messages : 64
    Points : 36
    Points
    36
    Par défaut
    Oulah... sa à l' air très compliqué vous auriez pas un exemple concret pour que je comprenne plus facilement s il vous plaît ?

  5. #5
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    J'entrevois bien que l'utilisation d'un composite permet l'antialiassage, mais pour un dégradé comme tu décris @Bouye, j'ai dû mal à voir concrètement l'implémentation. On peut faire ça avec un simple AlphaComposite, ou c'est d'un autre type de composite qu'il faut utiliser ? En tout cas, pour avoir fait quelques essais avec un AlphaComposite, je n'ai jamais réussi à obtenir de dégradé, et en particulier, à contrôler l'épaisseur de la zone de transition (dégradée donc).
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  6. #6
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Pour faire une forme simple, par exemple un rectangle :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Shape forme = new Rectangle2D.Double(x, y, largeur, hauteur);
    Une ellpise :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Shape forme = new Ellipse2D.Double(x, y, largeur, hauteur);
    donc après un déplacement ton personnage est en x,y, et que sa taille fait largeur et hauteur, tu peux directement appliquer ces 2 cas.

    Essaye juste de faire ça, et d'afficher cette forme juste avant d'afficher ton personnage, pour voir ce que ça fait.

    Pour dessiner le contour d'un java.awt.Shape :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    graphics2d.draw( forme );
    Pour peindre (remplir) un java.awt.Shape :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    graphics2d.fill( forme );
    Pour faire un secteur (une forme correspondant à ce que le personnage voit, c'est-à-dire une sorte de triangle dont la pointe est à l'endroit des yeux, et la base est un arc de cercle), tu pourras utiliser un Arc2D.



    Pour faire l'assemblage de plusieurs Shape, tu peux utiliser un java.awt.geom.Area. Au début, avant tout déplacement, il n'y a aucune forme. Donc l'Area n'existe pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    private Area area = null;
    Donc, après chaque déplacement du personnage, tu construis la Shape correspondant, puis tu l'ajoutes à l'Area avec le cas particulier du début :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Shape forme = ... // la forme que tu auras choisie à ta convenance
    if ( area==null ) { // au début
       area = new Area(forme);
    }
    else {
       area.add(new Area(forme));
    }
    Area étend Shape. Essaye simplement pour commencer d'afficher area (avec un Graphics2d.draw() ou fill(), puisque c'est aussi un Shape).

    Pour faire du clipping, il suffit, au lieu de faire draw() ou fill(), de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    graphics.setClip( area );
    Ceci à pour effet de faire que tout ce qui sera dessiné après, n'apparaitra que dans les limites de l'area. Tout ce qui est dessiné, avec n'importe quelle méthode de Graphics2D, n'apparait pas en dehors de ces limites.

    Tu peux avoir besoin de pouvoir dessiner autre chose dans la zone complète, par exemple pour faire un premeir plan. Dans ce cas, soit tu sauvegardes le clipping avant de faire setClip(), (avec Shape saveclip = graphics2S.getClip();) et tu le remets après avoir dessiné les images, soit tu créés un nouveau Graphics sur le premier ce qui fait une copie de premier dans laquelle tu peux modifier tout ce que tu veux (couleurs, clipping, transformées affines, etc...) sans effet sur le Graphics d'origine (sauf ce que tu dessines évidemment, qui se dessine bien dans le composant au final).

    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
     
    Graphics2D graphics2d = (Graphics2D) g;
     
    Graphics2D copygr = (Graphics2D) graphics2d.create(); // fait une copy
     
    copygr.setClip(area); // mets un clip sur copygr, mais pas sur graphics2d
     
    	for(int i=0;i<Fleurs.size();i++){
     
    		fleur = Fleurs.get(i);
     
    		copygr.drawImage(fleur.getImage(), fleur.getX(), fleur.getY(), null); // le clip a un effet sur cette image
     
    	}
     
     
    graphics2d.drawImage( image,  x, y, null); // le clip n'a pas d'effet sur cette image
     
    ...
     
    copygr.dispose(); // on libère toujours quand on a créé

    Ce que suggère @Bouye par combiner les 2 approches, et que tu peux rapidement tester si la forme correspondant à ton personnage est en intersection avec une image, et donc si ça vaut le coup d'ajouter cette forme à l'area. Si la forme n'est pas en intersection avec une image, l'ajouter ou pas n'aura aucun effet. Comme les positions de tes images sont fixes, tu peux créer une "liste" des rectangles correspondant dès le chargement. En utilisant un QuadTree, tu optimiseras le test l'intersection. Commence d'abord par une approche, ensuite combine. Pour déterminer une intersection entre 2 Shape, vois la méthode intersects() de Shape.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  7. #7
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Allez un peu de code et une image valent mieux qu'un long discours :

    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
    package test;
     
    import java.awt.AlphaComposite;
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Paint;
    import java.awt.RadialGradientPaint;
    import java.awt.RenderingHints;
    import java.awt.Shape;
    import java.awt.event.ItemEvent;
    import java.awt.geom.Ellipse2D;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.imageio.ImageIO;
    import javax.swing.JCheckBox;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JToolBar;
    import javax.swing.SwingUtilities;
     
    public class Main extends JPanel {
     
        public enum DrawMethod {
     
            NO_CLIP,
            CLIP,
            CLIP_SHAPE,
            SRC_IN_HARD,
            MASK_HARD,
            SRC_IN_SOFT,
            MASK_SOFT;
        }
     
        private static final Color TRANSPARENT_COLOR = new Color(0, 0, 0, 0);
     
        private final BufferedImage image;
        private final Shape clip;
        private final Color hardMask = Color.BLACK;
        private final RadialGradientPaint softMask = new RadialGradientPaint(150, 150, 150, new float[]{0, 0.5f, 1}, new Color[]{Color.BLACK, Color.BLACK, TRANSPARENT_COLOR});
     
        public Main() throws IOException {
            super();
            setDrawMethod(DrawMethod.CLIP);
            addPropertyChangeListener("drawMethod", propertyChangeEvent -> {
                buffer = null;
                repaint();
            });
            setAntialias(true);
            addPropertyChangeListener("antialias", propertyChangeEvent -> {
                buffer = null;
                repaint();
            });
            image = ImageIO.read(getClass().getResource("ME0000867589_2.jpg"));
            clip = new Ellipse2D.Float(0, 0, 300, 300);
        }
     
        @Override
        protected void paintComponent(final Graphics g) {
            super.paintComponent(g);
            final Graphics2D g2d = (Graphics2D) g.create();
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, getAntialias() ? RenderingHints.VALUE_ANTIALIAS_ON : RenderingHints.VALUE_ANTIALIAS_OFF);
            try {
                final DrawMethod drawMethod = getDrawMethod();
                switch (drawMethod) {
                    case CLIP: {
                        g2d.setClip(clip);
                        drawContent(g2d);
                    }
                    break;
                    case CLIP_SHAPE: {
                        g2d.setPaint(hardMask);
                        g2d.fill(clip);
                    }
                    break;
                    case SRC_IN_HARD:
                    case SRC_IN_SOFT: {
                        final Graphics2D gtemp = initializeBuffer();
                        initializeMask(gtemp, drawMethod);
                        gtemp.setComposite(AlphaComposite.SrcIn);
                        drawContent(gtemp);
                        gtemp.dispose();
                        drawBuffer(g2d);
                    }
                    break;
                    case MASK_HARD:
                    case MASK_SOFT: {
                        final Graphics2D gtemp = initializeBuffer();
                        initializeMask(gtemp, drawMethod);
                        gtemp.setComposite(AlphaComposite.SrcIn);
                        gtemp.dispose();
                        drawBuffer(g2d);
                    }
                    break;
                    case NO_CLIP:
                    default: {
                        drawContent(g2d);
                    }
                }
            } finally {
                g2d.dispose();
            }
        }
     
        private BufferedImage buffer;
     
        private void drawContent(Graphics2D g2d) {
            g2d.drawImage(image, 0, 0, null);
        }
     
        private void drawBuffer(Graphics2D g2d) {
            g2d.drawImage(buffer, 0, 0, null);
        }
     
        private Graphics2D initializeBuffer() {
            if (buffer == null) {
                buffer = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
            }
            final Graphics2D g2d = buffer.createGraphics();
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, getAntialias() ? RenderingHints.VALUE_ANTIALIAS_ON : RenderingHints.VALUE_ANTIALIAS_OFF);
            g2d.setColor(TRANSPARENT_COLOR);
            g2d.fillRect(0, 0, image.getWidth(), image.getHeight());
            return g2d;
        }
     
        private void initializeMask(Graphics2D g2d, DrawMethod drawMethod) {
            final Paint paint = (drawMethod == DrawMethod.SRC_IN_HARD || drawMethod == DrawMethod.MASK_HARD) ? hardMask : softMask;
            g2d.setPaint(paint);
            g2d.fill(clip);
        }
     
        ////////////////////////////////////////////////////////////////////////////
        public final void setDrawMethod(final DrawMethod value) {
            putClientProperty("drawMethod", value);
        }
     
        public final DrawMethod getDrawMethod() {
            return (DrawMethod) getClientProperty("drawMethod");
        }
     
        public final void setAntialias(final boolean value) {
            putClientProperty("antialias", value);
        }
     
        public final boolean getAntialias() {
            return (Boolean) getClientProperty("antialias");
        }
     
        ////////////////////////////////////////////////////////////////////////////
        public static void main(String[] args) {
            SwingUtilities.invokeLater(Main::createUI);
        }
     
        private static void createUI() {
            try {
                final Main main = new Main();
                final JComboBox combo = new JComboBox(DrawMethod.values());
                combo.setSelectedItem(main.getDrawMethod());
                combo.addItemListener(itemEvent -> {
                    switch (itemEvent.getStateChange()) {
                        case ItemEvent.SELECTED:
                            final DrawMethod drawMethod = (DrawMethod) combo.getSelectedItem();
                            main.setDrawMethod(drawMethod);
                            break;
                        default:
                    }
                });
                final JCheckBox checkBox = new JCheckBox("Antialiasing");
                checkBox.setSelected(main.getAntialias());
                checkBox.addChangeListener(changeEvent -> {
                    main.setAntialias(checkBox.isSelected());
                });
                final JToolBar toolBar = new JToolBar();
                toolBar.add(combo);
                toolBar.add(checkBox);
                toolBar.setFloatable(false);
                final JFrame jframe = new JFrame("Test");
                jframe.setLayout(new BorderLayout());
                jframe.add(main, BorderLayout.CENTER);
                jframe.add(toolBar, BorderLayout.NORTH);
                jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                jframe.setSize(500, 500);
                jframe.setVisible(true);
            } catch (IOException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
    Nom : clip et masque de transparence.jpg
Affichages : 298
Taille : 181,7 Ko

    Alors :
    • Le clip (découpe) peut être utilisé directement sur le graphic fourni au composant.
    • Le clip ne permet pas d'avoir un masquage aux bords anti-aliasés (le bord du cercle dans lequel s'affiche l'image est TOUJOURS aliasé quelque soit la configuration du graphique).
    • Le masque doit être utilisé sur un graphique transparent (donc une autre image car le graphique fourni au controle est toujours opaque - ou alors il faut bidouiller pour avoir un controle transparent et c'est la porte ouverte a des ennuis).)
    • Le masque permet d'avoir un masquage aux bord anti-aliasé.
    • La transparence de la peinture du masque influe sur l'image composée ce qui permet d'avoir un effet "brouillard de guerre" (image qui s'estompe sur les bords).
    • Ici j'ai utilisé un masque dont la source est une forme vertorielle. On peut aussi utiliser des masques bitmap.
    • Dans le cas d'une animation on peut utiliser des effets (mise à l'échelle, flou, etc.) pour faire varier le masque ou la découpe entre chaque frame (ex: le personnage porte une bougie et le diamètre du cercle varie d'une animation à l'autre pour simuler le fait que la flamme vacille quand le perso marche ou à cause du vent).


    Le masque fonctionne sur le même principe que ce qui est utilisé dans des logiciels de dessins qui supportent les calques et les masques (ex: Photoshop).
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  8. #8
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Ah, oui, ok, avec un masque. Mais difficile de produire le masque à partir d'une Shape quelconque.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  9. #9
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Une shape suivit d'un coup de gaussian blur avant la composition et le tour est joué !!! Plus sérieusement, en général on aura tendance à utiliser des masques bitmap pré-générés (images en dégradés de gris ou en transparence de noir comme ici) :
    • Composer une image c'est plus rapide que de composer des formes complexes.
    • Ça permet d'avoir facilement à la fois des bords nets et des bords dégradés sur le même masque.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  10. #10
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par bouye Voir le message
    Une shape suivit d'un coup de gaussian blur avant la composition et le tour est joué !!! Plus sérieusement, en général on aura tendance à utiliser des masques bitmap pré-générés (images en dégradés de gris ou en transparence de noir comme ici) :
    • Composer une image c'est plus rapide que de composer des formes complexes.
    • Ça permet d'avoir facilement à la fois des bords nets et des bords dégradés sur le même masque.
    Certes, pour un effet lampe de poche, projecteur ou bougie, mais là, il s'agit, si j'ai bien compris, de faire apparaître au fur et à mesure la carte découverte.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  11. #11
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Pareil : tu as une bitmap/texture qui couvre toute la carte qui sert de masque et qui est modifiée au fur et à mesure que le perso se déplace. Aucun soucis et permet de faire des effets bien plus jolis qu'avec de simple shapes. Et aussi la même optimisation en utilisant le quadtree.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  12. #12
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Voilà un exemple un peu plus parlant (et fun à programmer). Je vous met également les images donc vous pouvez tester par vous même directement.

    Egalement j'en ai profité pour corriger ici la partie "nettoyage de la surface avec la couleur transparente" du précédent code car il ne fonctionne pas comme prévu (ça ne se voyait pas dans le précédent code car il n'y avait pas de déplacement tandis que là, le bug a sauté tout de suite aux yeux) -> le problème vient du fait qu'un fillRect() avec une couleur translucide ou transparente conserve ce qu'il y avait dans le graphique précédemment).

    Ici la méthode clearSurface() réinitialise complètement la surface du graphique à la couleur transparente.

    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
    package test;
     
    import java.awt.AlphaComposite;
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Point;
    import java.awt.Rectangle;
    import java.awt.TexturePaint;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.util.Optional;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.imageio.ImageIO;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
     
    public class Main extends JPanel {
     
        private static final Color TRANSPARENT_COLOR = new Color(0, 0, 0, 0);
     
        // Source : carte quand elle est dans son état visible.
        private final BufferedImage mapVisible;
        // Source : carte quand elle est dans son état cachée par le brouillard de guerre (ici en niveau de gris et sans ennemis).
        private final BufferedImage mapFog;
        // Masque de la zone dans le champ visuel du joueur.
        private final BufferedImage playerMask;
        // Masque de la zone dans le champ visuel du joueur.
        private final BufferedImage fogMask;
        // Masque contenant les zones que le joueur a visité.
        private final BufferedImage visibleBuffer;
        // Buffer écran : les parties de la zone visitées par le joueur (sous brouillard de guerre).
        private final BufferedImage fogBuffer;
        // Buffer écran : les parties de la zone visibles par le joueur.
        private final BufferedImage visitedMask;
        // Texture des nuages qui sera affichée sur les zones non-visitées.
        private final TexturePaint cloudTexture;
     
        public Main() throws IOException {
            super();
            setMinimumSize(new Dimension(500, 500));
            setPreferredSize(new Dimension(500, 500));
            setMaximumSize(new Dimension(500, 500));
            mapVisible = ImageIO.read(getClass().getResource("mapvisible.png"));
            mapFog = ImageIO.read(getClass().getResource("mapfog.png"));
            playerMask = ImageIO.read(getClass().getResource("playermask.png"));
            fogMask = ImageIO.read(getClass().getResource("fogMask.png"));
            visibleBuffer = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);
            fogBuffer = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);
            visitedMask = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);
            final BufferedImage cloudImage = ImageIO.read(getClass().getResource("clouds.png"));
            cloudTexture = new TexturePaint(cloudImage, new Rectangle(0, 0, cloudImage.getWidth(), cloudImage.getHeight()));
            addMouseMotionListener(new MouseAdapter() {
                @Override
                public void mouseMoved(MouseEvent mouseEvent) {
                    setPlayerPosition(new Point(mouseEvent.getX(), mouseEvent.getY()));
                }
            });
            addMouseMotionListener(new MouseAdapter() {
                @Override
                public void mouseEntered(MouseEvent mouseEvent) {
                    setPlayerPosition(new Point(mouseEvent.getX(), mouseEvent.getY()));
                }
     
                @Override
                public void mouseExited(MouseEvent e) {
                    setPlayerPosition(null);
                }
            });
            addPropertyChangeListener("playerPosition", propertyChangeEvent -> updatePlayerPosition());
        }
     
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            final Graphics2D g2d = (Graphics2D) g.create();
            try {
                g2d.setPaint(cloudTexture);
                g2d.fillRect(0, 0, getWidth(), getHeight());
                g2d.drawImage(fogBuffer, 0, 0, null);
                g2d.drawImage(visibleBuffer, 0, 0, null);
            } finally {
                g2d.dispose();
            }
        }
     
        ////////////////////////////////////////////////////////////////////////////
        private Point lasPosition;
     
        private void updatePlayerPosition() {
            final Graphics2D visitedg2d = visitedMask.createGraphics();
            final Graphics2D fogg2d = fogBuffer.createGraphics();
            final Graphics2D visibleg2d = visibleBuffer.createGraphics();
            // Clear visible area with transparent color.
            clearSurface(visibleg2d, visibleBuffer.getWidth(), visibleBuffer.getHeight());
            final Optional<Point> positionOptional = Optional.ofNullable(getPlayerPosition());
            positionOptional.ifPresent(position -> {
                if (lasPosition == null || lasPosition.distance(position) > 30) {
                    // Visited mask.
                    visitedg2d.setComposite(AlphaComposite.SrcOver);
                    visitedg2d.drawImage(fogMask, position.x - fogMask.getWidth() / 2, position.y - fogMask.getHeight() / 2, null);
                    // Visited area.
                    // Clear fog area with transparent color.
                    clearSurface(fogg2d, fogBuffer.getWidth(), fogBuffer.getHeight());
                    fogg2d.setComposite(AlphaComposite.SrcOver);
                    fogg2d.drawImage(visitedMask, 0, 0, null);
                    fogg2d.setComposite(AlphaComposite.SrcIn);
                    fogg2d.drawImage(mapFog, 0, 0, null);
                    lasPosition = position;
                }
                // Visible area.
                visibleg2d.setComposite(AlphaComposite.SrcOver);
                visibleg2d.drawImage(playerMask, position.x - playerMask.getWidth() / 2, position.y - playerMask.getHeight() / 2, null);
                visibleg2d.setComposite(AlphaComposite.SrcIn);
                visibleg2d.drawImage(mapVisible, 0, 0, null);
            });
            visitedg2d.dispose();
            fogg2d.dispose();
            visibleg2d.dispose();
            repaint();
        }
     
        private void clearSurface(final Graphics2D g2d, final int width, final int height) {
            g2d.setComposite(AlphaComposite.SrcOver);
            g2d.setPaint(Color.BLACK);
            g2d.fillRect(0, 0, width, height);
            g2d.setComposite(AlphaComposite.SrcIn);
            g2d.setPaint(TRANSPARENT_COLOR);
            g2d.fillRect(0, 0, width, height);
            g2d.setComposite(AlphaComposite.SrcOver);
        }
     
        ////////////////////////////////////////////////////////////////////////////
        public final void setPlayerPosition(final Point value) {
            putClientProperty("playerPosition", value);
        }
     
        public final Point getPlayerPosition() {
            return (Point) getClientProperty("playerPosition");
        }
     
        ////////////////////////////////////////////////////////////////////////////
        public static void main(String[] args) {
            SwingUtilities.invokeLater(Main::createUI);
        }
     
        private static void createUI() {
            try {
                final Main main = new Main();
                final JFrame jframe = new JFrame("Test");
                jframe.setLayout(new BorderLayout());
                jframe.add(main, BorderLayout.CENTER);
                jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                jframe.setResizable(false);
                jframe.setVisible(true);
                jframe.pack();
            } catch (IOException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
    Et les images associées :

    La texture des nuages :
    Nom : clouds.png
Affichages : 314
Taille : 73,3 Ko

    La carte représentant les parties visitées (en gris et sans ennemis) :
    Nom : mapfog.png
Affichages : 318
Taille : 23,6 Ko

    La vraie carte (avec les couleurs et les ennemis) :
    Nom : mapvisible.png
Affichages : 299
Taille : 25,0 Ko

    Les zones directement visibles par le joueur :
    Nom : playermask.png
Affichages : 284
Taille : 4,5 Ko

    Le masque utilisé pour afficher les zones déjà visitées (au départ j'utilisais l'image précédente mais ça faisait des bordures trop nettes - à cause du fait qu'on dessine plusieurs fois ce masque sur lui-même pour découvrir les zones au fur et à mesure) :
    Nom : fogmask.png
Affichages : 360
Taille : 5,0 Ko
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  13. #13
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Et ce que ça donne au final (j'ai du spliter comme on ne peut plus attacher plus de 5 images par message) :

    Nom : Test.jpg
Affichages : 291
Taille : 83,1 Ko

    Quand on déplace le curseur on découvre des portions de la carte et la partie directement sous le curseur affiche ce que voit le joueur (c-a-d les ennemis quand ils sont dans son champ de vision).

    Voilà, à adapter avec des plans/images composées au vol (en fonction de l'évolution du monde dans le jeu, des déplacements des ennemis, etc) et à optimiser avec le quadtree pour éviter de manipuler des images trop grosses (le stage complet est bien sur plus grand que ce qui est visible ici).

    Il reste encore plein de choses possibles à optimiser :
    • Utiliser des images compatibles pour avoir l’accélération graphique.
    • Il n'y a pas réellement besoin que le buffer visible soit aussi grand, ça pourrait être une image bien plus petite (même taille que le masque visible) et positionnée au bon endroit au moment du rendu final.
    • etc.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  14. #14
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Merci @Bouye d'avoir pris le temps de faire cet exemple concret très intéressant, et très complet.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

Discussions similaires

  1. Afficher une partie de texte qui est préalablement stockée dans la base
    Par sooprano dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 18/02/2010, 20h55
  2. Une partie du code n'est pas exécutée
    Par eddy37fr dans le forum VBA Access
    Réponses: 4
    Dernier message: 31/03/2008, 19h11
  3. Réponses: 2
    Dernier message: 22/02/2008, 10h54
  4. Réponses: 3
    Dernier message: 18/07/2006, 10h17

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