IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 Java Discussion :

Déplacement d'un sprite


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Juin 2009
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 30
    Par défaut Déplacement d'un sprite
    Bonjour à tous

    Voilà je suis confronté à un petit problème que je ne vois comment résoudre
    Donc je veux pouvoir déplacer une image avec des KeyListener
    Voici un bout de code :

    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
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    public void move() {
    	// Déplacement
    	x += dx;
    	y += dy;
     
    	// Ne pas dépasser les bords
    	if (x < 1) x = 1;
    	if (y <1 ) y = 1;
    	if (x > 370) x = 370;
    	if (y > 250) y = 250; }
     
     
    public void keyPressed(KeyEvent e) {
    	// Récupération de la touche enfoncée
    	int key = e.getKeyCode();
     
    	// Actions
    	switch (key) {
    		case KeyEvent.VK_LEFT :
    			depLeft = true;
    			break;
    		case KeyEvent.VK_RIGHT :
    			depRight = true;
    			System.out.println("right pressed");
    			break;
    		case KeyEvent.VK_UP :
    			depUp = true;
    			break;
    		case KeyEvent.VK_DOWN :
    			depDown = true;
    			break; }
     
    	// MAJ
    	update(); }
     
     
    public void keyReleased(KeyEvent e) {
    	// Récupération de la touche relâchée
    	int key = e.getKeyCode();
     
    	// Actions & MAJ
    	switch (key) {
    		case KeyEvent.VK_LEFT :
    			depLeft = false;
    			break;
    		case KeyEvent.VK_RIGHT :
    			depRight = false;
    			System.out.println("right released");
    			break;
    		case KeyEvent.VK_UP :
    			depUp = false;
    			System.out.println("Up released");
    			break;
    		case KeyEvent.VK_DOWN :
    			depDown = false;
    			break; }
     
    	// MAJ
    	update();}
     
     
    public void update() {
    	// Initialisation du déplacement à 0
    	dx = 0;
    	dy = 0;
     
    	// Déplacement
    	if (depLeft) dx = -speed;
    	if (depRight) dx = speed;
    	if (depDown) dy = speed;
    	if (depUp) dy = -speed; }

    J'ai mis des tests d'affichage dans la console pour dentifier le probleme, et le voici :
    Si j'appuie sur une touche (par ex RIGHT) puis sur une autre (par ex UP), quand je relache l'une des 2 touches, le code exécute les 2 keyReleased associés au 2 touches.

    De plus, un test identique sur KeyPressed m'indique qu'elle est enfoncée tout le temps, mais dès qu'une des touches est relâchée, la ligne "right pressed" n'apparait plus, bref le systeme ne reconnait plus aucune touche enfoncée dès que l'une est relâchée...


    J'avoue je bloque un peu
    QQ a-t'il une idée du pourquoi du comment ? Peut-on contourner ce problème ?
    Merci d'avance

  2. #2
    Membre émérite
    Homme Profil pro
    Inscrit en
    Octobre 2004
    Messages
    398
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2004
    Messages : 398
    Par défaut
    Citation Envoyé par Jyhem Voir le message
    Bonjour à tous

    Voilà je suis confronté à un petit problème que je ne vois comment résoudre
    Donc je veux pouvoir déplacer une image avec des KeyListener
    Voici un bout de code :

    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
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    public void move() {
    	// Déplacement
    	x += dx;
    	y += dy;
     
    	// Ne pas dépasser les bords
    	if (x < 1) x = 1;
    	if (y <1 ) y = 1;
    	if (x > 370) x = 370;
    	if (y > 250) y = 250; }
     
     
    public void keyPressed(KeyEvent e) {
    	// Récupération de la touche enfoncée
    	int key = e.getKeyCode();
     
    	// Actions
    	switch (key) {
    		case KeyEvent.VK_LEFT :
    			depLeft = true;
    			break;
    		case KeyEvent.VK_RIGHT :
    			depRight = true;
    			System.out.println("right pressed");
    			break;
    		case KeyEvent.VK_UP :
    			depUp = true;
    			break;
    		case KeyEvent.VK_DOWN :
    			depDown = true;
    			break; }
     
    	// MAJ
    	update(); }
     
     
    public void keyReleased(KeyEvent e) {
    	// Récupération de la touche relâchée
    	int key = e.getKeyCode();
     
    	// Actions & MAJ
    	switch (key) {
    		case KeyEvent.VK_LEFT :
    			depLeft = false;
    			break;
    		case KeyEvent.VK_RIGHT :
    			depRight = false;
    			System.out.println("right released");
    			break;
    		case KeyEvent.VK_UP :
    			depUp = false;
    			System.out.println("Up released");
    			break;
    		case KeyEvent.VK_DOWN :
    			depDown = false;
    			break; }
     
    	// MAJ
    	update();}
     
     
    public void update() {
    	// Initialisation du déplacement à 0
    	dx = 0;
    	dy = 0;
     
    	// Déplacement
    	if (depLeft) dx = -speed;
    	if (depRight) dx = speed;
    	if (depDown) dy = speed;
    	if (depUp) dy = -speed; }

    J'ai mis des tests d'affichage dans la console pour dentifier le probleme, et le voici :
    Si j'appuie sur une touche (par ex RIGHT) puis sur une autre (par ex UP), quand je relache l'une des 2 touches, le code exécute les 2 keyReleased associés au 2 touches.

    De plus, un test identique sur KeyPressed m'indique qu'elle est enfoncée tout le temps, mais dès qu'une des touches est relâchée, la ligne "right pressed" n'apparait plus, bref le systeme ne reconnait plus aucune touche enfoncée dès que l'une est relâchée...


    J'avoue je bloque un peu
    QQ a-t'il une idée du pourquoi du comment ? Peut-on contourner ce problème ?
    Merci d'avance
    regardes keyEntered

  3. #3
    Membre éclairé
    Inscrit en
    Juin 2006
    Messages
    570
    Détails du profil
    Informations forums :
    Inscription : Juin 2006
    Messages : 570
    Par défaut
    Citation Envoyé par franck06 Voir le message
    regardes keyEntered
    Ca vient de quelle interface ca ? Oo

  4. #4
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Par défaut
    Tu devrais nettoyer un peu ton code, notamment ne pas utiliser de boolean pour savoir sur quelle touche tu appuies. Tu devrais directement appeler la méthode "update" dans tes listeners en ajoutant un argument de type enum. Ca va diminuer le nombre de données membres et clarifier le code.
    Sinon, donne le code minimal qui reproduit le problème. Et il doit compiler aussi, on pourra ainsi t'aider plus rapidement.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  5. #5
    Membre émérite
    Homme Profil pro
    Inscrit en
    Octobre 2004
    Messages
    398
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2004
    Messages : 398
    Par défaut
    Citation Envoyé par Djobird Voir le message
    Ca vient de quelle interface ca ? Oo
    je voulais dire keyTyped ... désolé
    essaies de mettre a jour tes booleans aussi dans l'implementation de cette methode voir ce que ca donne ...

    pour les booleans dans le code, je suis pour, ca permet que le sprite se deplace tant qu'on appuie sur la touche
    dans le cas inverse, je pense qu'il faut appuyer sur la touche chaque fois pour obtenir le deplacement

  6. #6
    Membre averti
    Inscrit en
    Juin 2009
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 30
    Par défaut
    Merci de vos réponses.

    Pour l'histoire des booléens modifié lors de l'appui sur une touche, on m'a conseillé de faire comme ça et c'est vrai que je trouve ça pas mal. Maintenant c'est peut être pas la meilleure façon de faire, mais ça m'a l'air plus "propre" de ne pas gérer l'animation dans les méthodes qui gèrent les évènements.

    KeyTyped, j'avais essayé, c'est pareil et c'est pas ce que je recherchais niveau déplacement non plus.

    En fait mon problème a l'air plus sévère que je pensais, je le retrouve dans bcp de jeu java que je trouve sur le net en open source...

    Voici le code du jeu que j'ai essayé d'alléger au maximum.
    J'ai gardé les missiles car le problème est flagrant : quand on tire un missile en mouvement (avec la barre espace), le vaisseau s'arrête de bouger. On voit dans les logs que la touche de déplacement a été relâchée alors que ce n'est pas le cas. Niveau gameplay c'est pas terrible

    Image vaisseau : http://zepload.com/images/1245316524_craft.png
    Image missile : http://zepload.com/images/1245316548_missile.png

    Classe RType :
    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
    import java.awt.Color;
    import javax.swing.JFrame;
     
     
    public class RType extends JFrame {
     
    	// Constructeur
    	// -------------------------------------------
    	public RType() {
    		add(new Board()); 
     
    		setSize(400,300);
    		setTitle("R-Type");
    		setLocationRelativeTo(null);
    		setDefaultCloseOperation(EXIT_ON_CLOSE);
    		setVisible(true); }
     
     
     
    	// Méthode main()
    	// -------------------------------------------
    	public static void main(String[] arg) {
    		new RType(); }
     
    }
    Classe Crat :
    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
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    import java.awt.Image;
    import java.awt.event.KeyEvent;
    import java.util.ArrayList;
    import javax.swing.ImageIcon;
     
     
    public class Craft {
     
    		private String craft = "craft.png";
    		private Image image;
    		private int dx,	dy,	x, y, craftHeight, craftWidth, speed;
    		private ArrayList missiles;
    		private Boolean 
    			depLeft = false,
    			depRight = false,
    			depUp = false,
    			depDown = false;
     
     
    		// Constructeur
    		// -------------------------------------------
    		public Craft() {
    			// Récupération de l'image du vaisseau
    			image = new ImageIcon(getClass().getResource(craft)).getImage();
    			// Récupération de tailles
    			craftWidth = image.getWidth(null);
    			craftHeight = image.getHeight(null);
     
    			// Tableau des missiles
    			missiles = new ArrayList();
     
    			// Position de départ et vitesse
    			speed = 1;
    			x = 40;
    			y = 60; }
     
     
    		// Méthode move()
    		// -------------------------------------------
    		public void move() {
    			// Déplacement
    			x += dx;
    			y += dy;
     
    			// Ne pas dépasser les bords
    			if (x < 1) x = 1;
    			if (y <1 ) y = 1;
    			if (x > 370) x = 370;
    			if (y > 250) y = 250; }
     
     
    		// Touches appuyées
    		// -------------------------------------------
    		public void keyPressed(KeyEvent e) {
    			// Récupération de la touche enfoncée
    			int key = e.getKeyCode();
     
    			// Actions
    			switch (key) {
    				case KeyEvent.VK_LEFT :
    					depLeft = true;
    					break;
    				case KeyEvent.VK_RIGHT :
    					depRight = true;
    					break;
    				case KeyEvent.VK_UP :
    					depUp = true;
    					break;
    				case KeyEvent.VK_DOWN :
    					depDown = true;
    					break; }
     
    			// MAJ
    			update(); }
     
     
    		// Touches relâchées
    		// -------------------------------------------
    		public void keyReleased(KeyEvent e) {
    			// Récupération de la touche relâchée
    			int key = e.getKeyCode();
     
    			// Actions & MAJ
    			switch (key) {
    				case KeyEvent.VK_SPACE : 
    					fire();
    					break;
    				case KeyEvent.VK_LEFT :
    					depLeft = false;
    					System.out.println("Left released");
    					break;
    				case KeyEvent.VK_RIGHT :
    					depRight = false;
    					System.out.println("Right released");
    					break;
    				case KeyEvent.VK_UP :
    					depUp = false;
    					System.out.println("Up released");
    					break;
    				case KeyEvent.VK_DOWN :
    					depDown = false;
    					System.out.println("Down released");
    					break; }
     
    			// MAJ
    			update(); }
     
     
    		// Méthode update()
    		// -------------------------------------------
    		public void update() {
    			// Initialisation du déplacement à 0
    			dx = 0;
    			dy = 0;
     
    			// Déplacement
    			if (depLeft) dx = -speed;
    			if (depRight) dx = speed;
    			if (depDown) dy = speed;
    			if (depUp) dy = -speed; }
     
     
    		// Méthode fire()
    		// -------------------------------------------
    		public void fire() {
    			missiles.add(new Missile(x + craftWidth, y + craftHeight/2)); }
     
     
    		// Accesseurs
    		// -------------------------------------------
    		public int getX() { return x; }
    		public int getY() { return y; }
    		public Image getImage() { return image; }
    		public ArrayList getMissiles() { return missiles; } 
     
    }
    Classe Board :
    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
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Toolkit;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import java.util.ArrayList;
    import javax.swing.JPanel;
    import javax.swing.Timer;
     
     
    public class Board extends JPanel implements ActionListener {
     
     
    		private Timer timer;
    		private Craft craft;
     
     
    		// Constructeur
    		// -------------------------------------------
    		public Board() {
    			addKeyListener(new TAdapter());
     
    			setSize(400, 300);
    			setBackground(Color.BLACK);
    			setDoubleBuffered(true);
    			setFocusable(true);
     
    			craft = new Craft();
     
    			timer = new Timer(5, this);
    			timer.start(); }
     
     
     
    		// Méthode paintComponent
    		// -------------------------------------------
    		public void paintComponent(Graphics g) {
    			super.paintComponent(g);
     
    			Graphics2D g2d = (Graphics2D) g;
     
    			// Vaisseau
    			g2d.drawImage(craft.getImage(), craft.getX(), craft.getY(), this);
    			// Missiles
    			ArrayList ms = craft.getMissiles();
    			for (int i=0; i<ms.size(); i++) {
    					Missile m = (Missile) ms.get(i);
    					g2d.drawImage(m.getImage(), m.getX(), m.getY(), this); }
     
     
    			// Synchro Linux et libération objet g			
    			Toolkit.getDefaultToolkit().sync();
    			g.dispose(); }
     
     
    		// Méthode actionPerformed
    		// -------------------------------------------
    		public void actionPerformed(ActionEvent e) {
    			// Missiles
    			ArrayList ms = craft.getMissiles();
    			for (int i=0; i <ms.size(); i++) {
    				Missile m = (Missile) ms.get(i);
    				if (m.isVisible()) m.move();
    				else ms.remove(i); }
     
    			// Mouvement vaisseau
    			craft.move();
     
    			// Rafraîchissement
    			repaint(); }
     
     
    		// Classe interne TAdapter
    		// -------------------------------------------
    		class TAdapter extends KeyAdapter {
    			public void keyReleased(KeyEvent e) {
    				craft.keyReleased(e); }
     
    			public void keyPressed(KeyEvent e) {
    				craft.keyPressed(e); }}	
    }
    Classe Missile :
    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
    51
    52
    53
    import java.awt.Image;
    import java.awt.Rectangle;
    import javax.swing.ImageIcon;
     
     
    public class Missile {
     
     
    		private int x, y;
    		private Image image;
    		private Boolean visible;
    		private int height, width;
     
    		private final int BOARD_WIDTH = 390;
    		private final int MISSILE_SPEED = 2;
     
     
    		// Constructeur
    		// -------------------------------------------
    		public Missile(int x, int y) {
    			image = new ImageIcon(getClass().getResource("missile.png")).getImage();
    			this.x = x;
    			this.y = y;
     
    			width = image.getWidth(null);
    			height = image.getHeight(null);
     
    			visible = true; }
     
     
    		// Méthode isVisible()
    		// -------------------------------------------
    		public Boolean isVisible() {
    			return visible; }
     
     
    		// Méthode de déplacement du missile
    		// -------------------------------------------
    		public void move() {
    			x += MISSILE_SPEED;
    			if (x > BOARD_WIDTH) visible = false; }
     
     
    		// Accesseurs
    		// -------------------------------------------
    		public int getX() { return x; }
    		public int getY() { return y; }
    		public Image getImage() { return image; }
    		public void setVisible(boolean visible) { this.visible = visible; }
    		public Rectangle getBounds() { return new Rectangle(x, y, width, height); }
     
     
    }

    Merci beaucoup de votre aide

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [SDL 1.2] Déplacement d'un Sprite avec Scrolling
    Par stephantasy dans le forum SDL
    Réponses: 4
    Dernier message: 30/04/2014, 09h07
  2. Réponses: 21
    Dernier message: 01/03/2009, 23h41
  3. déplacement d'un sprite
    Par Mindiell dans le forum Développement 2D, 3D et Jeux
    Réponses: 13
    Dernier message: 23/09/2007, 13h58
  4. Réponses: 10
    Dernier message: 03/03/2007, 13h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo