[Java] Mise en pause d'un jeu

Je suis en train de réaliser un Bomberman. Je souhaite mettre en place un bouton pause afin que le joueur puisse stopper momentanément le jeu.

J’essaie d’utiliser des threads afin de pouvoir mettre mon Thread de jeu en attente quand on clique sur le bouton avec la méthode wait. Mais bon, j’ai l’air de très mal m’y prendre, car soit j’obtiens une erreur du type: Current Thread Not Owner ou alors l’ensemble des threads sont bloqués et je ne peux pas recliquer sur le bouton “pause”… :sweat:

En gros, j’ai implémenté le programme suivant

[cpp]

public class Jeu extends JFrame implements JeuI,ActionListener,KeyListener{

private Plateau plateau;
private Thread plat;

public Jeu(){

	// comme Jeu hérite de JFrame, on peut lui spécifier un titre et une taille
	setTitle("Bomberman");
	setSize(new Dimension(800,600));
	this.setFocusable(true);
	// on spécifie au JFrame qu'un clic sur la croix aura pour effet de fermer le programme
	
	addWindowListener(new WindowAdapter()
	{  
		public void windowClosing(WindowEvent e){  
			System.exit(0); 
        		} 
     	});
	
}

public void demarrer(){

	plateau = new Plateau(9, nbJoueurs);
	
	plat = new Thread(plateau);
	plat.start();

}

public void actionPerformed(ActionEvent evt){

Object source = evt.getSource();

if (source == pause){

try {
            plat.wait();
			
        	} catch (InterruptedException e) {}

}
}

public class Plateau extends JPanel implements PlateauI,Runnable{
public Plateau(int tailleMatrice, int nbJoueurs){

	setBackground(Color.white); //couleur de fon

}

public void run(){

	timerMonstre = creerTimerMonstre();
	timerMonstre.start();
while(true){
	
	System.out.println("a");
}

}

[/cpp]

Bien sûr c’est qu’une petite partie du programme pour que vous puissiez voir la démarche que j’ai voulu emprunter… qui n’est pas du tout bonne :fou: :??:

Comment faire pour ne bloquer que le programme exécutant le jeu en lui même, contenu dans la classe Plateau?

Merci d’avance pour vos réponses. :jap:

Le thread du jeu en lui-même (raffraîchissement de l’image, …) ne doit jamais être arrêté… Tu dois avoir un second thread qui gère les déplacements (prise en compte des touches saisies, déplacements, …). C’est celui-là qui doit être mis en attente.

Tu peux temporiser le thread sur pas mal de choses… Ce qui est pas mal c’est d’utiliser le wait sur l’objet Thread en lui-même, mais tu peux créer n’importe quel objet pour ça…

Je suis tout à fait d’accord sur le principe mais comment gérer les déplacements dans un Thread à part… il faudrait créer une classe déplacement… à la limite ça ca va mais maintenant comment faire pour faire déplacer mes éléments (c’est des classes à part entière ).
Pour le moment le KeyListener ressemble à ça:

[cpp]
public void keyPressed(KeyEvent e){

	switch(e.getKeyCode()){
		
		// ecouteur directionnel du premier bomberman
		
		case KeyEvent.VK_DOWN : plateau.deplacerBomberman("bas",0); break;
		case KeyEvent.VK_UP : plateau.deplacerBomberman("haut",0); break;
		case KeyEvent.VK_LEFT : plateau.deplacerBomberman("gauche",0); break;
		case KeyEvent.VK_RIGHT : plateau.deplacerBomberman("droite",0); break;

		
		case 96 : plateau.poserBombe(0); break;  // bomberman souhaite poser une bombe
	
		
	}
	
	if(nbJoueurs == 2){ // déterminer quelle bombe a été posée par quel joueur
	
	   		System.out.println("joueurs: "+nbJoueurs);
	   
			switch(e.getKeyCode()){
				
				// ecouteur directionnel deuxième bomberman			
				
				case 83: plateau.deplacerBomberman("bas",1); break;
				case 90 : plateau.deplacerBomberman("haut",1); break;
				case 81 : plateau.deplacerBomberman("gauche",1); break;
				case 68 : plateau.deplacerBomberman("droite",1); break;			
				
				case 32 : plateau.poserBombe(1); break;  // bomberman souhaite poser une bombe
				
		}	
	}
	
	
	
	plateau.afficher();
} 

[/cpp]

Si je met dans une autre classe, comment je pourrai accéder à l’objet plateau … :??: qui lui même dans la méthode déplacerBomberman fait référence à un objet bomberman.

Heu… Il te manque quelque chose… Regarde ton listener :
Si tu gardes la touche enfoncée, le listener n’enregistre qu’un KeyPressed, ton perso se déplace… une fois

Plus un type tape vite, plus il va vite

Corrige ça, après tu trouveras ma proposition limpide…

Oui ça déjà c’est à corriger tu as raison, il suffirait de faire ça plutôt nan ?

[cpp]
public void keyReleased(KeyEvent e){

	switch(e.getKeyCode()){
		
		// ecouteur directionnel du premier bomberman
		
		case KeyEvent.VK_DOWN : plateau.deplacerBomberman("bas",0); break;
		case KeyEvent.VK_UP : plateau.deplacerBomberman("haut",0); break;
		case KeyEvent.VK_LEFT : plateau.deplacerBomberman("gauche",0); break;
		case KeyEvent.VK_RIGHT : plateau.deplacerBomberman("droite",0); break;

		
		case 96 : plateau.poserBombe(0); break;  // bomberman souhaite poser une bombe
	
		
	}
	
	if(nbJoueurs == 2){ // déterminer quelle bombe a été posée par quel joueur
	
	   		System.out.println("joueurs: "+nbJoueurs);
	   
			switch(e.getKeyCode()){
				
				// ecouteur directionnel deuxième bomberman			
				
				case 83: plateau.deplacerBomberman("bas",1); break;
				case 90 : plateau.deplacerBomberman("haut",1); break;
				case 81 : plateau.deplacerBomberman("gauche",1); break;
				case 68 : plateau.deplacerBomberman("droite",1); break;			
				
				case 32 : plateau.poserBombe(1); break;  // bomberman souhaite poser une bombe
				
		}	
	}
	
	
	
	plateau.afficher();
      // action à réaliser 
} 

[/cpp]

Mais euh, je ne vois toujours pas vraiment comment il faut faire …

Ce KeyListener se trouvant dans la classe Jeu héritant de JFrame…

J’arrive maintenant à stopper le mouvement des monstres… Pour arrêter le Keylistener, j’emploie la méthode removeKeylistener().

Le problème et que si je veux à nouveau recréer ce Keylistener si le joueur souhaite relancer la partie, il se recrée pas … :confused:

Comment faire ? :fou:

Là, s’il ne lâche pas la touche, le bomberman ne bouge pas du tout…

Imaginons que tu rafraîchisses ton terrain de jeu toutes les 20ms (50fps)… Le but va être de conserver les informations de touches saisies pendant cette durée et d’effectuer tous les traitements à la fin (déplacements persos, ennemis, bombes), pour un affichage à la frame suivante

Pour faire pause, il suffit d’un simple if sur cette boucle de traitement (un wait est plus propre :wink: )

Il existe un certain nombre de petits frameworks pour faire des jeux en java, tu peux peut-être t’en inspirer?