0

I am working on a circular health bar for a top-down 2d shooter and would like some opinions of the best way to do this in only graphics2D. Wondering if drawing many arcs or just using images would be best.

piechesse
  • 39
  • 1
  • 7
  • 1
    You mean like a pie/wedge shape? Try an [`Arc2D`](http://docs.oracle.com/javase/7/docs/api/java/awt/geom/Arc2D.html) with closure type `PIE`. – Geobits Oct 03 '13 at 23:27
  • @Geobits - if you post that as an answer, I will upvote it. – Dawood ibn Kareem Oct 03 '13 at 23:33
  • If he confirms he wants a pie, I will. "Portions of a circle" is somewhat vague. – Geobits Oct 03 '13 at 23:35
  • I admire your restraint. I don't really see what "portions of circles based on percentages" could possibly mean, other than a pie chart. – Dawood ibn Kareem Oct 03 '13 at 23:41
  • The first thing I thought of was an arc section of a thick "ring". Probably because I use something similar as a battery meter on my phone. Though, I suppose you could still do that with `Arc2D` and change the stroke width. – Geobits Oct 03 '13 at 23:44

1 Answers1

3

The answer depends on what you want to achieve...

This is a very basic example...

enter image description here

You can go backwards

enter image description here

Even start at a different angle.

enter image description here

With a little bit of work you could reduce the extended so you could have an "open" progress, for example, starting at 245 degrees with a total extent of 270 degrees if you wanted to

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Arc2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class CircleProgress {

    public static void main(String[] args) {
        new CircleProgress();
    }

    public CircleProgress() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new ProgressPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class ProgressPane extends JPanel {

        private float progress;
        private float startAt = 270;
        private float direction = -1;
        private Timer timer;

        public ProgressPane() {
            timer = new Timer(80, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    float value = getProgress();
                    if (value >= 1f) {
                        timer.stop();
                    }
                    setProgress(value += 0.01);
                }
            });
        }

        public void setProgress(float progress) {
            if (progress < 0.0) {
                progress = 0;
            } else if (progress > 1f) {
                progress = 1f;
            }
            this.progress = progress;
            repaint();
        }

        public float getProgress() {
            return progress;
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(100, 100);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            float extent = (360f * getProgress()) * direction;
            int width = getWidth();
            int height = getHeight();
            int radius = Math.min(width, height);

            int x = (width - radius) / 2;
            int y = (height - radius) / 2;

            g2d.setColor(Color.YELLOW);
            Arc2D arc = new Arc2D.Double(x, y, radius, radius, startAt, extent, Arc2D.PIE);
            g2d.fill(arc);

            g2d.dispose();
        }
    }

}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • @DavidWallace If you liked that, check out [this answer](http://stackoverflow.com/a/14437899/418556). ;) – Andrew Thompson Oct 04 '13 at 00:53
  • @MadProgrammer No need for apologies. Wait.. am I supposed to apologize for already upvoting *your* answer? Not that I'm likely to offer that apology, just curious really.. ;) – Andrew Thompson Oct 04 '13 at 00:58
  • @MadProgrammer BTW - If I'd realized those images were to be 'smacked down' to only a few colors, I'd have used a solid fill. They (which now include my own profile pic.) look horrid in 'blocks of color'.. :( – Andrew Thompson Oct 04 '13 at 01:00