Psp-like animated background in Java

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

Post Reply
wearymemory
Chaos Rift Junior
Chaos Rift Junior
Posts: 209
Joined: Thu Feb 12, 2009 8:46 pm

Psp-like animated background in Java

Post by wearymemory »

Useful for applications that ooze cool. Behavior, colors, and size are fully customizable.
GIF example of what it looks like in action:
Image
(400 frames total; 200 different frames in order, and in reverse for a seamless animation.)
The class has a main method which shows how to use it, but beware: It's undocumented.
PspBackground.java

Code: Select all

package misc;

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.CubicCurve2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;

public class PspBackground {

    private List<Curve> curves = new ArrayList<Curve>();
    private Dimension size;
    private Timer timer;
    private BufferedImage image;
    private List<ActionListener> repaintListeners = new ArrayList<ActionListener>();

    public PspBackground(Dimension size) {
        this.size = new Dimension(size);
        timer = new Timer(25, new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                image = new BufferedImage(
                        (int) PspBackground.this.size.getWidth(),
                        (int) PspBackground.this.size.getHeight(),
                        BufferedImage.TYPE_INT_ARGB);

                Graphics2D g2 = image.createGraphics();

                g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
                g2.setRenderingHint(RenderingHints.KEY_RENDERING,
                        RenderingHints.VALUE_RENDER_QUALITY);

                g2.setStroke(new BasicStroke(4F));

                for (Curve c : curves) {
                    for (int i = 100; i > 0; i--) {
                        Color color = c.getColor();
                        int r = color.getRed();
                        int g = color.getGreen();
                        int b = color.getBlue();
                        g2.setColor(new Color(r, g, b, i));
                        g2.draw(c.getCurve());
                        g2.translate(0, 1);
                    }
                    g2.translate(0, -100);
                    c.update();
                }

                g2.dispose();

                timer.setDelay(rand(1, 125));

                for (ActionListener a : repaintListeners) {
                    a.actionPerformed(new ActionEvent(PspBackground.this,
                            ActionEvent.ACTION_PERFORMED, "repaint"));
                }
            }
        });
        timer.start();
    }

    private int rand(double lo, double hi) {
        return (int) (lo + Math.random() * (1 + hi - lo));
    }

    public void setCurve(Curve c) {
        CubicCurve2D curve2d = c.getCurve();

        double diffy1 = curve2d.getCtrlY1() - curve2d.getY1();
        double diffy2 = curve2d.getCtrlY2() - curve2d.getY2();

        double qh = size.getHeight() * .25;
        double q2h = size.getHeight() * .5;
        double qw = size.getWidth() * .25;
        double q3w = size.getWidth() * .75;

        double x1 = 0;
        double y1 = q2h;

        double ctrlx1 = qw;
        double ctrly1 = q2h + diffy1;

        double ctrlx2 = q3w;
        double ctrly2 = q2h + diffy2;

        double x2 = size.getWidth();
        double y2 = q2h;

        double minctrlx1 = qw - rand(0, qw);
        double minctrly1 = q2h - rand(0, qh);

        double maxctrlx1 = qw + rand(0, qw);
        double maxctrly1 = q2h + rand(0, qh);

        double minctrlx2 = q3w - rand(0, qw);
        double minctrly2 = q2h - rand(0, qh);

        double maxctrlx2 = q3w + rand(0, qw);
        double maxctrly2 = q2h + rand(0, qh);

        double deltax1 = c.getDeltaX1();
        double deltay1 = c.getDeltaY1();

        double deltax2 = c.getDeltaX2();
        double deltay2 = c.getDeltaY2();

        curve2d.setCurve(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2);

        c.setCurve(curve2d,
                minctrlx1, minctrly1,
                maxctrlx1, maxctrly1,
                minctrlx2, minctrly2,
                maxctrlx2, maxctrly2,
                deltax1, deltay1,
                deltax2, deltay2,
                c.getColor());
    }

    public BufferedImage getImage() {
        return image;
    }

    public Dimension getSize() {
        return new Dimension(size);
    }

    public List<Curve> getCurves() {
        return curves;
    }

    public List<ActionListener> getRepaintListeners() {
        return repaintListeners;
    }

    public void setSize(Dimension size) {
        this.size = new Dimension(size);
    }

    public void addRepaintListener(ActionListener repaintListener) {
        repaintListeners.add(repaintListener);
    }

    public void removeRepaintListener(ActionListener repaintListener) {
        repaintListeners.remove(repaintListener);
    }

    public void addCurve(Curve c) {
        curves.add(c);
    }

    public void removeCurve(Curve c) {
        curves.remove(c);
    }

    public static class Curve {

        private CubicCurve2D curve;
        private double minctrlx1;
        private double minctrly1;
        private double maxctrlx1;
        private double maxctrly1;
        private double minctrlx2;
        private double minctrly2;
        private double maxctrlx2;
        private double maxctrly2;
        private double deltax1;
        private double deltay1;
        private double deltax2;
        private double deltay2;
        private Color color;

        public Curve(CubicCurve2D curve2D,
                double deltax1, double deltay1,
                double deltax2, double deltay2,
                Color color) {
            this.curve = curve2D;
            this.deltax1 = deltax1;
            this.deltay1 = deltay1;
            this.deltax2 = deltax2;
            this.deltay2 = deltay2;
            this.color = color;
        }

        public void update() {
            double x1 = curve.getX1();
            double y1 = curve.getY1();

            double ctrlx1 = curve.getCtrlX1();
            double ctrly1 = curve.getCtrlY1();

            double ctrlx2 = curve.getCtrlX2();
            double ctrly2 = curve.getCtrlY2();

            double x2 = curve.getX2();
            double y2 = curve.getY2();

            if (ctrlx1 <= minctrlx1) {
                deltax1 = Math.abs(deltax1);
            }
            if (ctrlx1 >= maxctrlx1) {
                deltax1 = -Math.abs(deltax1);
            }

            if (ctrly1 <= minctrly1) {
                deltay1 = Math.abs(deltay1);
            }
            if (ctrly1 >= maxctrly1) {
                deltay1 = -Math.abs(deltay1);
            }

            if (ctrlx2 <= minctrlx2) {
                deltax2 = Math.abs(deltax2);
            }
            if (ctrlx2 >= maxctrlx2) {
                deltax2 = -Math.abs(deltax2);
            }

            if (ctrly2 <= minctrly2) {
                deltay2 = Math.abs(deltay2);
            }
            if (ctrly2 >= maxctrly2) {
                deltay2 = -Math.abs(deltay2);
            }

            ctrlx1 += deltax1;
            ctrly1 += deltay1;

            ctrlx2 += deltax2;
            ctrly2 += deltay2;

            curve.setCurve(x1, y1, ctrlx1, ctrly1, ctrlx2, ctrly2, x2, y2);
        }

        public void setCurve(CubicCurve2D curve2d,
                double minCtrlX1, double minCtrlY1,
                double maxCtrlX1, double maxCtrlY1,
                double minCtrlX2, double minCtrlY2,
                double maxCtrlX2, double maxCtrlY2,
                double deltaX1, double deltaY1,
                double deltaX2, double deltaY2,
                Color color) {
            this.curve = curve2d;
            this.minctrlx1 = minCtrlX1;
            this.minctrly1 = minCtrlY1;
            this.maxctrlx1 = maxCtrlX1;
            this.maxctrly1 = maxCtrlY1;
            this.minctrlx2 = minCtrlX2;
            this.minctrly2 = minCtrlY2;
            this.maxctrlx2 = maxCtrlX2;
            this.maxctrly2 = maxCtrlY2;
            this.deltay1 = deltaX1;
            this.deltay1 = deltaY1;
            this.deltax2 = deltaX2;
            this.deltay2 = deltaY2;
            this.color = color;
        }

        public Color getColor() {
            return color;
        }

        public void setColor(Color color) {
            this.color = color;
        }

        public CubicCurve2D getCurve() {
            return curve;
        }

        public void setCurve(CubicCurve2D curve) {
            this.curve = curve;
        }

        public double getDeltaX1() {
            return deltax1;
        }

        public void setDeltaX1(double deltax1) {
            this.deltax1 = deltax1;
        }

        public double getDeltaX2() {
            return deltax2;
        }

        public void setDeltaX2(double deltax2) {
            this.deltax2 = deltax2;
        }

        public double getDeltaY1() {
            return deltay1;
        }

        public void setDeltaY1(double deltay1) {
            this.deltay1 = deltay1;
        }

        public double getDeltaY2() {
            return deltay2;
        }

        public void setDeltaY2(double deltay2) {
            this.deltay2 = deltay2;
        }

        public double getMaxCtrlX1() {
            return maxctrlx1;
        }

        public void setMaxCtrlX1(double maxctrlx1) {
            this.maxctrlx1 = maxctrlx1;
        }

        public double getMaxCtrlX2() {
            return maxctrlx2;
        }

        public void setMaxCtrlX2(double maxctrlx2) {
            this.maxctrlx2 = maxctrlx2;
        }

        public double getMaxCtrlY1() {
            return maxctrly1;
        }

        public void setMaxCtrlY1(double maxctrly1) {
            this.maxctrly1 = maxctrly1;
        }

        public double getMaxCtrlY2() {
            return maxctrly2;
        }

        public void setMaxCtrlY2(double maxctrly2) {
            this.maxctrly2 = maxctrly2;
        }

        public double getMinCtrlX1() {
            return minctrlx1;
        }

        public void setMinCtrlX1(double minctrlx1) {
            this.minctrlx1 = minctrlx1;
        }

        public double getMinCtrlX2() {
            return minctrlx2;
        }

        public void setMinCtrlX2(double minctrlx2) {
            this.minctrlx2 = minctrlx2;
        }

        public double getMinCtrlY1() {
            return minctrly1;
        }

        public void setMinCtrlY1(double minctrly1) {
            this.minctrly1 = minctrly1;
        }

        public double getMinCtrlY2() {
            return minctrly2;
        }

        public void setMinCtrlY2(double minctrly2) {
            this.minctrly2 = minctrly2;
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                JFrame f = new JFrame("PspBackground");
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                final Dimension d = new Dimension(250, 250);

                final PspBackground background = new PspBackground(d);

                Curve c1 = new Curve(new CubicCurve2D.Double(),
                        1, -1, 1, 1, Color.CYAN);
                Curve c2 = new Curve(new CubicCurve2D.Double(),
                        1, -1, 1, 1, Color.CYAN.brighter());

                background.setCurve(c1);
                background.setCurve(c2);

                background.addCurve(c1);
                background.addCurve(c2);

                final JPanel c = new JPanel() {

                    @Override
                    protected void paintComponent(Graphics g) {
                        Graphics2D g2 = (Graphics2D) g;
                        GradientPaint p = new GradientPaint(0, 0, Color.BLUE,
                                0, getHeight(), new Color(20, 170, 255));
                        g2.setPaint(p);
                        g2.fillRect(0, 0, getWidth(), getHeight());
                        g2.drawImage(background.getImage(), 0, 0,
                                getWidth(), getHeight(), this);
                    }

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

                background.addRepaintListener(new ActionListener() {

                    public void actionPerformed(ActionEvent e) {
                        c.repaint();
                    }
                });

                f.add(c);

                f.pack();
                f.setVisible(true);
            }
        });
    }
}

Last edited by wearymemory on Sun Aug 22, 2010 4:26 pm, edited 3 times in total.
User avatar
MrDeathNote
ES Beta Backer
ES Beta Backer
Posts: 594
Joined: Sun Oct 11, 2009 9:57 am
Current Project: cocos2d-x project
Favorite Gaming Platforms: SNES, Sega Megadrive, XBox 360
Programming Language of Choice: C/++
Location: Belfast, Ireland
Contact:

Re: Psp-like animated background in Java

Post by MrDeathNote »

Sweet, looks pretty cool.
http://www.youtube.com/user/MrDeathNote1988

Image
Image

"C makes it easy to shoot yourself in the foot. C++ makes it
harder, but when you do, it blows away your whole leg." - Bjarne Stroustrup
User avatar
dandymcgee
ES Beta Backer
ES Beta Backer
Posts: 4709
Joined: Tue Apr 29, 2008 3:24 pm
Current Project: https://github.com/dbechrd/RicoTech
Favorite Gaming Platforms: NES, Sega Genesis, PS2, PC
Programming Language of Choice: C
Location: San Francisco
Contact:

Re: Psp-like animated background in Java

Post by dandymcgee »

Indeed, very plasma-like.
Falco Girgis wrote:It is imperative that I can broadcast my narcissistic commit strings to the Twitter! Tweet Tweet, bitches! :twisted:
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Re: Psp-like animated background in Java

Post by Falco Girgis »

Wow, that's really kickass!
Post Reply