Java 图像赢得';t绘制,画布+;双缓冲+;使用缓冲图像
好的,这里是交易:我试图简单地画一个对象(在这个例子中是龙卷风)到我的主画布上。我使用JFrames、画布、缓冲策略和缓冲图像进行绘制。据我所知,我正确地使用了“游戏循环”,并且根据我之前所能找到的,我在渲染中的操作顺序是正确的。关于使用缓冲区策略的本质,我是否缺少一些东西?我说不出为什么我只有一个灰色的屏幕 基本上,我正在尝试使用尽可能多的“适当的”图形和编码技术使这个tornado程序工作。最终,我想要的是一个有龙卷风穿过的小城市,每个组成部分都作为一个物体存在(龙卷风、建筑物、人等等)。然而,我发现自己无法继续,直到我能真正画出该死的!下面的代码应该会告诉你你还需要知道什么,我对编程相当陌生,这是一个高中项目,所以欢迎任何其他的指点,但我想知道为什么龙卷风不会吸引你强> 顺便说一下,我正在使用eclipse。到目前为止,我一直在关注这些头像和帖子,以达到我现在的状态: 这是主类:Java 图像赢得';t绘制,画布+;双缓冲+;使用缓冲图像,java,image,swing,canvas,jframe,Java,Image,Swing,Canvas,Jframe,好的,这里是交易:我试图简单地画一个对象(在这个例子中是龙卷风)到我的主画布上。我使用JFrames、画布、缓冲策略和缓冲图像进行绘制。据我所知,我正确地使用了“游戏循环”,并且根据我之前所能找到的,我在渲染中的操作顺序是正确的。关于使用缓冲区策略的本质,我是否缺少一些东西?我说不出为什么我只有一个灰色的屏幕 基本上,我正在尝试使用尽可能多的“适当的”图形和编码技术使这个tornado程序工作。最终,我想要的是一个有龙卷风穿过的小城市,每个组成部分都作为一个物体存在(龙卷风、建筑物、人等等)。然
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()”修复了我的问题!但我一定会研究你的建议,并落实你的其他建议。多谢各位。