重新绘制java时闪烁

时间:2017-07-04 19:14:39

标签: java swing paint repaint

这是我的油漆代码。我知道我应该使用缓冲区,但我不明白如何在我的代码上使用它以及它做了什么,所以请你帮忙解释一下它是什么以及它做了什么和/或编辑我的代码以便它可以停止闪烁谢谢。

 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();}}}

2 个答案:

答案 0 :(得分:6)

你的代码太长了,没有人想调试它,但我发现你在快速检查中发现它有一些错误:

  1. public void paint(Graphics g ) {您应该从不覆盖paint(...)方法,但paintComponent(...)覆盖Swing components are double-buffered(正如@Radiodef在其回答中所解释的那样) ):

      

    Swing确保将适当类型的Graphics对象(用于双缓冲的屏幕外图像Graphics,否则为常规Graphics)传递给组件的paint回调,因此所有组件需要做的就是用它绘制

    我猜你使用这种方法的唯一原因是因为你正在扩展JFrame,你应该扩展JPanel并基于它们构建你的GUI,如JFrame是一个严格的容器,请点击此处阅读:Extends JFrame vs. creating it inside the program

  2. 您不是在调用super.paint(g);(或者如果遵循上面的建议super.paintComponent(g);作为方法中的第一行......那可能会破坏画颜链

  3. 读取绘制方法中的文件可能是程序闪烁的原因,因为它增加了处理时间和延迟,这些行:

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

    会更好地放置在构造函数级别,绘制方法应该绘制,只有那样,因为绘制方法被多次调用(每次将鼠标移到GUI上都会重新绘制,因此每次都会加载资源)

    < / LI>
  4. Thread.sleep(...);您阻止Event Dispatch Thread,这可能是您的程序闪烁的另一个原因,您应该使用Swing Timer执行peridic任务

  5. Boss = 2;Explode == true您没有关注Java naming conventions

    • FirstWordUpperCaseClass
    • firstWordLowerCaseVariable
    • firstWordLowerCaseMethod()
    • ALL_WORDS_UPPER_CASE_CONSTANT
  6. 您在repaint();方法中多次调用paint(...)!这是另一个原因,因为每次都是递归电话......

  7. if (Explode == true),可以写成if (explode),这样可以防止像这样的拼写错误if (explode = true)

  8. 您的代码未正确缩进,因此很难阅读

  9. 如果您遵循上述所有建议并仍然遇到问题,请考虑发布一个有效的Minimal, Complete and Verifiable Example来证明问题,它应该很短但仍然完整且可编辑

答案 1 :(得分:6)

Swing components are already double-buffered by default.你重写了paint,颠覆了这种机制。如果你改写paintComponent而不是(正如我们在Swing中绘画时那样),那么绘画将自动进行双缓冲。

然而

  • 您正在阅读paint中的文件,您不应该这样做。这使得您的绘画效率非常低,以至于低帧速率可能会明显变得明显。相反,您应该在程序首次启动时加载文件一次,并将资源放在您可以从程序中轻松引用的位置。

  • 您正在Thread.sleep中调用冻结GUI的paint。 Swing程序应使用Timer代替。

  • 您以递归方式调用repaint(),这会使事件队列充满油漆事件,并启动一个您无法控制的无限循环。使用Timer远远好得多。

如果你想学习如何使用Swing编写简单的游戏,你可以看一下我的这两个答案:https://stackoverflow.com/a/44371593/2891664https://stackoverflow.com/a/30175751/2891664