Comment animer une image en appuyant sur la touche Java 2d game?


Je suis au niveau débutant et je travaille sur un jeu java 2d. Donc, j'essaie de modifier un code déjà existant et je veux animer l'objet lorsque j'appuie sur la touche A. N'importe qui peut dire quoi et où je fais mal ?

Merci d'avance

Mon code est :

package object;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.geom.AffineTransform;
import javax.imageio.ImageIO;
import java.net.URL;
import java.awt.*;
import javax.swing.*;
import java.io.*;



@SuppressWarnings("serial")
public class PlayerA extends JPanel {
   // Named-constants
   static final int CANVAS_WIDTH = 400;
   static final int CANVAS_HEIGHT = 480;
   public static final String TITLE = "Test Player";

   private String[] imgFilenames = {
         "object/images/image1.png", "object/images/image2.png", "object/images/image3.png",};
   private Image[] imgFrames;    
   private int currentFrame = 0; 
   private int frameRate = 5;   
   private int imgWidth, imgHeight;   
   private double x = 50.0, y = 200.0;
   private double speed = 8;           
   private double direction = 0;       
   private double rotationSpeed = 10;  
   private AffineTransform transform = new AffineTransform();


   public PlayerA() {

      loadImages(imgFilenames);
      final Thread animationThread = new Thread () {
         @Override
         public void run() {
            while (true) {
               update();  
               repaint(); 
               try {
                  Thread.sleep(1000 / frameRate);
               } catch (InterruptedException ex) { }
            }
         }
      };

      addKeyListener(new KeyAdapter() {
          @Override
          public void keyPressed(KeyEvent evt) {
             switch(evt.getKeyCode()) {
                case KeyEvent.VK_A:
                    animationThread.start(); 

             }
          }
       });

      setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT));
      requestFocus(); 

   }

   private void loadImages(String[] imgFileNames) {
      int numFrames = imgFileNames.length;
      imgFrames = new Image[numFrames]; 
      URL imgUrl = null;
      for (int i = 0; i < numFrames; ++i) {
         imgUrl = getClass().getClassLoader().getResource(imgFileNames[i]);
         if (imgUrl == null) {
            System.err.println("Couldn't find file: " + imgFileNames[i]);
         } else {
            try {
               imgFrames[i] = ImageIO.read(imgUrl);  
            } catch (IOException ex) {
               ex.printStackTrace();
            }
         }
      }
      imgWidth = imgFrames[0].getWidth(null);
      imgHeight = imgFrames[0].getHeight(null);
   }


   public void update() {
      x += speed * Math.cos(Math.toRadians(direction));  
      if (x >= CANVAS_WIDTH) {
         x -= CANVAS_WIDTH;
      } else if (x < 0) {
         x += CANVAS_WIDTH;
      }
      y += speed * Math.sin(Math.toRadians(direction)); 
      if (y >= CANVAS_HEIGHT) {
         y -= CANVAS_HEIGHT;
      } else if (y < 0) {
         y += CANVAS_HEIGHT;
      }
      direction += rotationSpeed; 
      if (direction >= 360) {
         direction -= 360;
      } else if (direction < 0) {
         direction += 360;
      }
      ++currentFrame;    
      if (currentFrame >= imgFrames.length) {
         currentFrame = 0;
      }
   }


   @Override
   public void paintComponent(Graphics g) {
      super.paintComponent(g);  
      setBackground(Color.WHITE);
      Graphics2D g2d = (Graphics2D) g;

      transform.setToIdentity();
      transform.translate(x - imgWidth / 2, y - imgHeight / 2);
      transform.rotate(Math.toRadians(direction),
            imgWidth / 2, imgHeight / 2);

      g2d.drawImage(imgFrames[currentFrame], transform, null);
   }


   public static void main(String[] args) {

      SwingUtilities.invokeLater(new Runnable() {
         @Override
         public void run() {
            JFrame frame = new JFrame(TITLE);
            frame.setContentPane(new PlayerA());
            frame.pack();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLocation(900, 0); 
            frame.setVisible(true);
         }
      });
   }
}
Author: us0343, 2014-11-02

2 answers

Les mises à jour d'une interface graphique Swing doivent se produire sur le thread de répartition des événements. Je vous suggère donc de lire cela et de réécrire votre code en conséquence. La caisse SwingWorker et SwingUtilities, et éventuellement SwingTimer.

Il y a beaucoup d'exemples là-bas, voici quelques lectures pour vous aider à démarrer:

 0
Author: helmy, 2017-05-23 11:57:45

Je n'ai pas regardé votre code mais vous devriez faire quelque chose comme ceci:

update(float deltaTime) {
  if(isKeyPressed(Keys.A))
    animatePlayer(deltaTime);
//other things
}

private void animatePlayer(float deltaTime) {
//animation grounded on deltaTime here
}

N'oubliez pas d'utiliser deltaTime pour déplacer/animer quelque chose car votre jeu agira différemment sur PC / smartphone / tablette rapide et lent.

 0
Author: nikoliazekter, 2014-11-02 14:31:44