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 :

TiledImage: Passer par Graphics2D.drawImage() ou par BufferedImage.getSubImage() ?


Sujet :

2D Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Étudiant
    Inscrit en
    Août 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Âge : 36

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2007
    Messages : 10
    Par défaut TiledImage: Passer par Graphics2D.drawImage() ou par BufferedImage.getSubImage() ?
    Bonjour à tous, je fais mes premiers pas en programmation et suis entrain d'écrire un petit moteur de jeu (pour un jeu de Tank). Comme y'aura des sprites un peut partout, j'utilise un rendu par Double-buffering Hardware et utilise une image GIF avec transparence qui intègre plusieurs "sous-images" (technique de la Tiled Image que j'ai vu quelque part).

    Bon jusque là pas de problème, j'ai reussis à faire bouger mon sprite tout en lui faisant lire son animation de "sous images".

    Le seul soucis, c'est que j'ai trouvé DEUX solutions pour le faire:

    -l'une consiste à transformer mon Image GIF en BufferedImage puis à utiliser sa methode getSubImage(int* , int, int, int).

    -l'autre consiste à garder mon Image GIF sous forme d'Image et d'utiliser le constructeur
    Graphics.drawImage(Image img, int dstx1, int dsty1, int dstx2, int dsty2, int srcx1*, int srcy1, int srcx2*, int srcy2, ImageObserver observer);

    Sachant que mon Rendu est en Double Buffering, et je vais peut-etre dire des conneries, est-ce vraiment pertinent d'utiliser une BufferedImage??
    Quel methode est la plus performante?
    Parce que transformer mon Image en BufferedImage prends plusieurs lignes de code alors que le drawImage n'en prend qu'une seule...

    PS: l'asterisque * veut dire que je place à cette endroit une variable qui increment de la largeur d'une sous-image à chaque boucle).

  2. #2
    Membre habitué
    Étudiant
    Inscrit en
    Août 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Âge : 36

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2007
    Messages : 10
    Par défaut code
    Voici mon code, il est un peut en chantier parce que c'est de l'experimentation pour l'instant. J'ai mis la solution du drawImage() par défaut, celle de la BufferedImage est mis en commentaire spécial.

    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
     
    import javax.swing.*;
    import java.awt.*;
    import java.awt.Image;
    import java.awt.image.BufferStrategy;
    import java.awt.image.BufferedImage;
     
    public class Sprite extends JFrame
    {
        int angle = 0;
        int frame = 0;
        int delay = 400 ;
        int inc = 4;
        Graphics buffer;
        BufferStrategy strategy;
        RenderingThread tr = new RenderingThread();
        GraphicsEnvironment ge;
        MediaTracker tracker;
        Image img;
     
    	public Sprite()
    	{
    	super();
    	//ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    	//Rectangle bound = ge.getMaximumWindowBounds();
    	setSize(400,400);
    	setVisible(true);
    	setIgnoreRepaint(true);
    	createBufferStrategy(2);
     
    	strategy = super.getBufferStrategy();
    	buffer = strategy.getDrawGraphics();
     
    	charger();
    	tr.start();
     
     
     
    	setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    	}
     
    	public void charger()
    	{
    	tracker = new MediaTracker(this);
    	img = Toolkit.getDefaultToolkit().getImage("D:\\TankBoom\\anim.gif");
    	tracker.addImage(img, 0);
    	}
    	public void render()
    	{
     
    	Graphics2D g2d = (Graphics2D)buffer;
    	g2d.setColor(new Color(80,0,0));
    	g2d.fillRect(0, 0, 800, 800);
     
        //g2d.translate(50,0);
        //g2d.translate(angle, 0);
        //g2d.rotate(0);
     
    	//g2d.scale(Math.cos(angle), Math.cos(angle));
     
     
    	//autorise l'utilisation de l'image quand elle est chargée:
    	if((tracker.statusID(0, true)& MediaTracker.COMPLETE) != 0)
    		{
    		/**crée un bufferImage (graphic cachée) pour traiter l'image:
                    BufferedImage Bimg =  new BufferedImage(img.getWidth(null),img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
                    Graphics2D gi = Bimg.createGraphics();
                    gi.drawImage(img, 0, 0, this);
                    Image a = Bimg.getSubimage(frame, 0, 60, 60);
                    gi.dispose(); // qu'apporte cette ligne?? ferme le graphics cachée
            
                    //int w = img.getWidth(this)/3,
                    //h = img.getHeight(this);
                    //g2d.clipRect(0, 0, w, h); */
    		g2d.drawImage(img,30,30,90,90,frame,0,(60+frame),60,this); // dessine l'image traitée
     
    		strategy.show();
    		}
    		else
    		{
    		g2d.drawString("Loading...", 10, 10);
    		}
    	}
     
     
    public static void main(String [] args)
     {
     
    	new Sprite();
     
     }
     
     
     
    class RenderingThread extends Thread
     {
    public void run()
      {
    	while(true)
    	{
    		long t = System.currentTimeMillis(); //regarde l'heure avant de commencer son boulot
    		angle += inc;
    		frame+=60;
     
    		if(angle >= 400)
    		{
    			angle = 0;
    		}
    		if (frame >=180)
    		{
    			frame=0;
    		}
     
     
    		try
    		{   
    			render();
    			t+= delay; //rajoute le delai à l'heure de comencement
     
    			Thread.sleep(Math.max(0, t - System.currentTimeMillis())); 
    			//fais la différence entre l'heure de comencement ajouté au délai 
    			//et celle de maintenant!
    			//afin de soustraire le temps de travaille au délai à respecter.
    		}
    		catch ( Exception e)
    		{
    			System.err.print("Erreur");
    		}
     
    	}
      }
     
     }
    }

  3. #3
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 901
    Billets dans le blog
    54
    Par défaut
    Tu peux egalement utiliser un java.awt.image.CropImageFilter.
    Toutes ces approches sont viables dans des application de bureautique, donc concernant les performances, je crains qu'il ne te faille faire des tests toi-meme ou attendre les interventions de gens plus orientes dans le devellopement de jeu ou d'animation.
    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
    Membre habitué
    Étudiant
    Inscrit en
    Août 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Âge : 36

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2007
    Messages : 10
    Par défaut
    beh je vois pas du tout comment tester leur performance enfait... quoique...

    J'espere tout de même l'heureuse venu d'un progammeur orienté jeu ou animation sur cette page pour m'aider

    En attendant je vais essayer de faire augmenter le nombre de sprites animés sur l'ecran avec chacune des techniques et voir laquel galère en premier mais pour ça, va falloir que la Force soit avec moi: je sais pas du tout comment je va faire pour faire rajouter un sprite à chaque boucle!!

    Au boulot donc!

    Edit: j'avais aussi entendu parler de la technique du ImageCropFilter mais bon :s ça commençait à faire beaucoup trois techniques pour faire la même chose... En tout cas merci d'avoir répondu aussi vite!

  5. #5
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 901
    Billets dans le blog
    54
    Par défaut
    Mise a part la technique qui consiste a composer directement une sous-partie d'une grande image sur l'ecran, tu peux pour le reste te creer une SpriteFactory qui cree une image pour chaque sprite en utilisant au choix l'une des trois techniques selon sa configuration. Dans ce cas de toute maniere, le principal impact est lors de la creation initiale du sprite (puisque celui-ci est cree une fois et reutilise par la suite).

    Une autre chose qui peut influer sur les performances cependant : il te faut creer des BufferedImage compatible* (on echape pas alors a la recopie d'une image dans une autre). Faire des recherches dans le forum et la FAQ.

    *Sous-entendu compatible avec l'affichage. Cela permet d'eviter que les donnes de l'image ne soit remodifiees a chaque re-affichage pour etre compatible avec le format supporte par la carte video. Ca donne une certaine acceleration.

    Pour terminer, les forums anglais de javagaming.org ont une section specialement destinee aux jeux 2D et ton tu peux directement y demander l'avis de gens qui develloppent des jeux en Java.
    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

  6. #6
    Membre habitué
    Étudiant
    Inscrit en
    Août 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Âge : 36

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2007
    Messages : 10
    Par défaut Merci que même!! :p
    L'image Compatible est une bonne idée, merci

    Pour le SpriteFactory, je comprends pas trop :s tu veux pré-découper les images? et les utiliser comme des images indépendantes?

    J'ai aussi entendu parler d'Image volatile, ça vaut-il vraiment le coup? qu'entend-on par "risque de perdre l'image"? On peut que même pas la perdre du disque dur :s , il s'agit bien de la perdre dans la mémoire video... est-ce vraiment si "pratique" les volatileImages si l'application peut risquer de les perdre :s ??

    Sinon merci pour l'adresse, j'ai été poster un topic là bas je mettrais la réponse en français ici si ils me répondent, pour d'éventuelle français qui sont/seront dans le même cas.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. passer un tableau d'entier par valeurs à une fonction
    Par piotrr dans le forum Collection et Stream
    Réponses: 10
    Dernier message: 18/12/2007, 01h16
  2. [astuce] Comment passer des résultats en sortie par référence
    Par Hibou57 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 26/08/2007, 20h12
  3. Réponses: 4
    Dernier message: 07/06/2007, 11h40
  4. [WinForms]Passer du MDI à la navigation par onglet
    Par jyl2002 dans le forum Général Dotnet
    Réponses: 2
    Dernier message: 14/10/2006, 13h15
  5. Réponses: 2
    Dernier message: 03/10/2005, 22h16

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