Bonjour,
Je m'amuse a mes temps perdu en développant un petit jeu de shoot spatial. Le But étant de se déplacer dans une map, avec la souris mais en gardant le joueur au centre de l'écran, et de faire défiler la carte et les autre objet en fonction des mouvent de souris de l'utilisateur.
Ma première tentative a été de fixer les coordonnées de l'utilisateur et de faire bouger tout les autres objets en fonction des déplacement de celui-ci. Cela marchait mais c'était très lourd. J'ai opté pour utilisation d'un Jviewport qui bougerai sur la carte en fonction des déplacements de l'utilisateur.
Et maintenant cela ne marche plus ...
J'ai bien mon utilisateur qui est centré dans mon viewport, et mon viewport qui affiche la map avec les objet. Mais par contre mon viewport se déplace à la fois sur ma map ( donc bien ) et dans ma fenêtre (l pas bien ) ...
Et du coup très vite mon vaisseau et mon viewport sorte de la fenêtre et laisse place au fond gris de ma frame qui constitue ma fenêtre.
je suppose que le lien entre mon viewport et cet fenêtre est mauvais mais je ne vois pas ou.
Voila comment je crée ma fenêtre :
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
 
public Skeleton() {
 
        setTitle("Skeleton");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(1000,800);
        setLocationRelativeTo(null);
        setVisible(true);
        JViewport zoneAffichage = new JViewport();  
        //je place mon viewport dans ma fentre principal
        this.add(zoneAffichage,BorderLayout.CENTER);
        //j'instancie mon board qui correspond a mon niveau de jeu (map + vaisseau utilisateur + les objets de la map
        new Board(zoneAffichage);      
        }
    public static void main(String[] args) {
        new Skeleton();
    }
Ensuite voila comment je crée mon objet Board qui étend JFrame :

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
public Board(JViewport zoneAffichage) {
 
        //chargement de toutes les images et instanciation des objets du board
         ImageLoader.loadImage();
         listeObject= new ArrayList<SpaceObject>();
         SpaceObject.setBoardHeith(getHeight());
         SpaceObject.setBoardWidth(getWidth()); 
        //je recupere mon viewport       
        this.zoneAffichage=zoneAffichage;   
        this.setOpaque(false);
        //instanciation du vaiseau utilisateur positionné au centre de la fenetre
        craft = new Craft(zoneAffichage.getWidth()/2,zoneAffichage.getHeight()/2, this);
        //je paramétre la vue du viewport sur mon niveau de jeu
        zoneAffichage.setView(this);     
 
        ingame = true;      
        initAliens();       
 
         fondEcran = new FondEcran(this);
         //je place mon viewport au point d'origine avec la taile de ma fenetre 
         zoneAffichage.setBounds(0,0, SpaceObject.boardWidth, SpaceObject.boardHeith);
         zoneAffichage.setOpaque(false);
 
         timer = new Timer(3, this);
         timer.start();
         //defintion des listener sur mon viewport 
         zoneAffichage.addKeyListener(new TAdapter());
         zoneAffichage.addMouseMotionListener(new MAdapter());
         zoneAffichage.addMouseListener(new MAdapter());
         zoneAffichage.addMouseWheelListener(new MAdapter());
         zoneAffichage.setFocusable(true);
         //zoneAffichage.setBackground(Color.BLACK);
         zoneAffichage.setDoubleBuffered(true);
 
 
    }
Maintenant voila ma methode paintComponent :
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
 
public void paintComponent(Graphics g) {
        super.paintComponents(g);
         try {
             //mise a jour des taille de la fenetre en cas de modification de celle-ci
        if (boardWidth!=getWidth()) {
            boardWidth =getWidth();
            SpaceObject.setBoardWidth(getWidth());            
        }
        if (boardHeith!=getHeight()) {
            boardHeith =getHeight();
            SpaceObject.setBoardHeith(getHeight());            
        }
 
 
        if (ingame) {           
                   g2d = (Graphics2D)g;
 
                //on dessine la carte
                g2d.drawImage(fondEcran.getFond(), Math.round(fondEcran.getX()-boardWidth/2), Math.round(fondEcran.getY()-boardHeith/2), new Long(Math.round(fondEcran.width+zoom)).intValue(), new Long(Math.round(fondEcran.heigt+zoom)).intValue(),null);         
                Image currentCraft= craft.getImage(); 
                // utilisation de transformation affine pour gerer la direction du vaisseau en fonction de l'angle avec la souris
                AffineTransform ancienne_Transf =g2d.getTransform();     
                 AffineTransform at = AffineTransform.getRotateInstance(craft.dx,craft.dy,Math.round(craft.getCordX()), Math.round(craft.getCordY()));
                 g2d.translate(craft.getCordX(), craft.getCordY());
                 g2d.setTransform(at);           
                 g2d.drawImage(currentCraft, Math.round(craft.x), Math.round(craft.y), new Long(Math.round(craft.width+zoom)).intValue(), new Long(Math.round(craft.height+zoom)).intValue(),null);
                 g2d.setTransform(ancienne_Transf);    
 
 
 
        } else
        {
            //affichage du "game over"
             g2d = (Graphics2D)g;
            String msg = "Game Over";
            g2d.setColor(Color.WHITE);           
            g2d.drawImage(over, boardWidth/2, boardHeith/2, this);
        }    
 
         }
            catch (Exception e) {
                System.out.println("e : "+e.getLocalizedMessage());
            }
            finally {
                if (g2d==null) {
                    g2d.dispose();
                }
              }    
    }
Et enfin voila comment je fais bouger ce viewport dans le actionPerform :

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
public void actionPerformed(ActionEvent e) {
 
         if (isDrivingMode()) {           
                //on fais bouger le vaisseau
                craft.move();    
                Point origin = zoneAffichage.getViewPosition();     
                //Je definis un nouveau point d'origine pour que le vaisseau utilisateur reste au centre de la view par rapport à la taille de la fenetre
                origin = new Point( Math.round(craft.x-zoneAffichage.getWidth()/2),Math.round(craft.y-zoneAffichage.getHeight()/2));                
                //je replace ma view avec mon nouveau point d'origine
                zoneAffichage.setBounds(origin.x,origin.y, zoneAffichage.getWidth(), zoneAffichage.getHeight()); 
 
                //DEPLACEMENT DE TOUT LES OBJETS
 
 
                for (int i = 0; i < listeObject.size(); i++) {
                    SpaceObject o = (SpaceObject) listeObject.get(i);
                    if (!o.equals(craft)&& o.visible){                             
                        o.move();
                    }
                }
                //gestion des collisions 
                checkCollisions();               
          }
 
         if (g2d!=null) {
             Rectangle area=g2d.getClipBounds();
             repaint(area);
         } else {
             repaint();  
         }
    }
Si vous savez pourquoi mon viewport bouge dans ma fenêtre, et surtout comment le fixer je preneur, parce que la je commence à bien sécher ...

Merci d'avance