1

I have some questions about how to use ArrayList. I'm new to java, so I would like to know the practical uses of it and the correct way to use one. I have been told that I could use an array list to display my objects, but I can't seem to understand how to add that to my current project.

I am working on displaying 3 pipes at the same time, controlling the speed and refresh rate with timers. I think I finally understand the basics of JFrame and JPanel, but I have been introduced to the mystical CardLayout recently, so any examples on that would also be helpful.

So far, I have been able to add a start menu, which consists of a play button. After the user clicks "Play!", the menu should be replaced by the game panel, and set playerIsReady to true, starting the timers that should add three instances of pipe.java to the screen, each one being moved towards the left by the timer called "speed". All pipes start off to the right of the screen.

I would like to better understand how to add spacing between each pipe object. I am also interested in how I could load and print local images to the screen.

If you try to answer any of these questions, please explain each step in detail, as I am a newcomer to Java. Thank you for taking your time to help. If you are not here to answer a question, I hope that you might be able to learn something from any code/answers here.

Game

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;
import javax.swing.SwingUtilities;

public class Game {

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {             
                // the GUI as seen by the user (without frame)
                final CardLayout cl = new CardLayout();
                final JPanel gui = new JPanel(cl);
                // remove if no border is needed
                gui.setBorder(new EmptyBorder(10,10,10,10));

                JPanel menu = new JPanel(new GridBagLayout());
                JButton playGame = new JButton("Play!");
                ActionListener playGameListener = new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        cl.show(gui, "game");
                    }
                };
                playGame.addActionListener(playGameListener);
                Insets margin = new Insets(20, 50, 20, 50);
                playGame.setMargin(margin);
                menu.add(playGame);
                gui.add(menu);
                cl.addLayoutComponent(menu, "menu");

                final JPanel pipes = new Pipes();
                gui.add(pipes);
                cl.addLayoutComponent(pipes, "game");

                JFrame f = new JFrame("Pipes Game");
                f.add(gui);
                // Ensures JVM closes after frame(s) closed and
                // all non-daemon threads are finished
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                // See http://stackoverflow.com/a/7143398/418556 for demo.
                f.setLocationByPlatform(true);

                // ensures the frame is the minimum size it needs to be
                // in order display the components within it
                f.pack();
                // should be done last, to avoid flickering, moving,
                // resizing artifacts.
                f.setVisible(true);

                /*if (playerIsReady) { 
                    Timer speed = new Timer(10, new ActionListener() {  //pipe speed
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            pipes.move();
                        }
                    });
                    speed.start();

                    Timer refresh = new Timer(30, new ActionListener() {    //refresh rate
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            pipes.repaint();
                        }
                    });
                    refresh.start();
                }*/
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency
        SwingUtilities.invokeLater(r);
    }
}

PipeObject

import java.awt.Graphics;

public class PipeObject {
    //Declare and initialiaze variables
    int x1 = 754;               //xVal start
    int x2 = 75;                //pipe width
                                //total width is 83
    int y1 = -1;                //yVal start
    int y2 = setHeightVal();    //pipe height
    int gap = 130;              //gap height

    public void drawPipe(Graphics g) {

        g.clearRect(0,0,750,500);                       //Clear screen
        g.drawRect(x1,y1,x2,y2);                        //Draw part 1
        g.drawRect(x1-3,y2-1,x2+6,25);                  //Draw part 2
        g.drawRect(x1-3,y2+25+gap,x2+6,25);             //Draw part 3
        g.drawRect(x1,y2+25+gap+25,x2,500-y2-49-gap);   //Draw part 4
    }

    public void move() {
        x1--;
    }

    public int getMyX() {   //To determine where the pipe is horizontally
        return x1-3;
    }

    public int getMyY() {   //To determine where the pipe is vertically
        return y2+25;
    }

    public int setHeightVal() {     //Get a random number and select a preset height
        int num = (int)(9*Math.random() + 1);
        int val = 0;
        if (num == 9)
        {
            val = 295;
        }
        else if (num == 8)
        {
            val = 246;
        }
        else if (num == 7)
        {
            val = 216;
        }
        else if (num == 6)
        {
            val = 185;
        }
        else if (num == 5)
        {
            val = 156;
        }
        else if (num == 4)
        {
            val = 125;
        }
        else if (num == 3)
        {
            val = 96;
        }
        else if (num == 2)
        {
            val = 66;
        }
        else
        {
            val = 25;
        }
        return val;
    }
}
Cyber Storm
  • 217
  • 1
  • 13

1 Answers1

2

So your PipeObject class is just a data model class. the drawPipe method doesn't actually draw anything on its own. You need a JPanel class to render this data, and invoke the drawPipe method in the paintComponent method of the JPanel, passing the Graphics context to it.

Also if yo want to have different x location vlaues, you need a constructor to take in different x values. It seems the y values should be the same, since there are always going to remain on the same y axis. Your constructor in your PipeObject class should look something like this

int x1;   // no need to give them values. 
int x2;   // This will be done when you create a new PipeObject object

public PipeObject(int x1, int x2) {
    this.x1 = x1;
    this.x1 = x2;
}

And when you create the new PipeObject object, you will pass different values to it. To sum up the two points above, you will have something like this.

public class PipePanel extends JPanel {
    List<PipeObject> pipes = new ArrayList<PipeObject>();

    public PipePanel() {
        pipes.add(new PipeObject(100, 90));
        pipes.add(new PipeObject(300, 290));
        pipes.add(new PipeObject(500, 490));
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        for ( PipeObject pipe : pipes ){
            pipe.drawPipe(g);
        }
    }
}

Then you can add and instance of PipesPanel to your frame. Also note, in your PipesPanel you should override the getPreferredSize, so it will have a preferred size, and you can just pack() the frame

@Override
public Dimension getPreferredSize() {
    return new Dimension(800, 500);    // or what ever values you want for screen size
}

Also, when you want to manipulate or animate the PipeObject you just call one of itsmethods likemove(), then callrepaint`. Something like

Timer timer = new Timer(50, new ActionListener(){
    public void actionPerformed(ActionEvent e) {
        for (PipeObject pipe : pipes) {
            pipe.move();
        }
        repaint();
    }
});
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • Keep the [**Really Big Index**](http://docs.oracle.com/javase/tutorial/reallybigindex.html) as a reference tutorial. Try to complete a couple sections every day. It'll bring you up to speed on java basics. Objects are a very basic Java concept. You can start with the section [**Object-Oriented Programming Concepts**](http://docs.oracle.com/javase/tutorial/java/concepts/index.html). Happy Coding! – Paul Samsotha Feb 07 '14 at 05:42
  • Any time you're being presented with a concept you don't understand, 95% of the time, you will find a reference tutorial in the link. – Paul Samsotha Feb 07 '14 at 05:43
  • Read from top to bottom or what? 0.0 – Cyber Storm Feb 07 '14 at 06:55
  • _"That's a big index"_ - It's pretty much the Java SE language in a nutshell. You need to learn how to reference it. The beginning are the basics. After you learn the basics, then its safe to jump around.Well the sections are labeled. I'd start with the object orients concepts I linked. I'd say the basics go from everything from the top until `Essential classes`. Like I said, take it a day at a time. Don't rush to learn. It good to know the basics. – Paul Samsotha Feb 07 '14 at 07:00