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 :
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 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(); }
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 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); }
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
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(); } } }
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 ...
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(); } }
Merci d'avance
Partager