好的,所以这是交易:我试图简单地将一个对象(在这种情况下是龙卷风)绘制到我的主画布上。我正在使用JFrame,画布,缓冲策略和缓冲图像来绘制。据我所知,我正在正确使用“游戏循环”,并且我之前能够找到我在渲染中的操作顺序是正确的。对于使用缓冲策略的性质,我是否有些遗漏?我不知道为什么我只是一个灰色的屏幕。
基本上我正在努力让这个龙卷风计划使用尽可能多的“适当”图形和编码技术。最终我想要的只是一个龙卷风穿过它的小城市,每个组件都作为一个物体(龙卷风,建筑物,人等)存在。然而,我发现自己无法继续使用我可以实际绘制爆破!下面的代码应该向你展示你需要知道的其他内容,我是一个相当新的编程,这是一个高中项目,所以任何其他指针都是受欢迎的,但主要是我想知道为什么龙卷风不会画! /强>
顺便说一句,我正在使用eclipse。到目前为止,我已经按照这些toutorials和帖子来了解我现在的位置:
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);
}
}
答案 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());