Something like this might work for PacMan images. It uses a Java 2D-based Shape instance to represent the shape and AffineTransform to create different orientations.




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); } };
If you want to convert and render images at runtime, try starting with this series of PNG images, which uses partial transparency to soften the edges.



