为什么我不能为正在绘制的图像制作动画并使用关键侦听器制作动画?

Why can't i animate the image that's being painted and make animation with a key listener?

我无法制作动画 spaceship.png 也无法更新图像以制作动画。
需要使用 paint 方法对其进行动画处理(可以使用 ImageIcons 和标签对其进行动画处理)以便旋转。 所以,重写了它,但现在我什至无法更新它的当前位置。

  1. 我怎样才能用一个关键的听众制作动画?
  2. 为什么我不能为正在绘制的图像制作动画?

public class MyPanel extends JPanel implements KeyListener{
    
    final int PANEL_WIDTH = 1920;
    final int PANEL_HEIGHT = 1080;
    Image spaceship;
    Image spaceship2;
    Image spaceship3;
    Image Alien1;
    Image Alien2;
    Image AlienBoss;
    Image Asteroid1;
    Image Asteroid2;
    Timer timer;
    int xVelocity = 1;
    int yVelocity = 10;
    int x = 0;
    int y = 0;
    
    
    MyPanel(){
        this.setPreferredSize(new Dimension(PANEL_WIDTH,PANEL_HEIGHT));
        this.setBackground(new Color(0x080e12));
        this.addKeyListener(this);
        spaceship = new ImageIcon("D:\Users\Xigmatek\eclipse-workspace\SpaceGameRev\src\spaceship.png").getImage();
    }
    public void paint(Graphics g){
        
        super.paint(g);
        Graphics2D g2D = (Graphics2D) g;
        g2D.drawImage(spaceship, x, y, null);

        
    }
    @Override
    public void keyTyped(KeyEvent e) {
        // TODO Auto-generated method stub
        
    }
    @Override
    public void keyPressed(KeyEvent e) {
        switch(e.getKeyCode()) {
            case 87: x -=xVelocity;
            repaint();  
            break;
        
            case 83: x +=xVelocity;
            repaint();  
            break;
        }
        
    }
        
    
    @Override
    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub
        
    }
    
}

抱歉,如果我粘贴了太多代码,但我是新手,抱歉:/

您创建的 JPanel 的问题是它不可聚焦,即它不注册键事件,可以用一行简单的代码修复它 setFocusable(true),我注意到您更新了仅在 space 船移动时帧,但每 60 秒或每秒任何帧更新一次始终是一个好习惯,您可以通过实施 ActionListener 并传递class 到 Timer.

我将键更改为各自的变量(VK_W 和 VK_S)

这是更新后的代码

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

// in order to repeat after set delay, the class shall implement Action Listener and pass it to a timer(shown below)
public class MyPanel extends JPanel implements KeyListener, ActionListener {

    final int PANEL_WIDTH = 1920;
    final int PANEL_HEIGHT = 1080;
    Image spaceship;
    Image spaceship2;
    Image spaceship3;
    Image Alien1;
    Image Alien2;
    Image AlienBoss;
    Image Asteroid1;
    Image Asteroid2;
    Timer timer;
    int xVelocity = 1;
    int yVelocity = 10;
    int x = 0;
    int y = 0;


    MyPanel(){
        this.setPreferredSize(new Dimension(PANEL_WIDTH,PANEL_HEIGHT));
        this.setBackground(new Color(0x080e12));
        this.addKeyListener(this);
        // set this JComponent focusable so that it can register keyEvents 
        setFocusable(true);
        spaceship = new ImageIcon("res\spaceship.png").getImage();
        // pass this class to the timer to repeat after 1000/60 eth of a second(60 fps)
        Timer timer = new Timer(1000/60, this);
        timer.start();
    }
    public void paint(Graphics g){

        super.paint(g);
        Graphics2D g2D = (Graphics2D) g;
        g2D.drawImage(spaceship, x, y, null);


    }
    @Override
    public void keyTyped(KeyEvent e) {
        // TODO Auto-generated method stub

    }
    @Override
    public void keyPressed(KeyEvent e) {
        // I changed 87 and 83 to their respective VK value
        switch(e.getKeyCode()) {
            case KeyEvent.VK_W: x -=xVelocity;
                repaint();
                break;

            case KeyEvent.VK_S: x +=xVelocity;
                repaint();
                break;
        }

    }


    @Override
    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub

    }
    // Override this method from ActionListener
    @Override
    public void actionPerformed(ActionEvent e){
        repaint();
    }
}

请观看这个video,我在这个视频中演示了输出。

顺便说一下,您使用 w 和 s 进行水平移动(gamedev 建议)。