Drake Johnson
Drake Johnson

Reputation: 664

Changing the color in basic Java animation

I'm messing around with graphics in Java (specifically through the Swing and AWT libs), and want to move a circle across the screen (making lines) and set the x or y coordinate back to 0 when the line hits the bounds of the canvas. I have no problem with this part of the code.

However, now I'm trying to clear the screen when the coordinates are both 0 (using super.paint(Graphics)) and change the color. The screen clearing works fine, but I can't change the color. It seems, when the coordinates are both 0, an oval of the specified color appears under the streak being made at the (0, 0) position. I, however, want the color of the streak to change color until the coordinates are reset to (0, 0).

Here's my code:

@SuppressWarnings("serial")
public class Game extends JPanel
{
    static final int SCREEN_X = 300;
    static final int SCREEN_Y = 400;
    int x = 0;
    int y = 0;

    private void moveBall()
    {
        x += 1;
        y += 1;

        if (x >= SCREEN_X) x = 0;
        if (y >= SCREEN_Y) y = 0;
    }

    @Override
    public void paint(Graphics g)
    {
        Graphics2D g2d = (Graphics2D) g;

        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        if (x == 0 && y == 0)
        {
            super.paint(g);

            // Generate random value in [0, 5)
            int rand_val = (new Random()).nextInt(5);

            // Init random color variable
            Color rand_color = Color.black;

            // Pick a random color
            switch (rand_val)
            {
            case 0:
                rand_color = Color.black;
                break;

            case 1:
                rand_color = Color.red;
                break;

            case 2:
                rand_color = Color.green;
                break;

            case 3:
                rand_color = Color.blue;
                break;

            case 4:
                rand_color = Color.gray;
                break;
            }

            // I'm assuming I need to do something more here?
            // This is likely where my mistake is...
            g2d.setColor(rand_color);
        }

        g2d.fillOval(x, y, 30, 30);
    }

    public static void main(String[] args) throws InterruptedException
    {
        JFrame frame = new JFrame("Mini Tennis");
        Game game = new Game();

        frame.add(game);
        frame.setSize(SCREEN_X, SCREEN_Y);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        while (true)
        {
            game.moveBall();
            game.repaint();
            Thread.sleep(10);
        }
    }
}

Upvotes: 1

Views: 1024

Answers (2)

c0der
c0der

Reputation: 18792

Note the changes and comments:

public class Game extends JPanel
{
    static final int SCREEN_X = 300;
    static final int SCREEN_Y = 400;
    int x = 0;
    int y = 0;

    private void moveBall()
    {
        x += 1;
        y += 1;

        if (x >= SCREEN_X) {
            x = 0;
        }
        if (y >= SCREEN_Y) {
            y = 0;
        }
    }

    @Override
    public void paintComponent(Graphics g) { //for custom painting override paint componenet

        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        if (x == 0 && y == 0)
        {
            // Generate random value in [0, 5)
            int rand_val = new Random().nextInt(5);

            // Init random color variable
            Color rand_color = Color.black;

            // Pick a random color
            switch (rand_val)
            {
            case 0:
                rand_color = Color.black;
                break;

            case 1:
                rand_color = Color.red;
                break;

            case 2:
                rand_color = Color.green;
                break;

            case 3:
                rand_color = Color.blue;
                break;

            case 4:
                rand_color = Color.gray;
                break;
            }

            g2d.setColor(rand_color);
            g2d.fillRect(0, 0, getWidth(), getHeight()); //clear screen 
        }

        g2d.fillOval(x, y, 30, 30);
    }


Side note: you can define a colors array:

private final Color[] colors = {Color.black, Color.red, Color.green, Color.blue, Color.gray};

To make the code more concise:

@Override
public void paintComponent(Graphics g) { //for custom painting override paint componenet

    Graphics2D g2d = (Graphics2D) g;
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    if (x == 0 && y == 0)
    {
        int rand_val = new Random().nextInt(colors.length);
        Color rand_color = colors[rand_val];
        g2d.setColor(rand_color);
        g2d.fillRect(0, 0, getWidth(), getHeight()); //clear screen
    }

    g2d.fillOval(x, y, 30, 30);
}

Upvotes: 1

Andrew Thompson
Andrew Thompson

Reputation: 168835

// I'm assuming I need to do something more here?
// This is likely where my mistake is...
g2d.setColor(rand_color);

The Graphics2D instance used for this paint is on the verge of being disposed. No good changing the color now.

Instead, change the BG or FG color of the component (the JPanel) itself, then set the color of the graphics object before each paint.

Upvotes: 0

Related Questions