-2

This is my paint code. I know I should use a buffer but I don't understand how to use it on my code and what it does so please can you help by explaining what it is and what it does and/or edit my code so it can stop flickering thank you.

 public void paint(Graphics g ) {
    g.fillRect(BulletX, BulletY,0,0);
    g.setColor(Color.yellow);
    try{
    FileInputStream saveFile = new FileInputStream("Wins1.sav");
    ObjectInputStream save = new ObjectInputStream(saveFile);

    wins1 = (int) save.readObject();


    save.close();
    }
    catch(Exception exc){
    exc.printStackTrace();
    }
    Image image;
    URL resource = getClass().getClassLoader().getResource("moon1.jpg");
       URL resource1 = getClass().getClassLoader().getResource("Tank.jpg");
       URL resource2 = getClass().getClassLoader().getResource("Tank2.jpg");

       ImageIcon i2 = new ImageIcon(resource);
        ImageIcon i1 = new ImageIcon(resource1);
        ImageIcon i3 = new ImageIcon(resource2);
    image = i2.getImage();
        g.drawImage(image, 0,0,null);
        if (SHOW.equals("ON")){
        g.setFont(new Font("TimesRoman", Font.BOLD, 30));
        g.drawString("Player 1's health ="+Integer.toString(Player1H), 50, 25);}
    if (wins == 1){
        g.setColor(Color.BLACK);
        g.fillOval(20, 10, 30, 30);
        g.setColor(Color.YELLOW);
    }
    if (wins == 2){
        g.setColor(Color.BLACK);
        g.fillOval(20, 10, 30, 30);
        g.setColor(Color.BLACK);
        g.fillOval( 60,10, 30, 30);
        g.setColor(Color.YELLOW);
    }
    if (wins == 3){
        g.setColor(Color.BLACK);
        g.fillOval(20, 10, 30, 30);
        g.setColor(Color.BLACK);
        g.fillOval( 60,10, 30, 30);
        g.setColor(Color.BLACK);
        g.fillOval( 100,10, 30, 30);
        g.setColor(Color.YELLOW);
    }
    if (wins == 4){
        g.setColor(Color.BLACK);
        g.fillOval(20, 10, 30, 30);
        g.setColor(Color.BLACK);
        g.fillOval( 60,10, 30, 30);
        g.setColor(Color.BLACK);
        g.fillOval( 100,10, 30, 30);
        g.setColor(Color.BLACK);
        g.fillOval(140,10, 30, 30);
        g.setColor(Color.YELLOW);
    }
    if (wins1 == 1){
        g.setColor(Color.BLACK);
        g.fillOval( 360,10, 30, 30);
        g.setColor(Color.YELLOW);
    }
    if (wins1 == 2){
        g.setColor(Color.BLACK);
        g.fillOval( 360,10, 30, 30);
        g.setColor(Color.BLACK);
        g.fillOval( 400,10, 30, 30);
        g.setColor(Color.YELLOW);
    }
    if (wins1 == 3){
        g.setColor(Color.BLACK);
        g.fillOval( 360,10, 30, 30);
        g.setColor(Color.BLACK);
        g.fillOval( 400,10, 30, 30);
        g.setColor(Color.BLACK);
        g.fillOval( 480,10, 30, 30);
        g.setColor(Color.YELLOW);
    }
    if (wins1 == 4){
        g.setColor(Color.BLACK);
        g.fillOval( 360,10, 30, 30);
        g.setColor(Color.BLACK);
        g.fillOval( 400,10, 30, 30);
        g.setColor(Color.BLACK);
        g.fillOval( 480,10, 30, 30);
        g.setColor(Color.BLACK);
        g.fillOval( 520,10, 30, 30);
        g.setColor(Color.YELLOW);
    }
    image = i1.getImage();
    g.drawImage(image,myX, myY,null);
    image = i3.getImage();
    g.setColor(Color.blue);
    if (Boss == 1){
        g.setColor(Color.RED);
        g.fillOval(myX1, myY1, 50, 50);
         try {
        Thread.sleep(800);
    } catch (InterruptedException ex) {
        Logger.getLogger(onePlayer1.class.getName()).log(Level.SEVERE, null, ex);
    }
         Boss = 2;
        win();
    }

    g.drawImage(image,myX1, myY1,null);

    if (hit2 ==1){
        g.setColor(Color.red);
        hit2 =0;
        g.fillOval(myX1, myY1, 20, 20);

        try {
        Thread.sleep(200);
    } catch (InterruptedException ex) {
        Logger.getLogger(onePlayer1.class.getName()).log(Level.SEVERE, null, ex);
    }
        repaint();
    }
    if (hit1 ==1){
        g.setColor(Color.red);
        hit1 =0;
        g.fillOval(myX, myY, 20, 20);

        try {
        Thread.sleep(200);
    } catch (InterruptedException ex) {
        Logger.getLogger(onePlayer1.class.getName()).log(Level.SEVERE, null, ex);
    }
        repaint();
    }
    if (Explode == true){
        g.setColor(Color.RED);
        g.fillOval(myX11,myY11,40,40);
        number = 0;
        Explode = false;
        myX11 = -10;
        myY11 = -10;
        Player3H = 0;

        try {
        Thread.sleep(800);
    } catch (InterruptedException ex) {
        Logger.getLogger(onePlayer1.class.getName()).log(Level.SEVERE, null, ex);
    }
        repaint();
    }
    if (number ==11){
        URL resource3 = getClass().getClassLoader().getResource("Dynamite.jpg");
        ImageIcon i4 = new ImageIcon(resource3);
        image = i4.getImage();
        g.setColor(Color.GREEN);
                g.drawImage(image,myX11, myY11,null);
    }
    if (number == 1){

        g.setColor(Color.GREEN);
        myX11 = myX1+10;
        myY11 = myY1+10;
                g.drawImage(image,myX11, myY11,null);
        number =11;
        Player3H = 10;
        repaint();
    }
    g.setColor(Color.BLACK);
    if (fire1.equals("Yes")){


        if (aim1.equals("right")){
        BulletY1 = myY1;    
        BulletX1 = myX1;



        g.fillRect(BulletX1, BulletY1, 1000, 5);

        try {
            Thread.sleep(100);
        } catch (InterruptedException ex) {
            Logger.getLogger(HandlingEvents.class.getName()).log(Level.SEVERE, null, ex);
        }

        fire1="no";
        repaint();}
        if (aim1.equals("down")){
        BulletY1 = myY1;    
        BulletX1 = myX1;
        g.fillRect(BulletX1, BulletY1, 5, 1000);

        try {
            Thread.sleep(100);
        } catch (InterruptedException ex) {
            Logger.getLogger(HandlingEvents.class.getName()).log(Level.SEVERE, null, ex);
        }

        fire1="no";
        repaint();}
        if (aim1.equals("left")){
        BulletY1 = myY1;    
        BulletX1 = myX1-1000;
        g.fillRect(BulletX1, BulletY1, 1000,5);
        try {
            Thread.sleep(100);
        } catch (InterruptedException ex) {
            Logger.getLogger(HandlingEvents.class.getName()).log(Level.SEVERE, null, ex);
        }

        fire1="no";
        repaint();}
        if (aim1.equals("up")){

        BulletY1 = myY1-1000;    
        BulletX1 = myX1;
        g.fillRect(BulletX1, BulletY1, 5, 1000);

        try {
            Thread.sleep(100);
        } catch (InterruptedException ex) {
            Logger.getLogger(HandlingEvents.class.getName()).log(Level.SEVERE, null, ex);
        }

        fire1="no";
        repaint();}}
    if (fire.equals("Yes")){


        if (aim.equals("right")){
        BulletY = myY;    
        BulletX = myX;
        BulletXX = myX+10;
        BulletYY = myY+10;

        g.fillRect(BulletXX, BulletYY, 1000, 5);
        g.fillRect(BulletX, BulletY, 1000, 5);



        fire="no";

            try {
                Thread.sleep(100);
            } catch (InterruptedException ex) {
                Logger.getLogger(onePlayer1.class.getName()).log(Level.SEVERE, null, ex);
            }
        repaint();}
        if (aim.equals("down")){
        BulletY = myY;    
        BulletX = myX;
        BulletXX = myX+10;
        BulletYY = myY+10;

        g.fillRect(BulletXX, BulletYY, 5, 1000);
        g.fillRect(BulletX, BulletY, 5, 1000);

        try {
            Thread.sleep(100);
        } catch (InterruptedException ex) {
            Logger.getLogger(HandlingEvents.class.getName()).log(Level.SEVERE, null, ex);
        }

        fire="no";
        repaint();}
        if (aim.equals("left")){
        BulletY = myY;    
        BulletX = myX-1000;
         BulletXX = myX-990;
         BulletYY = myY+10;

        g.fillRect(BulletXX, BulletYY, 1000, 5);
        g.fillRect(BulletX, BulletY, 1000,5);
        try {
            Thread.sleep(100);
        } catch (InterruptedException ex) {
            Logger.getLogger(HandlingEvents.class.getName()).log(Level.SEVERE, null, ex);
        }

        fire="no";
        repaint();}
        if (aim.equals("up")){

        BulletY = myY-1000;    
        BulletX = myX;
         BulletXX = myX+10;
         BulletYY = myY-990;

        g.fillRect(BulletXX, BulletYY, 5, 1000);
        g.fillRect(BulletX, BulletY, 5, 1000);

        try {
            Thread.sleep(100);
        } catch (InterruptedException ex) {
            Logger.getLogger(HandlingEvents.class.getName()).log(Level.SEVERE, null, ex);
        }
        g.fillRect(BulletX, BulletY, 0, 0);
        fire="no";
        repaint();}}}
Frakcool
  • 10,915
  • 9
  • 50
  • 89
Cufe
  • 18
  • 6
  • Welcome to Stack Overflow, please take the [tour], go through the [help] and learn [ask], and provide a valid [mcve] that demonstrates your problem – Frakcool Jul 04 '17 at 19:35
  • 3
    Don't block the `paint` method, all that "logic" should be some where else, painting should paint the current state, it shouldn't be making decisions or modifying the state. Don't call `repaint` from within `paint`, that's asking for disaster. Swing uses a passive painting approach, meaning that a paint pass could occur at any time for any number of reasons, many of which you don't control – MadProgrammer Jul 04 '17 at 20:46

2 Answers2

7

Swing components are already double-buffered by default. You're overriding paint which subverts that mechanism. If you override paintComponent instead (as we ought to do when painting in Swing), then painting will be double-buffered automatically.

However:

  • You're reading files in paint, which you shouldn't be doing. This makes your painting very inefficient, to the point where the low frame rate will likely be obviously noticeable. Instead, you should load your files once when the program first starts and put the resources somewhere you can easily reference from within the program.

  • You're calling Thread.sleep in paint which freezes the GUI. Swing program should use a Timer instead.

  • You're calling repaint() recursively which floods the event queue with paint events and starts an infinite loop which you don't have control over. Using a Timer is far, far better.

If you want to learn how to write simple games with Swing, you might take a look at these two answers of mine: https://stackoverflow.com/a/44371593/2891664, https://stackoverflow.com/a/30175751/2891664.

Radiodef
  • 37,180
  • 14
  • 90
  • 125
  • Thank you for explaining how I can make it better I will do these changes – Cufe Jul 04 '17 at 20:09
  • Where you said instead of : public void paint(Graphics g) use public void paintComponent(Graphics g) it is not working as not showing anything is it because it is painting on a Canvas? – Cufe Jul 04 '17 at 20:26
  • If you're extending `java.awt.Canvas`, yes, that's an older AWT component. You should use `javax.swing.JPanel` instead. (As shown in the answers I linked to.) – Radiodef Jul 04 '17 at 20:52
  • so i change extends Canvas to extends JPanel – Cufe Jul 04 '17 at 21:21
  • 1
    Thank you their is no flickering when i changed canvas to jpanel :) – Cufe Jul 04 '17 at 21:25
6

Your code is sooo long, no one wants to debug it, but I find in a quick check that you have some errors in it:

  1. public void paint(Graphics g ) { You should NEVER override paint(...) method but paintComponent(...), as Swing components are double-buffered (as explained by @Radiodef in his answer):

    Swing ensures that the appropriate type of Graphics object (offscreen image Graphics for double-buffering, regular Graphics otherwise) is passed to the component's paint callback, so all the component needs to do is draw with it

    I'm going to guess that the only reason you're using this method is because you're extending JFrame, and you should extend JPanel instead and build your GUI based on them, as a JFrame is a rigid container, read more here: Extends JFrame vs. creating it inside the program

  2. You're not calling super.paint(g); (Or if following above recommendation super.paintComponent(g); as the first line in the method... that could break the paint chain

  3. Reading files inside the painting methods could be the reason your program is flickering as it adds processing time and lag, these lines:

    FileInputStream saveFile = new FileInputStream("Wins1.sav");
    ObjectInputStream save = new ObjectInputStream(saveFile);
    ...
    //until this line
    image = i2.getImage();
    

    would be better placed at constructor level , paint methods should paint and only that, as painting methods are called several times (everytime you move your mouse over the GUI it gets repainted, so it's loading resources everytime)

  4. Thread.sleep(...); You're blocking the Event Dispatch Thread, so that's probably another reason your program is flickering, you should instead use a Swing Timer to do peridic tasks

  5. Boss = 2;, Explode == true You're not following Java naming conventions:

    • FirstWordUpperCaseClass
    • firstWordLowerCaseVariable
    • firstWordLowerCaseMethod()
    • ALL_WORDS_UPPER_CASE_CONSTANT
  6. You're calling repaint(); several times inside the paint(...) method! That's another reason as it's a recursive call everytime...

  7. if (Explode == true), can be written as if (explode) which will prevent typos like this one if (explode = true)

  8. Your code is not correctly indented and thus it's hard to read

If you follow all the above recommendations and still have problems, consider posting a valid Minimal, Complete and Verifiable Example that demonstrates the problem, it should be short but still complete and compilable

Frakcool
  • 10,915
  • 9
  • 50
  • 89