图像不会绘制,使用Canvas +双缓冲+缓冲图像

时间:2013-12-04 02:26:35

标签: java image swing canvas jframe

好的,所以这是交易:我试图简单地将一个对象(在这种情况下是龙卷风)绘制到我的主画布上。我正在使用JFrame,画布,缓冲策略和缓冲图像来绘制。据我所知,我正在正确使用“游戏循环”,并且我之前能够找到我在渲染中的操作顺序是正确的。对于使用缓冲策略的性质,我是否有些遗漏?我不知道为什么我只是一个灰色的屏幕。

基本上我正在努力让这个龙卷风计划使用尽可能多的“适当”图形和编码技术。最终我想要的只是一个龙卷风穿过它的小城市,每个组件都作为一个物体(龙卷风,建筑物,人等)存在。然而,我发现自己无法继续使用我可以实际绘制爆破!下面的代码应该向你展示你需要知道的其他内容,我是一个相当新的编程,这是一个高中项目,所以任何其他指针都是受欢迎的,但主要是我想知道为什么龙卷风不会画! /强>

顺便说一句,我正在使用eclipse。到目前为止,我已经按照这些toutorials和帖子来了解我现在的位置:

http://www.gamedev.net/page/resources/_/technical/general-programming/java-games-active-rendering-r2418

http://examples.javacodegeeks.com/desktop-java/awt/image/drawing-on-a-buffered-image/

这是主要课程:

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

}

1 个答案:

答案 0 :(得分:0)

在测试代码时,它会引发异常,因为您的代码在调整窗口大小之前尝试构造BufferStrategy。因为主窗口使用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();
}

此代码表明图像是外部资源,如果不是(并且内置于应用程序中),则需要使用getClass().getResource("/TSprites.Tornado/TornadoFull.png")而不是new File(...) ...

您还应该考虑在事件调度线程的上下文中构建UI,有关详细信息,请查看Initial Threads

例如,我将您的main方法更改为更像......

EventQueue.invokeLater(new Runnable() {
    @Override
    public void run() {
        Simulation();
    }
});

并更新了您的Simulation方法以在另一个线程的上下文中执行主循环,例如......

public static void Simulation() {
    Setup();

    new Thread(new Runnable() {

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

您可能还想查看Code Conventions for the Java Programming Language,因为它会让您的代码更易于阅读

另外,请注意static的过度使用。如果没有正确使用,这可能会导致更多问题然后解决...

此外,尽量避免使用魔术数字,而是使用您知道的值,例如......

而不是......

g.clearRect(0, 0, 750, 600);

尝试使用...

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