重新绘制java时闪烁

重新绘制java时闪烁,java,swing,paint,repaint,Java,Swing,Paint,Repaint,这是我的绘画代码。我知道我应该使用缓冲区,但我不知道如何在我的代码中使用缓冲区,以及它的作用。请您解释一下缓冲区是什么,它的作用和/或编辑我的代码,使其停止闪烁。谢谢 public void paint(Graphics g ) { g.fillRect(BulletX, BulletY,0,0); g.setColor(Color.yellow); try{ FileInputStream saveFile = new FileInputStream("Win

这是我的绘画代码。我知道我应该使用缓冲区,但我不知道如何在我的代码中使用缓冲区,以及它的作用。请您解释一下缓冲区是什么,它的作用和/或编辑我的代码,使其停止闪烁。谢谢

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

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

  • public void paint(Graphics g){
    您应该决不覆盖
    paint(…)
    方法,但
    paintComponent(…)
    ,如@Radiodef在其回答中所述:

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

    我猜您使用此方法的唯一原因是因为您正在扩展
    JFrame
    ,而您应该扩展
    JPanel
    ,并基于它们构建GUI,因为
    JFrame
    是一个刚性容器,请阅读以下内容:

  • 您没有将
    super.paint(g);
    (或者如果遵循上述建议
    super.paintComponent(g);
    作为方法中的第一行调用……这可能会中断绘制链

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

    FileInputStream saveFile = new FileInputStream("Wins1.sav");
    ObjectInputStream save = new ObjectInputStream(saveFile);
    ...
    //until this line
    image = i2.getImage();
    
    最好放在构造函数级别,绘制方法应该绘制,而且只有这样,因为绘制方法会被调用多次(每次将鼠标移到GUI上时,它都会被重新绘制,所以每次都会加载资源)

  • Thread.sleep(…);
    您正在阻止,因此这可能是您的程序闪烁的另一个原因,您应该改用线程来执行周期性任务

  • Boss=2;
    Explode==true
    您没有跟踪:

    • FirstWordUpperCaseClass
    • firstWordLowerCaseVariable
    • firstWordLowerCaseMethod()
    • 所有单词大写常量
  • 您在
    paint(…)
    方法中多次调用
    repaint();
    !这是另一个原因,因为每次调用都是递归调用

  • if(Explode==true)
    可以写成
    if(Explode)
    ,这样可以防止像这样的打字错误
    if(Explode=true)

  • 您的代码没有正确缩进,因此很难阅读

  • 如果您遵循上述所有建议,仍然存在问题,请考虑发布一个有效的问题,它应该是简短的,但仍然是完整的和可编译的

    您是压倒<代码>油漆>代码>它颠覆了该机制。(就像我们在摇摆中绘画时应该做的那样),然后绘画将自动进行双缓冲

    然而:

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

    • 您正在
      paint
      中调用
      Thread.sleep
      ,这会冻结GUI。Swing程序应该使用

    • 您正在递归调用
      repaint()
      ,这会用绘制事件淹没事件队列,并启动一个您无法控制的无限循环。使用
      计时器
      要好得多


    如果你想学习如何使用Swing编写简单的游戏,你可以看看我的以下两个答案:,。

    欢迎使用Stack Overflow,请使用,仔细阅读并学习,并提供一个有效的示例来演示你的问题不要阻止
    paint
    方法,所有这些“逻辑”应该是在其他地方,绘制应该绘制当前状态,它不应该做出决定或修改状态。不要从
    paint
    中调用
    repaint
    ,这是在请求灾难。Swing使用被动绘制方法,这意味着绘制过程可能在任何时候出于各种原因发生,其中很多原因你不知道,谢谢你解释我如何能做得更好,我会做这些改变,而不是你说的:public void paint(图形g)使用public void paintComponent(图形g)它不是不显示任何内容,是因为它在画布上绘制吗?如果您正在扩展
    java.awt.Canvas
    ,是的,这是一个较旧的awt组件。您应该改用
    javax.swing.JPanel
    (如我链接的答案所示)因此,我将extensedcanvas更改为extensedjpanelhank当我将Canvas更改为jpanel时,它们不会闪烁:)