如何通过按Java 2d游戏来动画图像?

时间:2014-11-02 14:01:31

标签: java animation 2d keylistener

我在初学者级别并且正在开发java 2d游戏。 所以,我正在尝试修改已经存在的代码,并且当我按下键A时我想要为对象设置动画。任何人都可以知道我做错了什么和哪里?

提前致谢

我的代码是:

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);
         }
      });
   }
}

2 个答案:

答案 0 :(得分:0)

Swing GUI的更新必须在事件派发线程上进行。因此,我建议您对此进行一些阅读,并相应地重写您的代码。结帐SwingWorkerSwingUtilities,可能还有SwingTimer

有很多例子,这里有一些阅读可以帮助你入门:

答案 1 :(得分:0)

我还没看过你的代码,但你应该做这样的事情:

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

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

请记住使用deltaTime来移动/制作动画,因为您的游戏在快速和慢速PC /智能手机/平板电脑上的行为会有所不同。