Pacman abrir / cerrar la boca de animación

Quiero hacer la animación de apertura / cierre de pacman usando el método más fácil. Aquí está mi código reciente: ¿El problema es que no está pasando nada?

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

y aquí está mi panel de dibujo:

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

El ciclo while no afecta nada, ¿cuál podría ser el motivo?

Algo así podría funcionar para las imágenes de PacMan. Utiliza una instancia de Shape basada en Java 2D para representar el formulario y una AffineTransform para producir las diferentes orientaciones.

PacMan - DerechaPacMan - Abajo
PacMan - arribaPacMan - Izquierda

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

Si desea transformar y representar imágenes en tiempo de ejecución, intente comenzar con esta serie de imágenes en formato PNG que utiliza transparencia parcial para suavizar los bordes.

PacMan 1PacMan 2PacMan 3PacMan 4

Para la animación, puede usar un temporizador de swing para mover el gráfico de Pacman, así como para ajustar el ángulo por el que se abre la “boca”, variando los parámetros utilizados por fillArc .

La interacción con KeyEvents para el control del movimiento se puede lograr utilizando enlaces clave .

Además, movería la funcionalidad de paint a un método paintComponent en un JComponent para obtener un mejor rendimiento de pintura.

Relacionado: Pintura con Swing


Editar:

Como está iniciando Java, hay una serie de tareas para trabajar primero

  1. Crea la clase basada en JComponent con un gráfico estático de Pacman . Mueva su lógica de pintura a paintComponent
  2. Obtenga la funcionalidad de Swing Timer funcionando. Siga la guía de Oracle para Temporizadores .
  3. Implementar los Key Bindings
  4. Otra funcionalidad como la puntuación, etc.

Animación 2d: http://en.wikipedia.org/wiki/File:The_Horse_in_Motion.jpg

Pseudocódigo:

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

Aprender y hacer este tipo de cosas en Pygame sería fácil en comparación con Java, pero no apto para proyectos de mayor envergadura