Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 2 of 2

Thread: Running ChainRXN like game

  1. #1
    Junior Member
    Join Date
    Sep 2013
    Posts
    16
    Thanks
    1
    Thanked 0 Times in 0 Posts

    Default Running ChainRXN like game

    I can't quite seem to get this code to work correctly. This example is from User:Ciancun on github

    I think I have it fairly close to working, which is why I'm posting here rather than giving up on it. In the code, it is left to the user how to define the game logic in the main class. I'll show you how I tried to do it below. Unfortunately, the designer seems to have become fairly inactive, so contacting him directly doesn't seem promising.

    package ball;
     
    import java.awt.Color;
    import java.awt.Graphics2D;
    import java.awt.Rectangle;
     
    import java.awt.geom.Ellipse2D;
    import java.awt.geom.Rectangle2D;
    import gui.RxnPanel;
     
    public class Ball {
     
        private float x;
        private float y;
        private float radius;
        private float sX;
        private float sY;
     
        private final transient Ellipse2D.Float ellipse = new Ellipse2D.Float();
     
        private static float initialRadius = 6f;
        private static float finalRadius = 40f;
        private static long expandDuration = 900000000L; // 1.5 sec expand
     
        static double getInitialRadius() {
            return initialRadius;
        }
     
        public static void setInitialRadius(int initialRadius) {
            Ball.initialRadius = initialRadius / 10f;
        }
     
        static double getFinalRadius() {
            return finalRadius;
        }
     
        public static void setFinalRadius(int finalRadius) {
            Ball.finalRadius = finalRadius / 10f;
        }
     
        static long getExpandDuration() {
            return expandDuration;
        }
     
        public static void setExpandDuration(int expandDuration) {
            Ball.expandDuration = (long) ((expandDuration / 1000f + 0.5f)*1000000000);
        }
     
        private int chainCount;
        private long explodeTime;
        private long lastUpdateTime;
        private Color color;
        private boolean ended;
     
        BallManager manager;
     
        public int getChainCount() {
            return chainCount;
        }
     
        Ball(float x, float y, float sX, float sY, Color color) {
            this(x, y, sX, sY, color, 0);
        }
     
        Ball(float x, float y, float sX, float sY, Color color, long explodeTime) {
            this.x = x;
            this.y = y;
            this.radius = initialRadius;
            this.sX = sX;
            this.sY = sY;
            this.explodeTime = explodeTime;
            this.chainCount = 0;
            this.color = new Color(color.getRed(), color.getGreen(), color.getBlue(),
                    127);
            this.ended = false;
        }
     
        public boolean isExploded() {
            return explodeTime != 0;
        }
     
        private void move(long time) {
            if (lastUpdateTime == 0) {
                return;
            }
            long delta = time - lastUpdateTime;
            x += delta * sX;
            y += delta * sY;
     
            Rectangle boundries = manager.getBoundries();
            if (x < radius) {
                x = radius + 0.01f;
                sX = -sX;
            } else if (x > boundries.width - radius) {
                x = boundries.width - radius - 0.01f;
                sX = -sX;
            }
     
            if (y < radius) {
                y = radius + 0.01f;
                sY = -sY;
            } else if (y > boundries.height - radius) {
                y = boundries.height - radius - 0.01f;
                sY = -sY;
            }
     
            Ball collider = manager.checkCollision(this);
            if (collider != null) {
                explodeTime = time;
                chainCount = collider.chainCount + 1;
                manager.informCollision(this);
            }
        }
     
        private float getExpansionFraction(long time) {
            return (float) (time - explodeTime) / expandDuration;
        }
     
        private void expand(long time) {
            float expansionFraction = getExpansionFraction(time);
            if (expansionFraction < 0.75f) {
                radius = initialRadius + (finalRadius - initialRadius) * expansionFraction * 4/3;
            } else if (expansionFraction < 2f) {
                radius = finalRadius;
            } else if (expansionFraction < 2.33f) {
                float inverseFraction = 3 * (2.33f - expansionFraction);
                radius = initialRadius + (finalRadius - initialRadius) * inverseFraction;
                color = new Color(color.getRed(), color.getGreen(), color.getBlue(),
                        (int) (127 * inverseFraction));
            } else {
                ended = true;
            }
        }
     
        public void update(long time) {
            if (isExploded()) {
                expand(time);
            } else {
                move(time);
            }
            ellipse.x = x - radius;
            ellipse.y = y - radius;
            ellipse.width = ellipse.height = radius * 2;
            lastUpdateTime = time;
        }
     
        public int getPoint() {
            return 100 * chainCount * chainCount * chainCount;
        }
     
        public Ellipse2D getBounds() {
            return ellipse;
        }
     
        public boolean isEnded() {
            return ended;
        }
     
        public void draw(Graphics2D g) {
            if (!ended) {
                Color c = g.getColor();
                g.setColor(color);
                g.fill(getBounds());
                if (isExploded() && getPoint() != 0 &&
                        System.nanoTime() < explodeTime + expandDuration * 0.75) {
                    String point = "+"+RxnPanel.decimalFormat.format(getPoint());
                    Rectangle2D bounds = g.getFontMetrics().getStringBounds(point, g);
                    g.setColor(Color.WHITE);
                    g.drawString(point, (float) (x - bounds.getWidth()/2),
                                        (float) (y + bounds.getHeight()/2));
                }
                g.setColor(c);
            }
        }
     
    }

    package ball;
     
    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
     
    import java.awt.Color;
    import java.awt.Graphics2D;
    import java.awt.Rectangle;
    import java.awt.Shape;
     
    import java.util.LinkedList;
    import java.util.List;
     
     
    /**
     *
     * @author ToGo
     */
    public class BallManager implements CollisionListener, Runnable {
     
        private float minSpeed = 0.00000005f;
        private float maxSpeed = 0.00000008f;
     
        private final List<CollisionListener> collisionListeners = new LinkedList<CollisionListener>();
        private final List<GameEndListener> gameEndListeners = new LinkedList<GameEndListener>();
     
        private final List<Ball> balls = new LinkedList<Ball>();
        private final int ballsToExplode;
        private final int totalBallCount;
     
        private final Rectangle boundries;
     
        private int totalPoint;
        private int nExplodedBalls;
     
        private boolean initiallyClicked;
     
        private Thread logicThread;
     
        public void setMaxSpeed(int maxSpeed) {
            this.maxSpeed = 0.0000001f * maxSpeed / 1000;
        }
     
        public void setMinSpeed(int minSpeed) {
            this.minSpeed = 0.0000001f * minSpeed / 1000;
        }
     
        public int getTotalPoint() {
            return totalPoint;
        }
     
        public int getNExplodedBalls() {
            return nExplodedBalls;
        }
     
        public int getTotalBallCount() {
            return totalBallCount;
        }
     
        public BallManager(Rectangle boundries, int maxSpeed, int minSpeed, int totalBallCount, int ballsToExplode) {
            this.boundries = boundries;
            setMaxSpeed(maxSpeed);
            setMinSpeed(minSpeed);
            this.initiallyClicked = false;
            this.totalBallCount = totalBallCount;
            this.ballsToExplode = ballsToExplode;
            this.nExplodedBalls = 0;
            for (int i = 0; i < totalBallCount; ++i) {
                balls.add(createBall());
            }
            addCollisionListener(this);
        }
     
        public void initialClick(int x, int y, long time) {
            if (!initiallyClicked) {
                Ball ball = new Ball(x, y, 0, 0, new Color(0.5f, 0.5f, 0.5f), time);
                ball.manager = this;
                balls.add(ball);
                initiallyClicked = true;
                System.out.println(Ball.getExpandDuration());
            }
        }
     
        public boolean isInitiallyClicked() {
            return initiallyClicked;
        }
     
        private Ball createBall() {
            float x = (float) (Ball.getInitialRadius() + (boundries.width - 2 * Ball.getInitialRadius()) * Math.random());
            float y = (float) (Ball.getInitialRadius() + (boundries.height - 2 * Ball.getInitialRadius()) * Math.random());
            double speed = (maxSpeed - minSpeed)*Math.random() + minSpeed;
            double angle = 2*Math.PI*Math.random();
            float sX = (float) (Math.cos(angle)*speed);
            float sY = (float) (Math.sin(angle)*speed);
            Color color = new Color(
                    (int) (255 * Math.random()),
                    (int) (255 * Math.random()),
                    (int) (255 * Math.random()));
            Ball b = new Ball(x, y, sX, sY, color);
            b.manager = this;
            return b;
        }
     
        public Rectangle getBoundries() {
            return boundries;
        }
     
        public void update(long time) {
            List<Ball> endeds = new LinkedList<Ball>();
            synchronized (balls) {
                for (Ball b : balls) {
                    b.update(time);
                    if (b.isEnded()) {
                        endeds.add(b);
                    }
                }
                balls.removeAll(endeds);
            }
            boolean gameEnded = initiallyClicked;
            for (Ball b : balls) {
                if (b.isExploded()) {
                    gameEnded = false;
                    break;
                }
            }
            if (gameEnded) {
                for (GameEndListener gameEndListener : gameEndListeners) {
                    gameEndListener.gameEnded(ballsToExplode - nExplodedBalls);
                }
                stop();
            }
        }
     
        public boolean isGoalAchieved() {
            return ballsToExplode <= nExplodedBalls;
        }
     
        public void draw(Graphics2D g) {
            synchronized (balls) {
                for (Ball b : balls) {
                    b.draw(g);
                }
            }
        }
     
        Ball checkCollision(Ball ball) {
            Shape shape = ball.getBounds();
            synchronized (balls) {
                for (Ball b : balls) {
                    if (b.isExploded() && b.getBounds().intersects(shape.getBounds2D())) {
                        return b;
                    }
                }
            }
            return null;
        }
     
        public void addCollisionListener(CollisionListener listener) {
            collisionListeners.add(listener);
        }
     
        public void addGameEndListener(GameEndListener listener) {
            gameEndListeners.add(listener);
        }
     
        void informCollision(Ball ball) {
            for (CollisionListener listener : collisionListeners) {
                listener.collided(ball);
            }
        }
     
        public void collided(Ball ball) {
            totalPoint += ball.getPoint();
            ++nExplodedBalls;
        }
     
        public void run() {
            logicThread = Thread.currentThread();
            while(true) {
                update(System.nanoTime());
                try {
                    Thread.sleep(10);
                } catch (InterruptedException ex) {
                    return;
                }
            }
        }
     
        public void stop() {
            if (logicThread == null) {
                throw new IllegalStateException("Game is not started.");
            }
            logicThread.interrupt();
        }
     
    }

    package ball;
     
    public interface CollisionListener {
     
        void collided(Ball ball);
     
    }

    package ball;
     
    public interface GameEndListener {
     
        void gameEnded(int remainingBalls);
     
    }

    package gui;
     
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.Properties;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.swing.JColorChooser;
    import javax.swing.JFileChooser;
    import javax.swing.JFrame;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
     
    import static java.lang.Integer.*;
     
    /**
     *
     * @author ToGo
     */
    public class OptionPanel extends javax.swing.JFrame {
     
        private Properties properties;
     
        private void load(File file) throws IOException {
            properties = new Properties();
            if (file.exists()) {
                properties.load(new FileInputStream(file));
            }
            minSpeedSlider.setValue(parseInt(properties.getProperty("minSpeed", "500")));
            maxSpeedSlider.setValue(parseInt(properties.getProperty("maxSpeed", "800")));
            minRadiusSlider.setValue(parseInt(properties.getProperty("minRadius", "60")));
            maxRadiusSlider.setValue(parseInt(properties.getProperty("maxRadius", "400")));
            expandTimeSlider.setValue(parseInt(properties.getProperty("expandTime", "400")));
            widthField.setText(properties.getProperty("frameWidth", "640"));
            heightField.setText(properties.getProperty("frameHeight", "400"));
            ballCountField.setText(properties.getProperty("ballCount", "50"));
            explodeCountField.setText(properties.getProperty("explodeCount", "34"));
            backgroundColorLabel.setBackground(Color.decode(properties.getProperty("background", "0x090507")));
        }
     
        private void save(File file) throws IOException {
            properties.setProperty("minSpeed", String.valueOf(minSpeedSlider.getValue()));
            properties.setProperty("maxSpeed", String.valueOf(maxSpeedSlider.getValue()));
            properties.setProperty("minRadius", String.valueOf(minRadiusSlider.getValue()));
            properties.setProperty("maxRadius", String.valueOf(maxRadiusSlider.getValue()));
            properties.setProperty("expandTime", String.valueOf(expandTimeSlider.getValue()));
            properties.setProperty("frameWidth", widthField.getText());
            properties.setProperty("frameHeight", heightField.getText());
            properties.setProperty("ballCount", ballCountField.getText());
            properties.setProperty("explodeCount", explodeCountField.getText());
            properties.setProperty("background", toHexString(backgroundColorLabel.getBackground()));
            properties.store(new FileOutputStream(file), "");
        }
     
        /** Creates new form OptionPanel */
        public OptionPanel() {
            initComponents();
            setLocationRelativeTo(null);
            reset();
        }
     
        /** This method is called from within the constructor to
         * initialize the form.
         * WARNING: Do NOT modify this code. The content of this method is
         * always regenerated by the Form Editor.
         */
        @SuppressWarnings("unchecked")
        // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
        private void initComponents() {
     
            jPanel1 = new javax.swing.JPanel();
            jLabel1 = new javax.swing.JLabel();
            maxSpeedSlider = new javax.swing.JSlider();
            jLabel2 = new javax.swing.JLabel();
            minSpeedSlider = new javax.swing.JSlider();
            jLabel3 = new javax.swing.JLabel();
            maxRadiusSlider = new javax.swing.JSlider();
            jLabel4 = new javax.swing.JLabel();
            minRadiusSlider = new javax.swing.JSlider();
            jLabel5 = new javax.swing.JLabel();
            expandTimeSlider = new javax.swing.JSlider();
            jPanel2 = new javax.swing.JPanel();
            jLabel6 = new javax.swing.JLabel();
            jLabel7 = new javax.swing.JLabel();
            widthField = new javax.swing.JTextField();
            heightField = new javax.swing.JTextField();
            jPanel3 = new javax.swing.JPanel();
            jLabel8 = new javax.swing.JLabel();
            ballCountField = new javax.swing.JTextField();
            jLabel9 = new javax.swing.JLabel();
            explodeCountField = new javax.swing.JTextField();
            jLabel10 = new javax.swing.JLabel();
            backgroundColorLabel = new javax.swing.JLabel();
            startButton = new javax.swing.JButton();
            loadButton = new javax.swing.JButton();
            saveButton = new javax.swing.JButton();
            jButton1 = new javax.swing.JButton();
     
            setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
            setTitle("ChnRxn Configuration");
     
            jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Ball Properties"));
     
            jLabel1.setText("Max Speed :");
     
            maxSpeedSlider.setMaximum(1000);
            maxSpeedSlider.setPaintLabels(true);
            maxSpeedSlider.setPaintTicks(true);
            maxSpeedSlider.setValue(800);
            maxSpeedSlider.addChangeListener(new javax.swing.event.ChangeListener() {
                public void stateChanged(javax.swing.event.ChangeEvent evt) {
                    maxSpeedSliderStateChanged(evt);
                }
            });
     
            jLabel2.setText("Min Speed : ");
     
            minSpeedSlider.setMaximum(1000);
            minSpeedSlider.setPaintLabels(true);
            minSpeedSlider.setPaintTicks(true);
            minSpeedSlider.setValue(500);
            minSpeedSlider.addChangeListener(new javax.swing.event.ChangeListener() {
                public void stateChanged(javax.swing.event.ChangeEvent evt) {
                    minSpeedSliderStateChanged(evt);
                }
            });
     
            jLabel3.setText("Max Radius : ");
     
            maxRadiusSlider.setMaximum(1000);
            maxRadiusSlider.setPaintLabels(true);
            maxRadiusSlider.setPaintTicks(true);
            maxRadiusSlider.setValue(400);
            maxRadiusSlider.addChangeListener(new javax.swing.event.ChangeListener() {
                public void stateChanged(javax.swing.event.ChangeEvent evt) {
                    maxRadiusSliderStateChanged(evt);
                }
            });
     
            jLabel4.setText("Min Radius : ");
     
            minRadiusSlider.setMaximum(1000);
            minRadiusSlider.setPaintLabels(true);
            minRadiusSlider.setPaintTicks(true);
            minRadiusSlider.setValue(60);
            minRadiusSlider.addChangeListener(new javax.swing.event.ChangeListener() {
                public void stateChanged(javax.swing.event.ChangeEvent evt) {
                    minRadiusSliderStateChanged(evt);
                }
            });
     
            jLabel5.setText("Fade In/Out Time : ");
     
            expandTimeSlider.setMaximum(1000);
            expandTimeSlider.setPaintLabels(true);
            expandTimeSlider.setPaintTicks(true);
            expandTimeSlider.setValue(425);
     
            javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
            jPanel1.setLayout(jPanel1Layout);
            jPanel1Layout.setHorizontalGroup(
                jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel1Layout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                        .addGroup(jPanel1Layout.createSequentialGroup()
                            .addComponent(jLabel1)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 23, Short.MAX_VALUE)
                            .addComponent(maxSpeedSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGroup(jPanel1Layout.createSequentialGroup()
                            .addComponent(jLabel2)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 23, Short.MAX_VALUE)
                            .addComponent(minSpeedSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGroup(jPanel1Layout.createSequentialGroup()
                            .addComponent(jLabel3)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 23, Short.MAX_VALUE)
                            .addComponent(maxRadiusSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGroup(jPanel1Layout.createSequentialGroup()
                            .addComponent(jLabel4)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 23, Short.MAX_VALUE)
                            .addComponent(minRadiusSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGroup(jPanel1Layout.createSequentialGroup()
                            .addComponent(jLabel5)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(expandTimeSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
            );
     
            jPanel1Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jLabel1, jLabel2, jLabel3, jLabel4, jLabel5});
     
            jPanel1Layout.setVerticalGroup(
                jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel1Layout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                        .addComponent(jLabel1)
                        .addComponent(maxSpeedSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                        .addComponent(jLabel2)
                        .addComponent(minSpeedSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                        .addComponent(jLabel3)
                        .addComponent(maxRadiusSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                        .addComponent(jLabel4)
                        .addComponent(minRadiusSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                        .addComponent(jLabel5)
                        .addComponent(expandTimeSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
            );
     
            jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Frame Properties"));
     
            jLabel6.setText("Width : ");
     
            jLabel7.setText("Height : ");
     
            widthField.setText("640");
     
            heightField.setText("400");
     
            javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
            jPanel2.setLayout(jPanel2Layout);
            jPanel2Layout.setHorizontalGroup(
                jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel2Layout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(jLabel6)
                        .addComponent(jLabel7))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 110, Short.MAX_VALUE)
                    .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                        .addComponent(heightField)
                        .addComponent(widthField, javax.swing.GroupLayout.DEFAULT_SIZE, 65, Short.MAX_VALUE))
                    .addContainerGap())
            );
     
            jPanel2Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jLabel6, jLabel7});
     
            jPanel2Layout.setVerticalGroup(
                jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel2Layout.createSequentialGroup()
                    .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel6)
                        .addComponent(widthField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel7)
                        .addComponent(heightField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
            );
     
            jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("Game Properties"));
     
            jLabel8.setText("Total Number of Balls : ");
     
            ballCountField.setText("54");
     
            jLabel9.setText("Number of Balls to Explode : ");
     
            explodeCountField.setText("40");
     
            jLabel10.setText("Background Color : ");
     
            backgroundColorLabel.setBackground(new java.awt.Color(51, 255, 0));
            backgroundColorLabel.setOpaque(true);
            backgroundColorLabel.addMouseListener(new java.awt.event.MouseAdapter() {
                public void mouseClicked(java.awt.event.MouseEvent evt) {
                    backgroundColorLabelMouseClicked(evt);
                }
            });
     
            javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
            jPanel3.setLayout(jPanel3Layout);
            jPanel3Layout.setHorizontalGroup(
                jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel3Layout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(jLabel8)
                        .addComponent(jLabel9)
                        .addComponent(jLabel10))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                        .addComponent(backgroundColorLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel3Layout.createSequentialGroup()
                            .addGap(10, 10, 10)
                            .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(ballCountField, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 68, Short.MAX_VALUE)
                                .addComponent(explodeCountField, javax.swing.GroupLayout.DEFAULT_SIZE, 68, Short.MAX_VALUE))))
                    .addContainerGap())
            );
     
            jPanel3Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jLabel8, jLabel9});
     
            jPanel3Layout.setVerticalGroup(
                jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel3Layout.createSequentialGroup()
                    .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel8)
                        .addComponent(ballCountField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel9)
                        .addComponent(explodeCountField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                    .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel10)
                        .addComponent(backgroundColorLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
            );
     
            startButton.setText("Start!");
            startButton.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    startButtonActionPerformed(evt);
                }
            });
     
            loadButton.setText("Load");
            loadButton.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    loadButtonActionPerformed(evt);
                }
            });
     
            saveButton.setText("Save");
            saveButton.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    saveButtonActionPerformed(evt);
                }
            });
     
            jButton1.setText("Reset");
            jButton1.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    jButton1ActionPerformed(evt);
                }
            });
     
            javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
            getContentPane().setLayout(layout);
            layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addContainerGap()
                    .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                            .addComponent(jButton1)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                            .addComponent(saveButton)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                            .addComponent(loadButton)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                            .addComponent(startButton)))
                    .addContainerGap())
            );
            layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                            .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                .addComponent(startButton)
                                .addComponent(loadButton)
                                .addComponent(saveButton)
                                .addComponent(jButton1)))
                        .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addContainerGap())
            );
     
            pack();
        }// </editor-fold>//GEN-END:initComponents
     
        private void startButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_startButtonActionPerformed
            JFrame.setDefaultLookAndFeelDecorated(true);
            JFrame frame = new JFrame("ChnRxn");
            final RxnPanel rxnPanel = new RxnPanel(frame);
            rxnPanel.restartGame(
                    minRadiusSlider.getValue(), maxRadiusSlider.getValue(),
                    expandTimeSlider.getValue(),
                    minSpeedSlider.getValue(), maxSpeedSlider.getValue(),
                    Integer.parseInt(ballCountField.getText()),
                    Integer.parseInt(explodeCountField.getText()),
                    new Dimension(Integer.parseInt(widthField.getText()), 
                    Integer.parseInt(heightField.getText())),
                    backgroundColorLabel.getBackground());
            frame.addWindowListener(new WindowAdapter() {
                @Override
                public void windowClosed(WindowEvent e) {
                    rxnPanel.getManager().stop();
                    OptionPanel.this.setVisible(true);
                }
     
            });
            frame.add(rxnPanel);
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
            this.setVisible(false);
        }//GEN-LAST:event_startButtonActionPerformed
     
        private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
            minRadiusSlider.setValue(60);
            maxRadiusSlider.setValue(400);
            expandTimeSlider.setValue(400);
            minSpeedSlider.setValue(500);
            maxSpeedSlider.setValue(800);
            ballCountField.setText("50");
            explodeCountField.setText("34");
            widthField.setText("640");
            heightField.setText("400");
            backgroundColorLabel.setBackground(Color.decode("0x090507"));
        }//GEN-LAST:event_jButton1ActionPerformed
     
        private void maxSpeedSliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_maxSpeedSliderStateChanged
            if (maxSpeedSlider.getValue() < minSpeedSlider.getValue()) {
                maxSpeedSlider.setValue(minSpeedSlider.getValue());
                maxSpeedSlider.updateUI();
            }
        }//GEN-LAST:event_maxSpeedSliderStateChanged
     
        private void minSpeedSliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_minSpeedSliderStateChanged
            if (minSpeedSlider.getValue() > maxSpeedSlider.getValue()) {
                minSpeedSlider.setValue(maxSpeedSlider.getValue());
                minSpeedSlider.updateUI();
            }
        }//GEN-LAST:event_minSpeedSliderStateChanged
     
        private void maxRadiusSliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_maxRadiusSliderStateChanged
            if (maxRadiusSlider.getValue() < minRadiusSlider.getValue()) {
                maxRadiusSlider.setValue(minRadiusSlider.getValue());
                maxRadiusSlider.updateUI();
            }
        }//GEN-LAST:event_maxRadiusSliderStateChanged
     
        private void minRadiusSliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_minRadiusSliderStateChanged
            if (minRadiusSlider.getValue() > maxRadiusSlider.getValue()) {
                minRadiusSlider.setValue(maxRadiusSlider.getValue());
                minRadiusSlider.updateUI();
            }
        }//GEN-LAST:event_minRadiusSliderStateChanged
     
        private void loadButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_loadButtonActionPerformed
            JFileChooser fileChooser = new JFileChooser();
            int result = fileChooser.showOpenDialog(this);
            if(result == JFileChooser.APPROVE_OPTION) {
                File file = fileChooser.getSelectedFile();
                try {
                    load(file);
                } catch (IOException ex) {
                    Logger.getLogger(OptionPanel.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }//GEN-LAST:event_loadButtonActionPerformed
     
        private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveButtonActionPerformed
            JFileChooser fileChooser = new JFileChooser();
            int result = fileChooser.showSaveDialog(this);
            if(result == JFileChooser.APPROVE_OPTION) {
                File file = fileChooser.getSelectedFile();
                try {
                    save(file);
                } catch (IOException ex) {
                    Logger.getLogger(OptionPanel.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }//GEN-LAST:event_saveButtonActionPerformed
     
        private void backgroundColorLabelMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_backgroundColorLabelMouseClicked
            Color newColor = JColorChooser.showDialog(this, 
                    "Choose Background Color", null);
            backgroundColorLabel.setBackground(newColor);
            properties.setProperty("background", toHexString(newColor));
        }//GEN-LAST:event_backgroundColorLabelMouseClicked
     
        private String toHexString(Color color) {
            int rgb = color.getBlue() + (color.getGreen() << 8) +
                    (color.getRed() << 16);
            return "0x" + Integer.toHexString(rgb);
        }
     
        private void reset() {
            try {
                load(new File(""));
            } catch (IOException ex) {
            }
        }
     
        /**
        * @param args the command line arguments
        */
        public static void main(String args[]) {
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException ex) {
                        Logger.getLogger(OptionPanel.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (InstantiationException ex) {
                        Logger.getLogger(OptionPanel.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (IllegalAccessException ex) {
                        Logger.getLogger(OptionPanel.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (UnsupportedLookAndFeelException ex) {
                        Logger.getLogger(OptionPanel.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    new OptionPanel().setVisible(true);
                }
            });
        }
     
        // Variables declaration - do not modify//GEN-BEGIN:variables
        private javax.swing.JLabel backgroundColorLabel;
        private javax.swing.JTextField ballCountField;
        private javax.swing.JSlider expandTimeSlider;
        private javax.swing.JTextField explodeCountField;
        private javax.swing.JTextField heightField;
        private javax.swing.JButton jButton1;
        private javax.swing.JLabel jLabel1;
        private javax.swing.JLabel jLabel10;
        private javax.swing.JLabel jLabel2;
        private javax.swing.JLabel jLabel3;
        private javax.swing.JLabel jLabel4;
        private javax.swing.JLabel jLabel5;
        private javax.swing.JLabel jLabel6;
        private javax.swing.JLabel jLabel7;
        private javax.swing.JLabel jLabel8;
        private javax.swing.JLabel jLabel9;
        private javax.swing.JPanel jPanel1;
        private javax.swing.JPanel jPanel2;
        private javax.swing.JPanel jPanel3;
        private javax.swing.JButton loadButton;
        private javax.swing.JSlider maxRadiusSlider;
        private javax.swing.JSlider maxSpeedSlider;
        private javax.swing.JSlider minRadiusSlider;
        private javax.swing.JSlider minSpeedSlider;
        private javax.swing.JButton saveButton;
        private javax.swing.JButton startButton;
        private javax.swing.JTextField widthField;
        // End of variables declaration//GEN-END:variables
     
     
    }

    package gui;
     
    import java.awt.Color;
    import java.awt.Cursor;
    import java.awt.Dimension;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Image;
    import java.awt.Point;
    import java.awt.RadialGradientPaint;
    import java.awt.Rectangle;
    import java.awt.RenderingHints;
    import java.awt.Toolkit;
     
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.geom.Rectangle2D;
     
    import java.awt.image.BufferedImage;
     
    import java.text.DecimalFormat;
     
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
     
    import java.util.logging.Level;
    import java.util.logging.Logger;
     
    import javax.swing.JFrame;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
     
    import ball.Ball;
    import ball.BallManager;
    import ball.CollisionListener;
    import ball.GameEndListener;
     
    /**
     *
     * @author ToGo
     */
    public class RxnPanel extends JPanel implements Runnable, GameEndListener, CollisionListener {
     
        private static final ExecutorService executorService = Executors.newCachedThreadPool();
     
        private static BufferedImage sphereCursor;
        private static BufferedImage nullCursor;
     
        private static final Font pointFont = new Font("Impact", Font.PLAIN, 12);
        private static final Font scoreFont = new Font("Impact", Font.PLAIN, 30);
     
        public static DecimalFormat decimalFormat = new DecimalFormat("###,###,###,###");
     
        private static Image getSphereCursor() {
            if (sphereCursor == null) {
                int radius = 40;
                sphereCursor = new BufferedImage(2*radius, 2*radius, BufferedImage.TYPE_INT_ARGB);
                Graphics2D g = sphereCursor.createGraphics();
                Point center = new Point(radius, radius);
                g.setPaint(new RadialGradientPaint(center, radius,
                        new float[]{0.1f, 0.2f, 0.9f},
                        new Color[]{
                            new Color(0.5f, 0.5f, 0.5f, 0.7f),
                            new Color(0.7f, 0.7f, 0.7f, 0.5f),
                            new Color(0.5f, 0.5f, 0.5f, 0.01f)}));
                g.fillOval(0, 0, 2*radius, 2*radius);
                g.dispose();
            }
            return sphereCursor;
        }
     
        private static Image getNullCursor() {
            if (nullCursor == null) {
                nullCursor = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
            }
            return nullCursor;
        }
     
        private JFrame frame;
        private Dimension preferredSize = new Dimension(640, 400);
        private BallManager manager;
        private Point mouseLocation;
        private Color backgroundColor = new Color(0.1f, 0.1f, 0.12f);
        private Color achievementColor = new Color(1f, 1f, 1f, 0.5f);
     
        @Override
        public Dimension getPreferredSize() {
            return preferredSize;
        }
     
        public RxnPanel(JFrame frame) {
            super();
            this.frame = frame;
            RxnMouseListener rxnMouseListener = new RxnMouseListener();
            addMouseListener(rxnMouseListener);
            addMouseMotionListener(rxnMouseListener);
            Cursor cursor = Toolkit.getDefaultToolkit().createCustomCursor(getNullCursor(), new Point(), "null");
            setCursor(cursor);
            executorService.execute(this);
        }
     
        private int initialRadius, finalRadius, expandDuration,
                minSpeed, maxSpeed, totalBall, goal;
     
        public void restartGame(int initialRadius, int finalRadius, int expandDuration,
                int minSpeed, int maxSpeed, int totalBall, int goal, Dimension size, Color background) {
            if (manager != null) {
                manager.stop();
            }
            this.initialRadius = initialRadius;
            this.finalRadius = finalRadius;
            this.expandDuration = expandDuration;
            this.minSpeed = minSpeed;
            this.maxSpeed = maxSpeed;
            this.totalBall = totalBall;
            this.backgroundColor = background;
            this.goal = goal;
            Ball.setInitialRadius(initialRadius);
            Ball.setFinalRadius(finalRadius);
            Ball.setExpandDuration(expandDuration);
            this.preferredSize = size;
            manager = new BallManager(new Rectangle(size), minSpeed, maxSpeed, totalBall, goal);
            manager.addGameEndListener(this);
            manager.addCollisionListener(this);
            collided(null);
            executorService.execute(manager);
        }
     
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g;
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setColor(backgroundColor);
            g2.fillRect(0, 0, getWidth(), getHeight());
            g2.setFont(pointFont);
            if (manager != null) {
                manager.draw(g2);
                if (!manager.isInitiallyClicked() && mouseLocation != null) {
                    Image img = getSphereCursor();
                    g2.drawImage(img, mouseLocation.x - img.getWidth(null) / 2,
                            mouseLocation.y - img.getHeight(null) / 2, null);
                }
                if (manager.isGoalAchieved()) {
                    g2.setColor(achievementColor);
                    g2.fillRect(0, 0, getWidth(), getHeight());
                }
                g2.setColor(Color.BLACK);
                g2.setFont(scoreFont);
                String score = decimalFormat.format(manager.getTotalPoint());
                Rectangle2D rect = g2.getFontMetrics().getStringBounds(score, g);
                g2.drawString(score, (float) (preferredSize.width - rect.getWidth()),
                        (float) (preferredSize.height));
            }
        }
     
        public void run() {
            while(true) {
                repaint();
                try {
                    Thread.sleep(10);
                } catch (InterruptedException ex) {
                    Logger.getLogger(RxnPanel.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
     
        public void gameEnded(int remainingBalls) {
            if (remainingBalls <= 0) {
                JOptionPane.showMessageDialog(this,
                        "Congratulations!\n" +
                        "You've made " + decimalFormat.format(manager.getTotalPoint())
                        + " points!", "Game Over!",
                        JOptionPane.INFORMATION_MESSAGE);
            } else {
                JOptionPane.showMessageDialog(this,
                        "Sorry, you had " + remainingBalls + " balls remained.",
                        "Game Over!", JOptionPane.INFORMATION_MESSAGE);
            }
            restartGame(initialRadius, finalRadius, expandDuration, minSpeed,
                    maxSpeed, totalBall, goal, preferredSize, backgroundColor);
        }
     
        public void collided(Ball ball) {
            frame.setTitle("ChnRxn " + manager.getNExplodedBalls() + "/" + manager.getTotalBallCount());
        }
     
        public BallManager getManager() {
            return manager;
        }
     
        private class RxnMouseListener extends MouseAdapter {
     
            @Override
            public void mouseReleased(MouseEvent e) {
                if (manager != null) {
                    manager.initialClick(e.getX(), e.getY(), System.nanoTime());
                }
            }
     
            @Override
            public void mouseDragged(MouseEvent e) {
                mouseMoved(e);
            }
     
            @Override
            public void mouseMoved(MouseEvent e) {
                mouseLocation = e.getPoint();
            }
     
        }
     
    }

    package main;
     
    import gui.RxnPanel;
     
    import java.awt.Color;
    import java.awt.Dimension;
     
    import javax.swing.JFrame;
     
     
    /**
     *
     * @author ToGo
     */
    public class Main extends JFrame {
     
    	public Main(){
     
    	}
     
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
    JFrame frame = new JFrame();
    RxnPanel rp = new RxnPanel(frame);
    rp.restartGame(3, 6, 10, 1, 10, 100, 5, new Dimension(400,400), Color.black);
        frame.add(rp);
        frame.setPreferredSize(new Dimension(600,600));
        frame.pack();
        frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        }
     
    }

    The restart game is supposed to define all the variables important to the game, such as number of balls, background colour etc. (the labeling on the constructor is quite clear). Everything within the main method is my own code. It was originally empty. if you run it the way I have it, what you get is a black game screen on which you can see the cursor icon. however, no balls, even though if you follow the logic from the restartGame() method, the createBall() method will be called the number of times defined in the parameters. If you click, it will also activate the explosion, which you will not see, but you will know took place because the level will end and you won't have hit any balls (because they aren't there). Maybe someone more used to github than me can see what I'm doing incorrectly.

    The original can be found here, if people aremore comfortable using github directly

    --- Update ---

    Oh, never mind. My numbers were too small. Far too small. What is it about this forum? Every time I post something here, I end up solving it moments afterwards anyway. I should probably make this a more frequent habit...


  2. #2
    Super Moderator
    Join Date
    Jun 2013
    Location
    So. Maryland, USA
    Posts
    5,520
    My Mood
    Mellow
    Thanks
    215
    Thanked 698 Times in 680 Posts

    Default Re: Running ChainRXN like game

    Whatever works.

Similar Threads

  1. Replies: 21
    Last Post: June 12th, 2013, 11:33 AM
  2. How can I get my card game running?
    By Skynet928 in forum What's Wrong With My Code?
    Replies: 1
    Last Post: February 5th, 2013, 09:27 AM
  3. Tetris Mobile Game is not Running
    By HacKofDeatH in forum Java ME (Mobile Edition)
    Replies: 12
    Last Post: February 11th, 2012, 02:05 AM
  4. Tetris Mobile Game is not running.
    By HacKofDeatH in forum What's Wrong With My Code?
    Replies: 2
    Last Post: January 30th, 2012, 09:52 AM
  5. Random Errors Occurring When Running Game in Eclipse
    By WhenThCome4Me in forum Java IDEs
    Replies: 22
    Last Post: September 1st, 2011, 06:29 AM