Thread: Color Game

    #31
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    38
    Rep Power
    2
    Originally Posted by NormR
    When do you want the "other code" executed?
    Do you want to use a Timer that will call the "other code" every so many seconds?
    Do you want to execute the "other code" every time a user clicks on a square?
    Or when?

    What does the "other code" do?
    I want to execute the other code every time the top square changes colour. In other words, whenever the listener is called, execute the playGame() method.
  2. #32
  3. Lord of the Dance
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Oct 2003
    Posts
    3,644
    Rep Power
    1945
    Then you should call playGame() inside mouseClicked.

    Can you try to explain in detail what you want playGame() to do?
    From what i can see you never change the color of rCurrent, which mean prev will never change too.
  4. #33
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    38
    Rep Power
    2
    But playGame() is a method in Game.java and rCurrent is a cRect object.

    mouseClicked is inside cRect.java so how can I call playGame() from cRect, given that rCurrent is required in this method?

    The color of rCurrent changes in the mouseClicked method:
    Code:
    public void mouseClicked(MouseEvent evt){
            int r = gen.nextInt(8);
            color = rArray[r].col();
            System.out.println("Listener called.");
            repaint();
        }
    What I want playGame() to do:
    - For each square in the array, check if the color matches that of "prev".
    - If it does (only one square should):
    (Let's call this square X)
    - Make prev equal the color of rCurrent
    - Update the color of rCurrent to a new random color.
    - Change the listener on rCurrent so that the X is the object that next updates rCurrent.
    - If it doesn't:
    - Skip the square (i.e. rCurrent shouldn't be affected by this color).
    - OR (haven't attempted this bit yet): Have a listener for this sqaure to display a message saying "game over"
    - Wait for user to click a color. Repeat.
  6. #34
  7. Contributing User
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Aug 2010
    Location
    Eastern Florida
    Posts
    3,711
    Rep Power
    348
    Suggestion: use mousePressed instead of mouseClicked to make it easier on users.
    Clicking requires press and release in a certain time span that is sometimes missed.

    Make the class with the listener an inner class and it will be able to call methods in the surrounding class.
    Or pass a reference to the class with the playGame() method to the cRect constructor so the listener method can call the method using the reference.
  8. #35
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    38
    Rep Power
    2
    Originally Posted by NormR
    Suggestion: use mousePressed instead of mouseClicked to make it easier on users.
    Clicking requires press and release in a certain time span that is sometimes missed.

    Make the class with the listener an inner class and it will be able to call methods in the surrounding class.
    Or pass a reference to the class with the playGame() method to the cRect constructor so the listener method can call the method using the reference.
    Ok, I'm not sure if I've implemented exactly what you said, but I seem to have a working system. See code below (select the red square to start)

    I have a new problem now. How do I add listeners to the other squares that would effectively display "game over" and stop the game?

    Game.java
    Code:
    import javax.swing.*;
    import javax.swing.border.*;
    import java.awt.*;
    
    class Game implements Runnable
    {
        private Rect[] rArray;
        private cRect rCurrent = new cRect(Color.blue);
    
        public static void main(String[] args)
        {
            Game program = new Game();
            program.colours();
            SwingUtilities.invokeLater(program);
            program.playGame();
        }
        
        void playGame() {
            rCurrent.setrCurrent(rCurrent);
            rCurrent.playGame(rCurrent);
        }
    
        public void run()
        {
            JFrame w = new JFrame();
            w.setDefaultCloseOperation(w.EXIT_ON_CLOSE);
            w.setTitle("Color Game");
            w.setSize(600, 400);
            w.add(display());
            w.setLocationByPlatform(true);
            w.setVisible(true);
        }
        
        void colours(){
            rArray = rCurrent.getArray();
        }
    
        Box display()
        {
            GridLayout grid = new GridLayout(2, 4, 0, 0);
            Border border1 = BorderFactory.createEmptyBorder(20, 20, 50, 20);
            Border border2 = BorderFactory.createEmptyBorder(0, 0, 5, 0);
            JPanel current = new JPanel();
            Box boxcurr = Box.createVerticalBox();
            JLabel label = new JLabel("Current Colour:");
            current.setAlignmentX(JComponent.CENTER_ALIGNMENT);
            label.setBorder(border2);
            boxcurr.add(label);
            boxcurr.add(rCurrent);
            boxcurr.setBorder(border1);
            current.add(boxcurr);
            Box box = Box.createVerticalBox();
            JPanel colArr = new JPanel();
            colArr.setPreferredSize(new Dimension(500, 200));
            colArr.setLayout(grid);
            JLabel select = new JLabel("Select Previous Colour:");
            for( int i=0; i<8; i++ ) {
                colArr.add(rArray[i]);
            }
            box.add(current);
            box.add(select);
            box.add(colArr);
            return box;
        }
    }
    cRect.java
    Code:
    import javax.swing.*;
    import java.awt.*;
    import java.util.*;
    import java.awt.event.*;
    
    class cRect extends JPanel implements MouseListener {
    
        private Random gen = new Random();
        private Color color = new Color(0, 0, 0);
        private Rect[] rArray = new Rect[8];
        private Color prev = Color.red;
        private cRect something;
        
        cRect() {
            setPreferredSize(new Dimension(75, 75));
            setupcols();
        }
        
        cRect(Color pCol){
            setPreferredSize(new Dimension(75, 75));
            color = pCol;
            setupcols();
        }
        
        void setrCurrent(cRect rCurrent){
            something = rCurrent;
        }
        
        void playGame(cRect rCurrent) {
            int i;
            boolean clickDone = false;
            for( i=0; i<rArray.length; i++ ) {
                rArray[i].removeMouseListener(rCurrent);
                System.out.println("removed listener: " + i);
            }
            for( i=0; i<rArray.length; i++ ) {
                rArray[i].removeMouseListener(rCurrent);
                System.out.println("array col: " + rArray[i].col());
                System.out.println("prev before if:" + prev);
                if( (clickDone==false) && (rArray[i].col().equals(prev)) ) {
                    System.out.println("click listener: " + rArray[i].col());
                    rArray[i].addMouseListener(rCurrent);
                    prev = rCurrent.col();
                    System.out.println("new prev:" + prev);
                    clickDone = true;
                } else {
                    //rArray[i].addMouseListener(
                }
            }
            System.out.println("Current:" + rCurrent.col());
        }
        
        void setupcols(){
            rArray[0] = new Rect(Color.red);
            rArray[1] = new Rect(Color.green);
            rArray[2] = new Rect(Color.blue);
            rArray[3] = new Rect(Color.yellow);
            rArray[4] = new Rect(Color.pink);
            rArray[5] = new Rect(new Color(128, 0, 128));
            rArray[6] = new Rect(new Color(255, 128, 0));
            rArray[7] = new Rect(new Color(202, 225, 255));
        }
        
        Rect[] getArray(){
            return rArray;
        }
        
        Color col(){
            return color;
        }
    
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g;
            g2.setPaint(color);
            g2.fillRect(0, 0, 75, 75);
        }
        
        public void mousePressed(MouseEvent evt){
            int r = gen.nextInt(8);
            color = rArray[r].col();
            System.out.println("Listener called.");
            repaint();
            playGame(something);
        }
        
        public void mouseMoved(MouseEvent evt){}
        public void mouseEntered(MouseEvent evt){}
        public void mouseExited(MouseEvent evt){}
        public void mouseClicked(MouseEvent evt){}
        public void mouseReleased(MouseEvent evt){}
    
    }
    Rect.java
    Code:
    import javax.swing.*;
    import java.awt.*;
    import java.util.*;
    import java.awt.event.*;
    
    class Rect extends JPanel {
    
        private Random gen = new Random();
        private Color[] cols = new Color[8];
        private Color color = new Color(0, 0, 0);
        
        Rect() {
            setPreferredSize(new Dimension(75, 75));
        }
        
        Rect(Color pCol){
            setPreferredSize(new Dimension(75, 75));
            color = pCol;
        }
       
        Color col(){
            return color;
        }
    
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g;
            g2.setPaint(color);
            g2.fillRect(0, 0, 75, 75);
        }
    }
  10. #36
  11. Contributing User
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Aug 2010
    Location
    Eastern Florida
    Posts
    3,711
    Rep Power
    348
    If you added listeners to all of the squares, you could detect if the one that had the mouse press had the right color or not. The EventObject class's getSource() method returns a reference to the square where the mouse was pressed.
  12. #37
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    38
    Rep Power
    2
    Originally Posted by NormR
    If you added listeners to all of the squares, you could detect if the one that had the mouse press had the right color or not. The EventObject class's getSource() method returns a reference to the square where the mouse was pressed.
    That's not exactly what I want though, because the layout and positions of the squares may change as I change the design.

    Is there a way to pass a variable to the listener, like a boolean for whether or not the correct square was clicked?
  14. #38
  15. Contributing User
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Aug 2010
    Location
    Eastern Florida
    Posts
    3,711
    Rep Power
    348
    a way to pass a variable to the listener
    The getSource() method returns a reference to the component that was clicked.
    That reference can be used to determine what you want.
  16. #39
  17. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    38
    Rep Power
    2
    Ok, now my mousePressed() method knows whether the choice was correct or not, how can I stop the game and display "game over" to the user?
  18. #40
  19. Contributing User
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Aug 2010
    Location
    Eastern Florida
    Posts
    3,711
    Rep Power
    348
    how can I stop the game and display "game over" to the user?
    The JOptionPane class could be used to display a message.

    Change some variables and call some methods to stop the game. Look at how the game is controlled and see what needs to be done to stop it.
  20. #41
  21. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    38
    Rep Power
    2
    Originally Posted by NormR
    The JOptionPane class could be used to display a message. Change some variables and call some methods to stop the game.
    I was thinking more along the lines of a new JFrame, however, I can't really display the objects from the class because it's the parent class (Game.java) that handles the display.

    Originally Posted by NormR
    Look at how the game is controlled and see what needs to be done to stop it.
    That's sort of where I need your help, I don't know how to stop it.
  22. #42
  23. Contributing User
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Aug 2010
    Location
    Eastern Florida
    Posts
    3,711
    Rep Power
    348
    Originally Posted by EffX
    That's sort of where I need your help, I don't know how to stop it.
    What is to be stopped?
    Describe what keeps the program going and that will tell you what you need to change to make it stop.

    Calling System.exit(0) will stop the program.
  24. #43
  25. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    38
    Rep Power
    2
    Originally Posted by NormR
    What is to be stopped?
    Describe what keeps the program going and that will tell you what you need to change to make it stop.

    Calling System.exit(0) will stop the program.
    I don't necessarily want to stop the program, just replace the JFrame over the game with a new one saying "game over" and a button to start over.
  26. #44
  27. Lord of the Dance
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Oct 2003
    Posts
    3,644
    Rep Power
    1945
    Before you know how, you should specify when a game is over.
  28. #45
  29. Contributing User
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Aug 2010
    Location
    Eastern Florida
    Posts
    3,711
    Rep Power
    348
    You could remove all the components on the JFrame and rebuild its contents.

IMN logo majestic logo threadwatch logo seochat tools logo