Java 图像赢得';t绘制,画布+;双缓冲+;使用缓冲图像

Java 图像赢得';t绘制,画布+;双缓冲+;使用缓冲图像,java,image,swing,canvas,jframe,Java,Image,Swing,Canvas,Jframe,好的,这里是交易:我试图简单地画一个对象(在这个例子中是龙卷风)到我的主画布上。我使用JFrames、画布、缓冲策略和缓冲图像进行绘制。据我所知,我正确地使用了“游戏循环”,并且根据我之前所能找到的,我在渲染中的操作顺序是正确的。关于使用缓冲区策略的本质,我是否缺少一些东西?我说不出为什么我只有一个灰色的屏幕 基本上,我正在尝试使用尽可能多的“适当的”图形和编码技术使这个tornado程序工作。最终,我想要的是一个有龙卷风穿过的小城市,每个组成部分都作为一个物体存在(龙卷风、建筑物、人等等)。然

好的,这里是交易:我试图简单地画一个对象(在这个例子中是龙卷风)到我的主画布上。我使用JFrames、画布、缓冲策略和缓冲图像进行绘制。据我所知,我正确地使用了“游戏循环”,并且根据我之前所能找到的,我在渲染中的操作顺序是正确的。关于使用缓冲区策略的本质,我是否缺少一些东西?我说不出为什么我只有一个灰色的屏幕

基本上,我正在尝试使用尽可能多的“适当的”图形和编码技术使这个tornado程序工作。最终,我想要的是一个有龙卷风穿过的小城市,每个组成部分都作为一个物体存在(龙卷风、建筑物、人等等)。然而,我发现自己无法继续,直到我能真正画出该死的!下面的代码应该会告诉你你还需要知道什么,我对编程相当陌生,这是一个高中项目,所以欢迎任何其他的指点,但我想知道为什么龙卷风不会吸引你

顺便说一下,我正在使用eclipse。到目前为止,我一直在关注这些头像和帖子,以达到我现在的状态:

这是主类:

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Transparency;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import javax.swing.*;


public class Main {

    static BufferStrategy BuffStrat;
    static Thread t1;
    static BufferedImage backbuff;
    static JFrame mainframe;

    static Tornado tornado;

    public static void main(String[] args) {
        Simulation();
    }


    public static void Setup() {
        mainframe = new JFrame("Tornado Ally");
        mainframe.setIgnoreRepaint(true);
        mainframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Canvas maincanvas = new Canvas();
        maincanvas.setIgnoreRepaint(true);
        maincanvas.setSize(750, 600);

        mainframe.add(maincanvas);
        mainframe.pack();
        mainframe.setVisible(true);

        maincanvas.createBufferStrategy(2);
        BuffStrat = maincanvas.getBufferStrategy();

        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice gd = ge.getDefaultScreenDevice();
        GraphicsConfiguration gc = gd.getDefaultConfiguration();

        backbuff = gc.createCompatibleImage(750, 600, Transparency.BITMASK);
        tornado = new Tornado (0, 0, 0, 0, 0, backbuff);
    }

    public static void Simulation() {
        Setup();

        while (true) {
            Render();
            delay(10);
        }
    }

    public static void Render() {

        Graphics2D g = null; 

        g =  backbuff.createGraphics();

        g.setBackground(Color.LIGHT_GRAY);
        g.clearRect(0, 0, 750, 600);
        tornado.drawTornado(g);

        Graphics gI = BuffStrat.getDrawGraphics();
        gI.drawImage(backbuff, 0, 0, null);

        BuffStrat.show();
        gI.dispose();
        g.dispose();

    }

    public static void delay(int ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException e) {

        }
    }
}
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.geom.Dimension2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class Tornado {

    int x, y, z;
    int mag;
    double velocity;
    Dimension2D hitbox;

    GraphicsConfiguration gc;
    Image t;
    BufferedImage backbuff;


    public Tornado(int x, int y, int z, int mag, double velocity, BufferedImage backbuff) {
        this.x = x;
        this.y = y;
        this.z = z;
        this.mag = mag;
        this.velocity = velocity;
        this.backbuff = backbuff;

        {
            try {
                t = ImageIO.read(new File("Sprites.Tornado/TornadoFull.png"));
            } catch (IOException e) {
            }
        }


    }

    public void drawTornado(Graphics2D g) {

        g.drawImage(t, 0, 0, null);
    }

}
这是龙卷风对象:

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Transparency;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import javax.swing.*;


public class Main {

    static BufferStrategy BuffStrat;
    static Thread t1;
    static BufferedImage backbuff;
    static JFrame mainframe;

    static Tornado tornado;

    public static void main(String[] args) {
        Simulation();
    }


    public static void Setup() {
        mainframe = new JFrame("Tornado Ally");
        mainframe.setIgnoreRepaint(true);
        mainframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Canvas maincanvas = new Canvas();
        maincanvas.setIgnoreRepaint(true);
        maincanvas.setSize(750, 600);

        mainframe.add(maincanvas);
        mainframe.pack();
        mainframe.setVisible(true);

        maincanvas.createBufferStrategy(2);
        BuffStrat = maincanvas.getBufferStrategy();

        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice gd = ge.getDefaultScreenDevice();
        GraphicsConfiguration gc = gd.getDefaultConfiguration();

        backbuff = gc.createCompatibleImage(750, 600, Transparency.BITMASK);
        tornado = new Tornado (0, 0, 0, 0, 0, backbuff);
    }

    public static void Simulation() {
        Setup();

        while (true) {
            Render();
            delay(10);
        }
    }

    public static void Render() {

        Graphics2D g = null; 

        g =  backbuff.createGraphics();

        g.setBackground(Color.LIGHT_GRAY);
        g.clearRect(0, 0, 750, 600);
        tornado.drawTornado(g);

        Graphics gI = BuffStrat.getDrawGraphics();
        gI.drawImage(backbuff, 0, 0, null);

        BuffStrat.show();
        gI.dispose();
        g.dispose();

    }

    public static void delay(int ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException e) {

        }
    }
}
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.geom.Dimension2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class Tornado {

    int x, y, z;
    int mag;
    double velocity;
    Dimension2D hitbox;

    GraphicsConfiguration gc;
    Image t;
    BufferedImage backbuff;


    public Tornado(int x, int y, int z, int mag, double velocity, BufferedImage backbuff) {
        this.x = x;
        this.y = y;
        this.z = z;
        this.mag = mag;
        this.velocity = velocity;
        this.backbuff = backbuff;

        {
            try {
                t = ImageIO.read(new File("Sprites.Tornado/TornadoFull.png"));
            } catch (IOException e) {
            }
        }


    }

    public void drawTornado(Graphics2D g) {

        g.drawImage(t, 0, 0, null);
    }

}

测试代码时,它会引发异常,因为在调整窗口大小之前,代码试图构造
缓冲策略。因为主窗口使用的是
LayoutManager
,所以更好的解决方案是使用类似于

//maincanvas.setSize(750, 600);
maincanvas.setPreferredSize(new Dimension(750, 600));
当您调用
pack
时,窗口将调整大小以适应其子组件的首选大小

加载图像时,您也会忽略异常,所以您甚至不知道它是否因为某种原因未加载。至少,您应该记录任何异常

例如

try {
    t = ImageIO.read(new File("TSprites.Tornado/TornadoFull.png"));
} catch (IOException e) {
    e.printStackTrace();
}
public static void Simulation() {
    Setup();

    new Thread(new Runnable() {

        @Override
        public void run() {
            while (true) {
                Render();
                delay(10);
            }
        }
    }).start();
}
这段代码表明图像是一个外部资源,如果不是(并且它内置在应用程序中),则需要使用
getClass().getResource(“/TSprites.Tornado/tornadfull.png”)
而不是
新文件(…)

您还应该考虑在事件调度线程的上下文中构造UI,详情请看./P> 例如,我将您的

main
方法更改为更像

EventQueue.invokeLater(new Runnable() {
    @Override
    public void run() {
        Simulation();
    }
});
并更新了
模拟
方法,以在另一个线程的上下文中执行主循环,例如

try {
    t = ImageIO.read(new File("TSprites.Tornado/TornadoFull.png"));
} catch (IOException e) {
    e.printStackTrace();
}
public static void Simulation() {
    Setup();

    new Thread(new Runnable() {

        @Override
        public void run() {
            while (true) {
                Render();
                delay(10);
            }
        }
    }).start();
}
您可能还想看一看,因为这将使您的代码更容易被其他人阅读

另外,要注意过度使用
静态
。这可能会导致更多的问题,然后他们解决,如果不正确使用

此外,尽量避免使用幻数,而是使用您知道的值,例如

try {
    t = ImageIO.read(new File("TSprites.Tornado/TornadoFull.png"));
} catch (IOException e) {
    e.printStackTrace();
}
public static void Simulation() {
    Setup();

    new Thread(new Runnable() {

        @Override
        public void run() {
            while (true) {
                Render();
                delay(10);
            }
        }
    }).start();
}
而不是

g.clearRect(0, 0, 750, 600);
尝试使用

g.clearRect(0, 0, backbuff.getWidth(), backbuff.getHeight());

不要忽略您的异常,映像可能没有被加载我已经考虑过了,我现在正在研究这个问题,但到目前为止,我似乎没有得到任何异常,除非我调用映像对象的方法,例如“t.getWidth();”,它会导致nullpointerexception。所以我不确定这到底意味着什么…啊!没看到你的答案,没关系!现在我来看看你说的话,谢谢你的帮助。将“新文件”更改为“getClass().getResource()”修复了我的问题!但我一定会研究你的建议,并落实你的其他建议。多谢各位。