【问题标题】:Having Issues in Animating and moivng Pacman in java在动画中遇到问题并在 java 中移动 Pacman
【发布时间】:2014-09-14 18:02:25
【问题描述】:

为了制作动画,我使用了一条不同方向的 pacman 图像(嘴巴张开、半闭、全闭),并通过以下方式绘制它们:

frame = 0;

public  void paintComponent(Graphics g) {
    super.paintComponent(g);    
    g.drawImage(PacRIGHT.getSubimage(frame, 0, 28, 28), x, y, null);
}  

要为 pacman 设置动画,帧是 * 30 以向右移动 30 个像素,>= 60 以完成 1 个动画周期,这将是这样的:

frame = 0*30 ;
frame = 1*30 ;
frame = 2*30 ;

这里我们为每个方向绘制了 4 个不同的图像条,我面临的第一个问题是想办法做到这一点,而且我无法移动它,这是代码


更新: 这次使用摇摆计时器 代码已更新,现在我可以移动 Pacman 和正确方向的动画嘴 问题是现在我遇到了多个错误。

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Runtest extends JPanel implements ActionListener, KeyListener {

    Timer t = new Timer(4, this);
    int x, y, velocx, velocy = 0;
    int keyCode;
    int frame = 0;

    BufferedImage PacUP;
    BufferedImage PacDOWN;
    BufferedImage PacLEFT;
    BufferedImage PacRIGHT;

    public Runtest() throws IOException {
        t.start();
        addKeyListener(this);
        setFocusable(true);
        PacRIGHT = ImageIO.read(new File("E:\\javapacman\\newright.png"));

    }

    public int frame() {

        frame++;
        if (frame > 3)
            frame = 0;

        return frame;
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(PacRIGHT.getSubimage(frame() * 30, 0, 28, 28), x, y, null);

        // Graphics2D g2 = (Graphics2D) g ;
        // g2.fill(new Ellipse2D.Double(x,y,40,40));
    }

    public void actionPerformed(ActionEvent ae) {
        repaint();
        x += velocx;
        y += velocy;
    }

    public void up() {
        velocy = -1;
        velocx = 0;

    }

    public void down() {
        velocy = 1;
        velocx = 0;

    }

    public void left() {
        velocx = -1;
        velocy = 0;

    }

    public void right() {
        velocx = 1;
        velocy = 0;
    }

    @Override
    public void keyPressed(KeyEvent ke) {
        keyCode = ke.getKeyCode();

        if (keyCode == KeyEvent.VK_UP) {
            up();
        }

        if (keyCode == KeyEvent.VK_DOWN) {
            down();
        }

        if (keyCode == KeyEvent.VK_LEFT) {
            left();

        }
        if (keyCode == KeyEvent.VK_RIGHT) {
            right();
        }

    }
}

还有主类:

public class PacMan {
    public static void main(String[] args) throws IOException {
        JFrame frame = new JFrame("Test");
         Runtest test = new Runtest();
         frame.setSize(400, 400);
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.add(test);
         frame.setVisible(true);
    }
}    

我遇到的错误

Exception in thread "AWT-EventQueue-0" java.lang.UnsupportedOperationException:      Not supported yet.
at pactest.Runtest.keyReleased(Runtest.java:128)
at java.awt.Component.processKeyEvent(Component.java:6466)
at javax.swing.JComponent.processKeyEvent(JComponent.java:2828)
at java.awt.Component.processEvent(Component.java:6282)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4861)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1895)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:762)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1027)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:899)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:727)
at java.awt.Component.dispatchEventImpl(Component.java:4731)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:708)
at java.awt.EventQueue$4.run(EventQueue.java:706)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:705)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

【问题讨论】:

  • 首先,我将运动和动画分开 - 使用 1 张图像开始,然后让运动正常工作。然后处理图像切换问题。
  • 我的第一个重点也是先移动图像然后想办法绘制,但卡在移动上尝试了不同的方法但失败了,
  • @AMATURE 你需要一些东西来移动packman,你目前在actionPerformed 中有一些东西,但我不知道它是如何被调用的。不久前,我提出了一个关于游戏循环的问题stackoverflow.com/questions/16364487/…,也许您可​​以使用该代码并对其进行处理。

标签: java animation jquery-animate keylistener pacman


【解决方案1】:

首先,如果我是你,我会将运动和动画分开。让运动首先使用一组图像。

运动:
在您更改速度参数的关键事件上,这似乎很好。您似乎正在使用MyPanel 中的xy 变量作为位置变量。 您应该在某处将它们设置为初始值 - 在构造函数中或在实例变量声明中。

您对使用速度变量修改 xy 变量有正确的想法,但您是在 actionPerformed 方法中这样做的。那不是你想要的。您需要根据时间更新位置变量,而不是用户输入。您应该查看@ug_ 提到的游戏循环。游戏循环基本上是在游戏中持续运行的循环:检查输入、更新游戏信息并呈现更改。您应该在游戏循环中更新位置变量。请务必在修改位置变量后调用repaint,以便屏幕反映更改。

正确更新位置变量后,您需要在调用g.drawImage 时在paintComponent 方法中使用xy 变量作为位置参数。这样,图像的位置就会绘制在您跟踪xy 的位置。

动画:
一旦你的运动工作,那么你应该弄清楚图像切换。对此的建议是有一个 curImage 的实例变量,您的 g.drawImage 调用使用该变量。然后,您将使用“游戏循环”处理 3 张图像的循环,以便选择将哪个图像设置为 curImage。这将基于时间,因此例如每 1/2 秒您可以将图像更改为集合中的下一个图像。当您到达集合的末尾时,您将在集合中反向移动。所以顺序是:open, half, close, half, open, half, etc..。您也可以使用最初设置为 0 的索引计数器轻松完成此操作,每次选择图像时递增,然后在到达集合中的最终图像时递减,在开始时重复该过程。

另外,您提到每个方向都有不同的图像集。在游戏循环中,您可以检查速度参数以确定正在行进的方向。该信息将告诉您从哪个图像集合中提取图像。然后,您可以使用索引计数器从该集合中获取正确的图像。

【讨论】:

  • 我可以使用 javax.swing.Timer 来调用每 xx 毫秒更新游戏状态的方法
  • @AMATURE 有多种方法可以做到这一点,所以我相信你可以让它以这种方式工作
  • @AMATURE 您现在遇到的问题是一个完全不同的问题。您的原始问题/问题已得到解答。您不应该编辑原始问题 - 您应该创建一个新问题。如果我的回答解决了您最初的问题,那么请接受它,这样问题就不会保持开放。
  • 每次按键时都会出现移动图像的问题,所以这不相关吗?
  • 您最初的问题是关于为什么您的动作无法使用原始代码以及如何制作动画 - 现在您的问题是关于您收到的特定错误。无论如何,如果您正在实现 KeyListener,您需要覆盖 keyPressedkeyReleasedkeyTyped 方法。另外,不知道为什么你仍然有那个actionPerformed 方法。您可能可以停止实施ActionListener
猜你喜欢
  • 2015-03-31
  • 1970-01-01
  • 2016-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多