1

I have a Java Game i need to restart it when the user presses the restart button. My code snippets :

package projectflappy;
//imports
 public class TheGame extends JFrame  implements MouseListener{
 JPanel jp;
 //declaration of the varibles
   ....
 int x_ball = 30;
int y_ball = 200;
int x_width = 500;
int y_height = 500;
Label img = new Label();
int count = 5 , test = -4000;
int i; //for ball loop
Ellipse2D Ball;
int cord_xup1 = 175,cord_xdown1 = 175;
int cord_xup2 = 320,cord_xdown2 = 320;
int cord_xup3 = 460,cord_xdown3 = 460;
int cord_xup4 = 585,cord_xdown4 = 585;
int cord_xup5 = 700,cord_xdown5 = 700;
Boolean flag = true;
RoundRectangle2D up1,down1,up2,down2,up3,down3,up4,down4,up5,down5;
Font font = new Font("Matura MT Script Capitals",Font.ROMAN_BASELINE,40);
Font font1 = new Font("Matura MT Script Capitals",Font.ROMAN_BASELINE,20);
Font font3 = new Font("Matura MT Script Capitals",Font.ROMAN_BASELINE,20);
Font font4 = new Font("Matura MT Script Capitals",Font.ROMAN_BASELINE,10);
float das[] = {10.0f};
BasicStroke color = new   BasicStroke(10,BasicStroke.CAP_ROUND,BasicStroke.JOIN_BEVEL,20.0f,das,0.0f); 


private CellRendererPane crp = new CellRendererPane(); 

GradientPaint gp2 = new GradientPaint(20, 0, 
Color.DARK_GRAY, 0, 10, Color.GRAY, true);


    GradientPaint gp3 = new GradientPaint(30, 0, 
    Color.BLACK, 0, 20, Color.GREEN, true);

   Toolkit kit = Toolkit.getDefaultToolkit();

   //Getting the "background.jpg" image we have in the folder
      Image background = kit.getImage("D:\\College\\Programs\\ProjectFLAPPY\\src\\projectflappy\\1.png");

   JLabel a = new JLabel("Get Ready ! Click to Start.");
   JLabel retry = new JLabel(new          
  ImageIcon("D:\\College\\Programs\\ProjectFLAPPY\\src\\projectflappy\\unnamed.png"));
//constructor
public TheGame() throws IOException 
{
    super("Simple Drawing");
    setSize(x_width, y_height);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setVisible(true);

    jp = new DrawingPanel();
    add(jp);

    addMouseListener(this);


}
// Timer class initiazation--animating the ball

ActionListener action = new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent ae) {
       update();

       repaint();
    }
};
Timer t = new Timer(50,action);

public void mouseClicked(MouseEvent e) {
     // mouse events for animating 
}

// for drawing on the panel
class DrawingPanel extends JPanel{
    private static final long serialVersionUID = 1L;

    public DrawingPanel() {
        setPreferredSize(new Dimension(300, 300));
        setLayout(null);
        retry.setVisible(false);
        retry.setBounds(175,260,46,46);
        a.setForeground(Color.YELLOW);
        a.setFont(font1);
        a.setVisible(true);
        a.setBounds(105,200,300,100);
        add(a);
        add(retry);

    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D d = (Graphics2D)g;
        d.drawImage(background, -270,-30, this);
        Ball = new Ellipse2D.Double(x_ball,y_ball,30,30);

        d.setColor(Color.green);
        d.setFont(font3);


        up1 = new RoundRectangle2D.Double(cord_xup1,-5,30,175,20,20);
        down1 = new RoundRectangle2D.Double(cord_xdown1,310,30,155,20,20);

        up2 = new RoundRectangle2D.Double(cord_xup2,-5,30,200,20,20);
        down2 = new RoundRectangle2D.Double(cord_xdown2,310,30,175,20,20);

        up3 = new RoundRectangle2D.Double(cord_xup3,-5,30,230,20,20);
        down3 = new RoundRectangle2D.Double(cord_xdown3,350,30,135,20,20);

        up4 = new RoundRectangle2D.Double(cord_xup4,-5,30,115,20,20);
        down4 = new RoundRectangle2D.Double(cord_xdown4,240,30,115,20,20);

        d.setPaint(gp2);
        d.setStroke(color);
        d.fill(up1);
        d.fill(down1);

        d.fill(up2);
        d.fill(down2);

        d.fill(up3);
        d.fill(down3);

        d.fill(up4);
        d.fill(down4);


        d.setPaint(gp3);
        d.setStroke(color);
        d.fill(Ball);
        d.setColor(Color.BLACK);
        d.setFont(font1);
        d.drawString(""+score ,200,50);
        if( Ball.intersects(up1.getBounds()) || Ball.intersects(down1.getBounds()) || Ball.intersects(up2.getBounds()) || Ball.intersects(down2.getBounds()) || Ball.intersects(up3.getBounds()) || Ball.intersects(down3.getBounds()) || Ball.intersects(up4.getBounds()) || Ball.intersects(down4.getBounds()))
    {
        t.stop();
        flag = false;
        d.setColor(Color.red);
        d.setFont(font);
        d.drawString("Game Over : "+score ,100,250);
        retry.setVisible(true);
    }
        ****this is the retry button actually it is a JLabel i have used a mouse event over it
        retry.addMouseListener( new MouseListener(){
         @Override
            public void mouseClicked(MouseEvent e) {
                ***i have tried this but doesnt work.
                new DrawingPanel();
                t.restart();
            }

            @Override
            public void mousePressed(MouseEvent e) {
               // throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }

            @Override
            public void mouseExited(MouseEvent e) {
                //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
            }
});
    }

}   


public void update()
{
    cord_xdown1 -= 5;
    cord_xup1 -= 5;

    cord_xdown2 -= 5;
    cord_xup2 -= 5;

    cord_xdown3 -= 5;
    cord_xup3 -= 5;

    cord_xdown4 -= 5;
    cord_xup4 -= 5;

    cord_xdown5 -= 5;
    cord_xup5 -= 5;

    if( cord_xup1 <=-20)
    {
        cord_xup1 = 500;
        cord_xdown1 = 500;
    }
    if( cord_xup2 <=-20)
    {
        cord_xup2 = 500;
        cord_xdown2 = 500;
    }
    if( cord_xup3 <=-20)
    {
        cord_xup3 = 500;
        cord_xdown3 = 500;
    }
    if( cord_xup4 <=-20)
    {
        cord_xup4 = 500;
        cord_xdown4 = 500;
    }
    if( cord_xup5 <=-20)
    {
        cord_xup5 = 500;
        cord_xdown5 = 500;
    }

    if(count >= 0)
    {
        y_ball = y_ball - 7;
        count--;

        if( y_ball == y_height)
        {
            t.stop();
        }
    }
    else
    {
        y_ball = y_ball + 7;
        if( y_ball == y_height-70)
        {
            t.stop();
        }
    }

    if(cord_xdown1 == x_ball || cord_xdown2 == x_ball || cord_xdown3 == x_ball || cord_xdown4  == x_ball)
        {   
            score = score+1;

        }

}
 public static void main(String[] args) throws IOException {
    new TheGame();

}

}

I have tried something but it doesn't work. Give me some idea on how to work on this. And when I try to do something like this

  new TheGame();

n number of windows get opened up. I don't get that. I have removed all the declarations and Java imports for reducing the length of the code. Please help. Thanks.

question
  • 392
  • 1
  • 4
  • 15
Rehan
  • 3,813
  • 7
  • 37
  • 58
  • Is there a reason for adding the first `DrawingPanel` to the frame, but not the new one? Why should a single `new DrawingPanel();` change anything if it is not displayed anywhere? – Tom Dec 20 '14 at 11:23
  • I just tried it blindly @Tom I don't have any idea about it. – Rehan Dec 20 '14 at 11:29
  • Well, then look in the `TheGame` constructor and see what you've done there with the `DrawingPanel` and try to understand why that works. Then you should be able to understand what you need to do, to replace the old `DrawingPanel` with a new one. – Tom Dec 20 '14 at 11:32
  • I have added the `DrawingPanel` to the `JPanel`. I thought to add the `JPanel` again in the main class `TheGame.add(jp)` but that doesn't even exist. – Rehan Dec 20 '14 at 11:41
  • `DrawingPanel` is a `JPanel` itself, why should you add it to one? If you need your `TheGame` reference, then pass it to your panel. – Tom Dec 20 '14 at 11:43
  • Im trying to understand what you are trying to make me understand. I have passed the `TheGame()` to the `JPanel` like this `jp.add(new TheGame());` . This actually works but another Window also get created. – Rehan Dec 20 '14 at 11:53
  • Why do you want a new `TheGame` instance? You already have one and you shouldn't *add* this reference to the panel, you should *pass* that reference to your panel to use it in a method in your `DrawingPanel` class. – Tom Dec 20 '14 at 11:55
  • I tried all the possibilities with the clues you have given but I'm not able to come to a conclusion. I don't know whose reference should be passed to the `JPanel`. – Rehan Dec 20 '14 at 12:04
  • `TheGame` is your JFrame, that means this is your main windows that displays your whole game. Therefore it is responsible in displaying the `DrawingPanel`. If you want a new game, when it might be enough to remove the old panel and insert a new one. In order to remove the old panel in your `mouseClicked` method, this method needs the `TheGame` reference to call `theGame.remove(currentDrawinPanel); theGame.add(newDrawingPanel);` (these variable names are made up, but I guess you get the point). You need to think about how you can store the reference of one class in another one. – Tom Dec 20 '14 at 12:10
  • Ya I understood now. And now I'm able to add new 'DrawingPanel' but how do I remove the old one? 'DrawingPanel.this.remove();' doesn't see to work. – Rehan Dec 20 '14 at 12:23
  • You need a reference of the old `DrawingPanel`. Since you're inside that class, the keyword `this` might help, but you have to "play" a little with it, since the method `mouseClicked` is inside of `MouseListener` and `this` might reference to it, instead of the panel. – Tom Dec 20 '14 at 12:26
  • I'm not able to get the reference of that. Give me the solution or a clue to get it. – Rehan Dec 20 '14 at 12:42
  • I'm breaking my head. Give me a clue atleast @Tom – Rehan Dec 20 '14 at 13:22
  • http://stackoverflow.com/questions/5666134/what-is-the-difference-between-class-this-and-this-in-java – Tom Dec 20 '14 at 13:32
  • 'DrawingPanel.this.removeall(); 'and 'DrawingPane.this.remove(jp); 'doesn't work – Rehan Dec 20 '14 at 14:00
  • Please give me the solution. I still didn't find it. Please. – Rehan Dec 20 '14 at 14:37
  • can you provide the variable declaration part as well , it is getting difficult to execute – VaibJ Dec 22 '14 at 09:43
  • I have declared all the variables as global. @VaibJ – Rehan Dec 24 '14 at 12:35
  • yes , but give the values you have set instead of //declaration of the varibles – VaibJ Dec 24 '14 at 12:53
  • I have updated the code. have a look. @VaibJ – Rehan Dec 24 '14 at 17:48

2 Answers2

0

Move your timer code and your action listener into the constructor:

//constructor
public TheGame() throws IOException 
{
    super("Simple Drawing");
    setSize(x_width, y_height);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setVisible(true);

    jp = new DrawingPanel();
    add(jp);

    addMouseListener(this);
  // Timer class initiazation--animating the ball

ActionListener action = new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent ae) {
       update();

       repaint();
    }
};
Timer t = new Timer(50,action);

}

Try calling this method from the restart buttons onclick listener:

retry.addMouseListener( new MouseListener(){
     @Override
        public void mouseClicked(MouseEvent e) {
         restartApplication();
        }


//------------------------------------------------------------------------------

public void restartApplication()
{
  final String javaBin = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
  final File currentJar = new File(TheGame.class.getProtectionDomain().getCodeSource().getLocation().toURI());

  /* is it a jar file? */
  if(!currentJar.getName().endsWith(".jar"))
    return;

  /* Build command: java -jar application.jar */
  final ArrayList<String> command = new ArrayList<String>();
  command.add(javaBin);
  command.add("-jar");
  command.add(currentJar.getPath());

  final ProcessBuilder builder = new ProcessBuilder(command);
  builder.start();
  System.exit(0);
}
Petro
  • 3,484
  • 3
  • 32
  • 59
  • Nope,it doesn't work. Instead it is called n number of times when u add it ti the click method. Checked it by adding a message dialog box. – Rehan Dec 24 '14 at 18:51
  • there is no difference. still the same. @Petro – Rehan Dec 24 '14 at 20:51
  • what happens when you add a sleep after the method? Like thread.sleep(10000); – Petro Dec 24 '14 at 20:56
  • I added a `delaytimer` . no Change. – Rehan Dec 24 '14 at 20:59
  • comment out your: Timer t = new Timer(50,action); – Petro Dec 24 '14 at 21:01
  • That doesn't make any sense as the timer is the heart of the game for animation. – Rehan Dec 24 '14 at 21:02
  • I know, but we need to see where the code breaks or changes behavior, that's part of the process of coding (sometimes the most fun :), cause you have a chance to learn something new) – Petro Dec 24 '14 at 21:04
  • Ahhh i see your Timer t = new Timer(50,action); needs to be moved into the constructor, also move your Action listener code into the constructor. – Petro Dec 24 '14 at 21:07
  • see my changes in the answer, let me know what happens – Petro Dec 24 '14 at 21:09
  • Moved. And you need me to keep the code for restarting in the same place? – Rehan Dec 24 '14 at 21:12
  • ya, see what happens now. sorry I don't have eclipse installed so I can't run it myself :( – Petro Dec 24 '14 at 21:14
0

Restructure your program such that your display code is independent from your game code

Create another class, a GameDisplay, that holds your JFrame and other swing components, and that manages mouse and keyboard events. In fact, it's best practice to create several classes to manage all this, but one is sufficient for this purpose. Then, have your GameDisplay contain a Game, and call the Game's methods in response to events. Once you have done that, you can restart the game simply by constructing a new Game instance and having your GameDisplay begin using the new instance instead.

Vitruvie
  • 2,327
  • 18
  • 25