【问题标题】:How to fix the blinking of the screen due to loading of the Image?如何解决由于加载图像而导致屏幕闪烁的问题?
【发布时间】:2023-04-04 11:20:01
【问题描述】:

我正在尝试在其上加载和图像绘制,然后将其显示在框架上。 我也可以在框架上加载图像并在框架上绘图,但这会在我的屏幕上产生更多的闪烁。

在下面的代码中,当用户按下任意键时屏幕会闪烁,因为图像被再次加载并且球的新位置被绘制。

if up_key y--
if down_key y++
if left_key x--
if right_key x++

根据按下的键重新显示图像并更新球的位置。

如何减少闪烁效果以使其平滑?

必须替换我在文件构造函数中给出的路径。

import java.awt.*;
import java.io.*;
import java.awt.image.*;
import javax.imageio.ImageIO;
import java.awt.event.*;

class MyFrame extends Frame implements KeyListener 
{
    BufferedImage img;
    int x=100,y=100;
    public MyFrame()
    {
        super("Box");
        this.setSize(1382,784);
        this.setVisible(true);
        this.addKeyListener(this);
        this.requestFocus();
        this.setResizable(false);
    }
    public void make()
    {
        try{
        img=ImageIO.read(new File("c:/users/udesh_2/desktop/Boundary.jpg"));
        Graphics gfx=img.getGraphics();
        gfx.setColor(Color.black);
        gfx.fillOval(x,y,40,40);
        }
        catch(IOException io){}
    }
    @Override
    public void paint(Graphics g)
    {
        make();
        g.drawImage(img,0,0,getWidth(),getHeight(),null);
    }
    public static void main(String $[])
    {
        MyFrame f=new MyFrame();
        f.make();
        f.repaint();
    }

    public void keyPressed(KeyEvent key)
    {
        boolean found=false;

        if(key.getKeyCode()==KeyEvent.VK_UP)
        {
            found=true;
            y--;
        }
        if(key.getKeyCode()==KeyEvent.VK_DOWN)
        {
            found=true;
            y++;
        }
        if(key.getKeyCode()==KeyEvent.VK_LEFT)
        {
            found=true;
            x--;
        }
        if(key.getKeyCode()==KeyEvent.VK_RIGHT)
        {
            found=true;
            x++;
        }
                    if(found)
        repaint();
    }
    public void keyTyped(KeyEvent key){}
    public void keyReleased(KeyEvent key){}
}

【问题讨论】:

  • 为避免预加载 img 时闪烁,请将 make() 调用移至构造函数,并避免在 paint 方法中调用 make()。在paint里面你应该只有绘图的东西,而不是加载资源和其他繁重的工作。
  • @mmmatey 那我应该如何有效地加载加载图像并在框架上显示图像。
  • 我为您准备了如何避免它的示例,现在无法运行,但它应该是这样的:pastebin.com/XpzDx33e 在这里查看代码。
  • “我想在图像上而不是在框架上绘画” 有趣的是(或者我猜不是),我实际上更喜欢在图像上完成所有绘画,但是它'd 只需使用标签显示(上述第二种方法)。这是an example of doing that,尽管它比您现在看起来需要的要复杂。 我注意到您的代码的一件事。大部分时间都花在了调整图像大小上!如果 GUI 不会改变大小,我只会缩放一次。
  • (拍前额)并且每次绘制都会调用make()方法,这会导致图像再次加载!

标签: java awt frame bufferedimage


【解决方案1】:

每次调用repaint() 时,您都在设置变量img 的值,这会导致闪烁。而是在您的构造函数中初始化一次。那么在这种情况下也不需要额外的 make 方法。这应该有效:

import java.awt.*;
import java.io.*;
import java.awt.image.*;
import javax.imageio.ImageIO;
import java.awt.event.*;

class MyFrame extends Frame implements KeyListener {

    BufferedImage img;
    int x = 100, y = 100;

    public MyFrame() {
        super("Box");
        this.setSize(480, 480);
        this.setVisible(true);
        this.addKeyListener(this);
        this.requestFocus();
        this.setResizable(false);
        try {
            img = ImageIO.read(new File("c:/users/udesh_2/desktop/Boundary.jpg"));   
        } catch (IOException io) {
            io.printStackTrace();
        }
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
        g.setColor(Color.black);
        g.fillOval(x, y, 40, 40);
    }

    public static void main(String $[]) {
        MyFrame f = new MyFrame();
        f.repaint();
    }

    public void keyPressed(KeyEvent key) {
        boolean found = false;

        if (key.getKeyCode() == KeyEvent.VK_UP) {
            found = true;
            y--;
        }
        if (key.getKeyCode() == KeyEvent.VK_DOWN) {
            found = true;
            y++;
        }
        if (key.getKeyCode() == KeyEvent.VK_LEFT) {
            found = true;
            x--;
        }
        if (key.getKeyCode() == KeyEvent.VK_RIGHT) {
            found = true;
            x++;
        }
        if (found) {
            repaint();
        }
    }

    public void keyTyped(KeyEvent key) {
    }

    public void keyReleased(KeyEvent key) {
    }
}

【讨论】:

  • g.drawImage(img, 0, 0, getWidth(), getHeight(), null); 1) 首先致电super.paint(g);。 2) FrameImageObserver 所以 null 最好是 this
  • @AndrewThompson 很好的观察和很好的建议,我已经编辑了我的答案。
【解决方案2】:
import java.awt.*;
import java.io.*;
import java.awt.image.*;
import javax.imageio.ImageIO;
import java.awt.event.*;

class MyFrame extends Frame implements KeyListener {

    BufferedImage img;
    Image _img;
    Graphics gfx;
    int x = 100, y = 100;

    public MyFrame() {
    super("Box");
    this.setSize(1000,780);
    this.setVisible(true);
    this.addKeyListener(this);
    this.requestFocus();
    this.setResizable(false);
    try {
        img = ImageIO.read(new File("c:/users/udesh_2/desktop/Boundary.jpg"));   
    } catch (IOException io) {
        io.printStackTrace();
    }
    _img=createImage(getWidth(),getHeight());
    gfx=_img.getGraphics();

    }

    @Override
    public void paint(Graphics g) {
        if(img!=null){
        gfx.drawImage((Image)img,0,0,getWidth(),getHeight(),this);
        gfx.fillOval(x,y,30,30);

        g.drawImage(_img, 0, 0, getWidth(), getHeight(), this);

        try
        {
            Thread.sleep(70);

        }catch(Exception e){System.out.println(e);}
        }
    }

    public static void main(String $[]) {
        MyFrame f = new MyFrame();
        f.repaint();
    }

    public void keyPressed(KeyEvent key) {
    boolean found = false;

        if (key.getKeyCode() == KeyEvent.VK_UP) {
            found = true;
            y-=2;
        }
        if (key.getKeyCode() == KeyEvent.VK_DOWN) {
            found = true;
            y+=2;
        }
        if (key.getKeyCode() == KeyEvent.VK_LEFT) {
            found = true;
            x-=2;
        }
        if (key.getKeyCode() == KeyEvent.VK_RIGHT) {
            found = true;
            x+=2;
        }
        if (found) {
            repaint();
        }
    }

    public void keyTyped(KeyEvent key) {
    }

    public void keyReleased(KeyEvent key) {
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-09
    • 2013-01-20
    相关资源
    最近更新 更多