【问题标题】:Animating two images in java在java中动画两个图像
【发布时间】:2014-04-30 23:27:48
【问题描述】:

我对 java 很陌生。我需要在 Java 游戏上为两个图像设置动画。它是一款宇宙飞船游戏,允许两个用户使用键盘控制物体。我已经部分实现了这一点,但是我无法理解如何允许两个键盘控件,而且通过键盘输入移动的一个对象闪烁很多。

public class MainFrame extends JFrame implements KeyListener {

    MainPanel mPanel;
        MainPanel secondss;
         MainPanel thirdss;
        int speed = 5;
        //ss facing north
        int direction = 0;

    MainFrame() {
        setTitle("spaceship Game");
        mPanel = new MainPanel("C:/img");
                secondss = new MainPanel("C:/img");

        setSize(1024, 768);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        add(mPanel); // add MainPanel JPanel to JFrame
        setVisible(true); // show class

                add(secondSs);
                add(thirdSs);
                seconds.currentSs.setX(400);
                secondSS.currentSs.setY(100);
    }

   public void actionPerformed( ActionEvent e )
   {
     if( e.getSource() == mPanel)
     {
     }
   }

        @Override
        public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == e.VK_LEFT) {

         int x = mPanel.currentSs.getX() - speed;
         mPanel.currentSs.setX(x);
        }

        if (e.getKeyCode() == e.VK_RIGHT) {
         int x = mPanel.currentSs.getX() + speed;
         mPanel.currentSs.setX(x);
        }
        if (e.getKeyCode() == e.VK_DOWN) {
         int y = mPanel.currentSs.getY() + speed;
         mPanel.currentSs.setY(y);
        }
        if (e.getKeyCode() == e.VK_UP) {
         int y = mPanel.currentSs.getY() - speed;
         mPanel.currentSs.setY(y);
        }
        //change image direction    
        mPanel.frame = direction;
        }

    public static void main(String[] args) {
        MainFrame mainFrame = new MainFrame();
                mainFrame.addKeyListener(mainFrame);
    }

如果有人可以提供帮助,或者如果没有为我指明正确的方向,我将不胜感激。

【问题讨论】:

  • 使用paint(Graphics g)
  • 为了尽快获得更好的帮助,请发布MCVE(最小完整且可验证的示例)。对代码块使用一致且合乎逻辑的缩进。代码的缩进是为了帮助人们理解程序流程。 @KlemensMorbe 至少出于两个原因,最好直接在顶级容器上绘制,而是使用JPanel 进行绘制。

标签: java swing object animation keylistener


【解决方案1】:
  • JFrame 对于 KeyEvents 是不可聚焦的,那么默认情况下永远不会对 KeyEvents 做出反应

  • setVisible(true);应该是最后一行代码,在所有 JComponents 都添加到 JFrame 之后,

  • 为什么会有public void actionPerformed(ActionEvent e),必须生成excpetion表单编译器


  • 创建一个 JFrame 作为局部变量

  • 将JPanel放入JFrame

  • 覆盖 JPanel 的 getPreferredSize,替代 JFrame 的 setSize

  • 然后调用 pack() 和 setVisble(true)


  • 将图像放入 Java 包中

  • 将图像放入 JLabel

  • 将 NullLayout 设置为 JPanel(否则无法显示动画)

  • 将 KeyBindings 添加到 JPanel,覆盖所需/必需的 KeyEvents


  • 还有另一种方法是使用自定义绘画,通过覆盖 JPanel 的paintComponent,KeyEvents 保留在这里 KeyBindings 作为比 KeyListener 更好的侦听器

【讨论】:

  • "为什么会有 public void actionPerformed(ActionEvent e),必须生成 excpetion form 编译器" 嗯?如果它使用@Override 表示法(这是最好的),它会产生编译器错误,但为什么显示的代码会产生编译器错误? +1 为您提供其他许多好的提示。
  • @Andrew Thompson 但为什么显示的代码会产生编译器错误? - 因为没有实现ActionListener,所以目前我可以看到
  • 如果代码有implements ActionListener 没有 actionPerformed(..) 我可以理解编译错误。 或者如果actionPerformed(..) 声明了@Override。但事实上,如果没有implements ActionListener @Override,它应该可以干净地编译。不幸的是,由于许多其他原因,它无法编译,(缺少课程,未关闭{..)所以我无法轻松检查我在这里所说的内容.. ;)
  • @Andrew Thompson s.o.s,不是或是,我不知道
  • AFAIU 没有(耸耸肩),但据我所知,我愿意推测/猜测不会从 OP 看到 SSCCE。
【解决方案2】:

这是一个宇宙飞船游戏,允许两个用户使用键盘控制对象

不要使用 KeyListener。 Swing 被设计为与键绑定一起使用。

有关更多信息和示例,请参阅Motion Using the Keyboard

KeyboardAnimation 示例演示了两个用户如何控制单个图像。

【讨论】:

    【解决方案3】:

    嗯,你应该在这里改变很多:

    1. 游戏中的图形很少使用组件来完成。请记住,组件很重要(例如 UI 委托、侦听器、对等点等)。您应该做的是创建一个将充当游戏板的自定义组件。该组件的绘制方法将绘制到宇宙飞船的图像上。这也将消除闪烁(在该组件上调用 setDoubleBuffered(true)
    2. 船的位置应该独立于绘画而改变,即应该计算位置并保存在成员变量中,并且绘画应该按照swing的绘画经理的意愿进行。但是,您仍然可以通过使用paintImmediately(...) 在船舶移动时绘制船舶图像来执行更严格的绘制
    3. 没有办法(至少我不知道)处理两个键盘或任何类似的东西。如果您希望 2 位用户同时演奏,他们应该使用相同的键盘,并且您应该有 2 组单独的(并且希望是距离较远的)键,每个玩家一个。就像过去一样:-)

    【讨论】:

    • However, you can still enforce more rigorous painting by using paintImmediately(...) to paint the images of the ships whenever they move == 但你需要确保这幅画是 EDT 外的,否则 RepaintManager 会杀死当前的 JVM,:-)
    • invoke setDoubleBuffered(true), Swing 默认是双缓冲的。
    【解决方案4】:

    根据我对问题的理解,玩家需要使用不同的键集与游戏交互,具体取决于您是玩家 1 还是玩家 2。如果是这种情况,请实现 KeyListener 并覆盖以下方法,就像以下代码可以:

    @Override
        public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_W)
                playerOne_up = true;
            if (e.getKeyCode() == KeyEvent.VK_S)
                playerOne_down = true;
            if (e.getKeyCode() == KeyEvent.VK_UP)
                playerTwo_up = true;
            if (e.getKeyCode() == KeyEvent.VK_DOWN)
                playerTwo_down = true;
        }
    
        @Override
        public void keyReleased(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_W)
                playerOne_up = false;
            if (e.getKeyCode() == KeyEvent.VK_S)
                playerOne_down = false;
            if (e.getKeyCode() == KeyEvent.VK_UP)
                playerTwo_up = false;
            if (e.getKeyCode() == KeyEvent.VK_DOWN)
                playerTwo_down = false;
    
            if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                if (!isStarted()) {
                    doInitializations();
                    setStarted(true);
                }
            }
    
            if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
                if (isStarted()) {
                    setStarted(false);
                } else {
                    frame.dispose();
                }
    
                    }
    
            }
    

    但是,在我的示例中,只允许上下移动(乒乓球游戏)。玩家一使用 W 向上和 S 向下,而玩家二使用向上箭头键和向下箭头键。布尔值 playerOne_up、playerOne_down 等是其他方法的开关,用于查看对象是否需要朝哪个方向移动。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-10
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      相关资源
      最近更新 更多