Tirer un laser vers le haut d'un jpanel
Jadorelinfo
Messages postés
51
Statut
Membre
-
KX Messages postés 19031 Statut Modérateur -
KX Messages postés 19031 Statut Modérateur -
Bonjour a toutes et a tous,
J'essaye de coder un petit jeu du genre bataille spatiale, je dois degommer un max d'aliens.
Faire descendre les aliens vers le bas j'ai réussis, mais moi je dois envoyer des laser(imageIcon) vers le haut(d'un jpanel) et la je beug mais grave!
A partir du for avec son i, je n'y arrive vraiment pas.Merçi d'avance.
J'essaye de coder un petit jeu du genre bataille spatiale, je dois degommer un max d'aliens.
Faire descendre les aliens vers le bas j'ai réussis, mais moi je dois envoyer des laser(imageIcon) vers le haut(d'un jpanel) et la je beug mais grave!
JLabel vaisseau= new JLabel(imgVaisseau);
JLabel laser= new JLabel(imgLaser);
public void keyPressed(KeyEvent e)
{ //des que j'appuis sur espace, ça lance le laser.
if(e.getKeyCode()==KeyEvent.VK_SPACE)
{
//la position initiale du laser est au point getY() du vaisseau.
// le point final est le y==0 du bounds du container
for(int i=vaisseau.getY(); i<=(container.getBounds().y); i--)
{
laser.setBounds(vaisseau.getX()-20, vaisseau.getY()+20, 10, 20);
try {
Thread.sleep(300);
} catch (InterruptedException ex) {
}
}
}
}
A partir du for avec son i, je n'y arrive vraiment pas.Merçi d'avance.
3 réponses
-
Bonjour,
Le problème, c'est que les paramètres que tu passes à SetBounds ne bougent pas !
Il faut utiliser le i de ta boucle.
De plus, ton test <= est mauvais puisqu'au contraire, le i décroit. Le pire c'est que tu donnes la bonne réponse dans ton commentaire :)int posX = vaisseau.getX() - 20; for(int i=vaisseau.getY(); i >= 0; i--) { laser.setBounds(posX, i, 10, 20); try { Thread.sleep(300); } catch (InterruptedException ex) { } }
Xavier -
désolé je vais risquer d'être hors sujet ...
mais tu essaies de refaire un Space Invaders ???-
-
pour info : https://fr.wikipedia.org/wiki/Space_invaders
-
-
merçi pour le lien, faut toujours revenir aux sources wiki :)
Sinon, j'ai une question: la methode keyListener utilise un thread (de base) et j'ai besoin d'un thread.sleep() pour actualiser l'emplacent du laser, quelqu'un aurait une idée svp??
Merçi.-
-
bonsoir,
merçi KX, avec un timer pourquoi pas?!
Par contre, existe t'il un moyen de n'avoir qu'un seulPublic static void main
celui du jeu de base, car avec 2, je risque de m'emmeler les pinceaux??
Et concretement mon Thread.sleep() je l'insere dans la methode run ou bien je raconte une enormité??
Merçi pour cette aide.
PS: J'ai oublié de dire: ALLER LES BLEUS!! :) -
"existe t'il un moyen de n'avoir qu'un seul Public static void main celui du jeu de base"
Le main que j'ai mis dans mon code c'était pour tester, il faut bien évidemment l'enlever et mettre son contenu au bon endroit dans ton code.
"mon Thread.sleep() je l'insere dans la methode run ou bien je raconte une enormité??"
Effectivement c'est une énormité. Si tu regardes mon code, nul part je n'ai de Thread.Sleep, et pourtant il y a bien 1 seconde entre chaque tâche. Pourquoi ? Parce que la tâche est ordonnancée pour s'exécuter régulièrementtimer.schedule(task, 0, 1000)
avec 1000ms=1s
Concrètement tu devrais donc avoir un Timer qui gère toutes tes actions, en particulier le rafraîchissement de la fenêtre, ou alors plusieurs Timer qui gère indépendamment chaque action mais ça semble être la fausse bonne idée, car plus il y aura d'actions à gérer, plus il y aura de threads en concurrence et l'ordonnanceur risque de figer certains threads, alors qu'avec un seul Timer tu es sûr que toutes les actions auront lieu en même temps. -
merçi mais j'ai vraiment du mal sur ce coup la, j'essaye mais je n'y arrive pas.
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode()==KeyEvent.VK_SPACE)
{
System.out.println("e");
//cont.getSize().setSize(500, 0);
//System.out.println(cont.getBounds().y);
for(int i=vaisseau.getY(); i>=0; i--)
{
laser.setBounds(vaisseau.getX()+5, i, 10, 20);
Task t1= new Task();
Timer time= new Timer();
time.schedule(t1, 0, 1000);
}
}
}
Est ce que tu pourrais encore m'aider stp??
Merçi. -
Déjà tu es partie sur le principe où chaque laser va avoir son propre Thread/Task, je ne pense pas que ce soit la meilleure méthode, mais admettons.
Avant toute chose il faut créer le TimerTask, moi j'avais une classe Task qui disait HelloWorld, toi ce qu'il te faudra c'est une classe LaserTask qui gère ton laser.
Un TimerTask s'exécute automatiquement régulièrement, c'est définit lors de son ordonnancement avec le Timer. Il n'y a donc pas à gérer de boucles, uniquement ce que fera chaque occurrence.
Par exemple :
public class LaserTask extends TimerTask { private final Component laser; private final int dx; private final int dy; private final int xMin; private final int yMin; private final int xMax; private final int yMax; private int x; private int y; public LaserTask(Component laser, int x0, int y0, int dx, int dy, int xMin, int yMin, int xMax, int yMax) { this.laser = laser; this.x = x0; this.y = y0; this.dx = dx; this.dy = dy; this.xMax = xMax; this.yMax = yMax; this.xMin = xMin; this.yMin = yMin; } @Override public void run() { if (x < xMin || y < yMin || x > xMax || y > yMax) cancel(); x += dx; y += dy; laser.setLocation(x, y); } }
Ce qui donnerait :
private static final Timer timer = new Timer(); public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_SPACE) { // j'ai mis 1000 comme max, il faut adapter à la taille de la fenêtre ou d'éventuels obstacles LaserTask task = new LaserTask(laser, vaisseau.getX(), vaisseau.getY(), 0, -1, 0, 0, 1000, 1000); timer.scheduleAtFixedRate(task, 0, 300); } }
Remarque technique : une tâche annulée est conservée dans le Timer, dans ton cas cela va utiliser de la mémoire car tu as une tâche par laser, il faut donc rajouter une tâche qui va purger régulièrement le Timer.
public class AutoPurgeTimer extends Timer { public AutoPurgeTimer(long delay, long period) { schedule(new PurgeTask(), delay, period); } private class PurgeTask extends TimerTask { @Override public void run() { purge(); } } }
Dans ce cas on aurait par exemple :
private static final Timer timer = new AutoPurgeTimer(1000,1000);
Autre remarque : quand tu as terminé le jeu, fait untimer.cancel();
, on pourrait aussi définir le Timer comme un démon... ça dépend du reste de l'application.
-