Probléme avec l'utilisation d'un JViewport
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 :cry: ...
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 :ccool:) 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:
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:
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:
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:
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