Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
453 views
in Technique[技术] by (71.8m points)

java - Pacman open/close mouth animation

I want to make the pacman open/close mouth animation using the easiest method. Here is my recent code: The problem is, nothing is happening?

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

 }

and here is my draw panel:

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++;




   } 
 }  

  }

The while loop doesn't affect anything, what could be the reason for that?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Something like this might work for PacMan images. It uses a Java 2D based Shape instance to represent the form, and an AffineTransform to produce the different orientations.

PacMan - Right PacMan - Down
PacMan - Up PacMan - Left

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

If you wanted to transform & render images at run-time, try starting with this series of PNG format images that uses partial transparency to soften the edges.

PacMan 1 PacMan 2 PacMan 3 PacMan 4


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...