Java Pacman张开/闭嘴动画

Java Pacman张开/闭嘴动画,java,swing,awt,java-2d,Java,Swing,Awt,Java 2d,我想用最简单的方法制作pacman张开/闭嘴动画。 这是我最近的代码:问题是,什么都没有发生 package ordner; import java.awt.Color; import java.awt.Graphics; import javax.swing.JFrame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class PacMan implements Ac

我想用最简单的方法制作pacman张开/闭嘴动画。 这是我最近的代码:问题是,什么都没有发生

package ordner;

import java.awt.Color;
import java.awt.Graphics;


import javax.swing.JFrame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;


public class PacMan implements ActionListener {

private JFrame frame;
private DrawPanel panel;

private void initGui() {

frame = new JFrame("Pacman");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

panel = new DrawPanel();
frame.add(panel);
panel.setBackground(Color.BLACK);
frame.setSize(300, 300);
frame.setVisible(true);
}

 public static void main(String[] args) {
  PacMan pm = new PacMan();
  pm.initGui();
}

 @Override 
  public void actionPerformed(ActionEvent e) {
  panel.repaint();  
   }

 }
这是我的绘图面板:

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;


 public class DrawPanel extends JPanel  {

 @Override
  public void paintComponent(Graphics g) {
    super.paintComponent(g); 


g.setColor(Color.yellow);
g.fillArc(70,50,150,150,30,300);

int i = 0;
while ( i <= 60) {

  g.fillArc(70,50,150,150,30-i,300+i+i);



  try {
    Thread.sleep(25);
  }
  catch (Exception e) {
    Thread.currentThread().interrupt();
    }
    i++;




   } 
 }  

  }
导入java.awt.Color;
导入java.awt.Graphics;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
公共类DrawPanel扩展了JPanel{
@凌驾
公共组件(图形g){
超级组件(g);
g、 setColor(颜色为黄色);
g、 fillArc(70,50150,30300);
int i=0;

(i对于动画,您可以使用a移动Pacman图形,并通过改变
fillArc
使用的参数来调整“嘴”打开的角度

可以使用实现与运动控制的
KeyEvents
交互

此外,我将
paint
功能移动到子类
JComponent
中的
paintComponent
方法,以获得更好的绘制性能

相关的:


编辑:

当您开始使用Java时,首先要完成许多任务

  • 使用静态
    Pacman
    图形创建基于
    JComponent
    的类。将绘制逻辑移动到
    paintComponent
  • 让Swing Timer功能正常工作。按照
  • 实现
    键绑定
  • 其他功能,如记分等
  • 二维动画:

    伪代码:

    while programActive:
        deltatime = get_time_since_last_call()
        update_animation_frame(deltatime)
        image = get_animation_frame()
        draw_background()
        draw(image)
        enforce_framerate(24)
    

    与Java相比,在Pygame中学习和做这类事情很容易,但不适合大型项目

    类似的东西可能适用于PacMan图像。它使用基于Java 2D的
    形状
    实例来表示形状,并使用
    仿射变换
    来生成不同的方向


    import java.awt.*;
    导入java.awt.event.*;
    导入java.awt.geom.*;
    导入java.awt.image.buffereImage;
    导入javax.swing.*;
    导入java.io.*;
    导入javax.imageio.imageio;
    PacManShape类{
    私人双户型;
    私人双重轮换;
    最终int maxSize=4;
    静态文件home=新文件(System.getProperty(“user.home”);
    静态文件图像=新文件(主文件,“图像”);
    PacManShape(整数大小,双旋转){
    这个。大小=大小;
    这个旋转=旋转;
    }
    公共区域getPacManShape(双颚){
    面积=新面积(新椭圆2d.Double(0d,0d,size,size));
    双x1=尺寸/2+(2d*尺寸*数学系数(jaws/2d));
    双y1=尺寸/2+(2d*尺寸*数学sin(钳口/2d));
    双x2=x1;
    双y2=尺寸/2-(2d*尺寸*数学sin(钳口/2d));
    多边形口=新多边形();
    嘴。添加点((int)(大小/2),(int)(大小/2));
    口.添加点((int)x1,(int)y1);
    口。添加点((int)x2,(int)y2);
    嘴。添加点((int)(大小/2),(int)(大小/2));
    面积减去(新面积(口));
    返回区;
    }
    公共缓冲区图像getPacManImage(双角度,彩色){
    BuffereImage bi=新的BuffereImage(
    (int)size,(int)size,buffereImage.TYPE_int_ARGB);
    Graphics2D g2=bi.createGraphics();
    g2.设置颜色(颜色);
    g2.fillRect(0,0,(int)size,(int)size);
    AffineTransform rotate=AffineTransform.getRotateInstance(
    旋转,大小/2,大小/2);
    g2.设置变换(旋转);
    面积pacMan=getPacManShape(角度);
    g2.setRenderingHint(
    RenderingHists.KEY\u抗锯齿,
    RenderingHints.VALUE_ANTIALIAS_ON);
    g2.设置颜色(颜色为黄色);
    float[]dist={.15f、.9f};
    Color[]colors={Color.YELLOW,Color.ORANGE};
    Point2D中心=新的Point2D.Double(大小/2,大小/2);
    RadialGradientPaint radial=新的RadialGradientPaint(
    中心,(浮动)(尺寸/2)-2f)、距离、颜色;
    g2.设置油漆(径向);
    g2.填充(pacMan);
    GradientPaint gradient=新GradientPaint(
    0,0,新颜色(255,255,225,220),
    (int)(大小/3),0,新颜色(255,255,255,0);
    g2.设置油漆(梯度);
    g2.填充(pacMan);
    g2.dispose();
    返回bi;
    }
    public void savePacManImage(int q,int num)引发IOException{
    双角度=数学PI*2/3d*((双)数值/(双)最大尺寸);
    BuffereImage bi=getPacManImage(角度、颜色、白色);
    images.mkdirs();
    文件img=新文件(图像,“PacMan-”+q+“x”+num+“.gif”);
    图像IO.write(bi,“gif”,img);
    }
    公共静态void main(字符串[]args){
    试一试{
    对于(int ii=0;ii<4;ii++){
    PacManShape pms=新PacManShape(100,(双)ii*Math.PI/2d);
    对于(int jj=0;jj 2*Math.PI/3){
    chomp=正确;
    }否则,如果(角度<0.01){
    chomp=假;
    }
    if(chomp){
    角度-=diff;
    }否则{
    角度+=差值;
    }
    PacManShape pms=新PacManShape(100,0d);
    Image=pms.getPacManImage(角度,新颜色(0,0,0,0));
    g2.drawImage(图像,0,0,this);
    g2.dispose();
    }
    }
    
    如果要在运行时变换和渲染图像,请尝试从这一系列使用部分透明度来软化边缘的PNG格式图像开始


    有关如何使用动画(使用
    drawImage
    创建图像)、游戏循环等的示例,请参见。也不要覆盖
    绘制(…)
    而是使用
    JPanel
    并覆盖
    paintComponent
    我不确定您的项目的目的,但在游戏中,这种动画是通过一种称为Blitting的技术实现的。它基本上与图像文件(spritesheet)一起工作在这里,你有所有的动画序列,你使用一个系统来重新计算一段时间内图像的视口,创建动画。几乎所有的
    import java.awt.*;
    import java.awt.event.*;
    import java.awt.geom.*;
    import java.awt.image.BufferedImage;
    import javax.swing.*;
    
    import java.io.*;
    import javax.imageio.ImageIO;
    
    class PacManShape {
    
        private double size;
        private double rotation;
        final int maxSize = 4;
        static File home = new File(System.getProperty("user.home"));
        static File images = new File(home, "images");
    
        PacManShape(int size, double rotation) {
            this.size = size;
            this.rotation = rotation;
        }
    
        public Area getPacManShape(double jaws) {
            Area area = new Area(new Ellipse2D.Double(0d, 0d, size, size));
    
            double x1 = size / 2 + (2d * size * Math.cos(jaws / 2d));
            double y1 = size / 2 + (2d * size * Math.sin(jaws / 2d));
            double x2 = x1;
            double y2 = size / 2 - (2d * size * Math.sin(jaws / 2d));
    
            Polygon mouth = new Polygon();
            mouth.addPoint((int) (size / 2), (int) (size / 2));
            mouth.addPoint((int) x1, (int) y1);
            mouth.addPoint((int) x2, (int) y2);
            mouth.addPoint((int) (size / 2), (int) (size / 2));
    
            area.subtract(new Area(mouth));
    
            return area;
        }
    
        public BufferedImage getPacManImage(double angle, Color color) {
            BufferedImage bi = new BufferedImage(
                    (int) size, (int) size, BufferedImage.TYPE_INT_ARGB);
    
            Graphics2D g2 = bi.createGraphics();
    
            g2.setColor(color);
            g2.fillRect(0, 0, (int) size, (int) size);
    
            AffineTransform rotate = AffineTransform.getRotateInstance(
                    rotation, size / 2, size / 2);
            g2.setTransform(rotate);
    
            Area pacMan = getPacManShape(angle);
            g2.setRenderingHint(
                    RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setColor(Color.YELLOW);
            float[] dist = {.15f, .9f};
            Color[] colors = {Color.YELLOW, Color.ORANGE};
            Point2D center = new Point2D.Double(size / 2, size / 2);
            RadialGradientPaint radial = new RadialGradientPaint(
                    center, (float) ((size / 2) - 2f), dist, colors);
            g2.setPaint(radial);
            g2.fill(pacMan);
            GradientPaint gradient = new GradientPaint(
                    0, 0, new Color(255, 255, 225, 220),
                    (int) (size / 3), 0, new Color(255, 255, 255, 0));
            g2.setPaint(gradient);
            g2.fill(pacMan);
    
            g2.dispose();
    
            return bi;
        }
    
        public void savePacManImage(int q, int num) throws IOException {
            double angle = Math.PI*2 / 3d * ((double) num / (double) maxSize);
            BufferedImage bi = getPacManImage(angle, Color.WHITE);
    
            images.mkdirs();
            File img = new File(images, "PacMan-" + q + "x" + num + ".gif");
            ImageIO.write(bi, "gif", img);
        }
    
        public static void main(String[] args) {
    
            try {
                for (int ii = 0; ii < 4; ii++) {
                    PacManShape pms = new PacManShape(100, (double) ii * Math.PI / 2d);
                    for (int jj = 0; jj <= pms.maxSize; jj++) {
                        pms.savePacManImage(ii, jj);
                    }
                }
                Desktop.getDesktop().open(images);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
    
            Runnable r = new Runnable() {
    
                @Override
                public void run() {
                    JPanel gui = new JPanel(new BorderLayout());
    
                    gui.add(new PacManComponent());
    
                    JOptionPane.showMessageDialog(null, gui);
                }
            };
            // Swing GUIs should be created and updated on the EDT
            // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
            SwingUtilities.invokeLater(r);
        }
    }
    
    class PacManComponent extends JPanel {
    
        double angle = 0d;
        int preferredSize = 100;
        double diff = Math.PI / 8;
        boolean chomp = true;
        Timer timer;
    
        PacManComponent() {
            ActionListener listener = new ActionListener() {
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    repaint();
                }
            };
            timer = new Timer(180, listener);
            timer.start();
        }
    
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(preferredSize, preferredSize);
        }
    
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g.create();
            //double size = (getWidth() < getHeight() ? getWidth() : getHeight());
            if (angle > 2 * Math.PI / 3) {
                chomp = true;
            } else if (angle < 0.01) {
                chomp = false;
            }
            if (chomp) {
                angle -= diff;
            } else {
                angle += diff;
            }
            PacManShape pms = new PacManShape(100, 0d);
    
            Image image = pms.getPacManImage(angle, new Color(0, 0, 0, 0));
            g2.drawImage(image, 0, 0, this);
    
            g2.dispose();
        }
    }