java图形中缓冲区的使用
我找到了一个在互联网上创建2D图形游戏的培训,并在此基础上编写了下面的代码,但当我编译时,什么都没有发生! 它只是显示一个没有任何内容的窗口。通过使用抽绳和抽绳,我真的希望看到一些东西,但窗户是空的!有什么问题吗? 代码错了吗?还是我使用了错误的方法java图形中缓冲区的使用,java,swing,graphics,Java,Swing,Graphics,我找到了一个在互联网上创建2D图形游戏的培训,并在此基础上编写了下面的代码,但当我编译时,什么都没有发生! 它只是显示一个没有任何内容的窗口。通过使用抽绳和抽绳,我真的希望看到一些东西,但窗户是空的!有什么问题吗? 代码错了吗?还是我使用了错误的方法 import java.awt.Canvas; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.image.
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Game extends Canvas {
BufferStrategy strategy;
boolean gameRunning = true;
public Game() {
JFrame jf = new JFrame("My Graphic thingy !");
JPanel panel = (JPanel) jf.getContentPane();
panel.setPreferredSize(new Dimension(800, 600));
panel.setLayout(null);
setBounds(0, 0, 800, 600);
panel.add(this);
setIgnoreRepaint(true);
jf.pack();
jf.setResizable(false);
jf.setVisible(true);
jf.createBufferStrategy(2);
strategy = jf.getBufferStrategy();
}
public void gameLoop() {
long lastLoopTime = System.currentTimeMillis();
while (gameRunning) {
lastLoopTime = System.currentTimeMillis();
Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
g.setColor(Color.black);
g.fillRect(0, 0, 800, 600);
g.drawString("HellO", 12,12);
g.drawLine(10, 10, 30, 30);
g.dispose();
strategy.show();
try {
Thread.sleep(2000);
} catch (Exception e) {
}
}
}
public static void main(String[] args) {
Game g = new Game();
g.gameLoop();
}
}
您当前的循环可能会占用Swing事件调度线程,或EDT,从而有效地冻结您的应用程序,因为这个非常重要的线程无法执行它必须执行的操作—呈现您的应用程序并响应用户输入。您需要通过确保循环在后台线程中运行来考虑线程 话虽如此,如果您的教程建议您使用AWT组件(如Canvas)进行编码,并且建议您使用零布局和组件的绝对定位(即使用
setBounds(…)
),那么我必须质疑教程的质量、及时性和相关性。根据教程,使用所有Swing组件和Swing图形会更好
请看一看:
- 基本Swing图形教程:
- 更高级的Swing和AWT图形文章:
- Swing线程教程:
编辑:还有
- 您不应该尝试直接绘制到JFrame,而应该使用JPanel,通常使用它的
方法,尽管有些游戏做的事情不同,并且使用主动渲染而不是典型的被动渲染paintComponent(…)
- 不要使用与绘图文本相同的颜色作为背景,因为如果它们相同,您将永远看不到任何文本
编辑2:例如
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.*;
@SuppressWarnings("serial")
public class Game2 extends JPanel {
private static final int PREF_W = 800;
private static final int PREF_H = 600;
private static final int TIMER_DELAY = 50;
private static final int DELTA_WIDTH = 50;
private static final Color HELLO_COLOR = new Color(150, 150, 255);
private int delta = 0;
private BufferedImage img;
public Game2() {
img = createMyImage();
setBackground(Color.BLACK);
new Timer(TIMER_DELAY, new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
delta++;
repaint(delta - 10, delta - 10, DELTA_WIDTH + 20, DELTA_WIDTH + 20);
}
}).start();
}
private BufferedImage createMyImage() {
BufferedImage myImg = new BufferedImage(DELTA_WIDTH, DELTA_WIDTH,
BufferedImage.TYPE_INT_ARGB);
Graphics g = myImg.getGraphics();
g.setColor(HELLO_COLOR);
g.drawString("Hello", 12, 12);
g.setColor(Color.red);
g.drawLine(10, 10, 30, 30);
g.dispose();
return myImg;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(img, delta, delta, this);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Game2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new Game2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
您当前的循环可能会占用Swing事件调度线程,或EDT,从而有效地冻结您的应用程序,因为这个非常重要的线程无法执行它必须执行的操作—呈现您的应用程序并响应用户输入。您需要通过确保循环在后台线程中运行来考虑线程 话虽如此,如果您的教程建议您使用AWT组件(如Canvas)进行编码,并且建议您使用零布局和组件的绝对定位(即使用
setBounds(…)
),那么我必须质疑教程的质量、及时性和相关性。根据教程,使用所有Swing组件和Swing图形会更好
请看一看:
- 基本Swing图形教程:
- 更高级的Swing和AWT图形文章:
- Swing线程教程:
编辑:还有
- 您不应该尝试直接绘制到JFrame,而应该使用JPanel,通常使用它的
方法,尽管有些游戏做的事情不同,并且使用主动渲染而不是典型的被动渲染paintComponent(…)
- 不要使用与绘图文本相同的颜色作为背景,因为如果它们相同,您将永远看不到任何文本
编辑2:例如
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.*;
@SuppressWarnings("serial")
public class Game2 extends JPanel {
private static final int PREF_W = 800;
private static final int PREF_H = 600;
private static final int TIMER_DELAY = 50;
private static final int DELTA_WIDTH = 50;
private static final Color HELLO_COLOR = new Color(150, 150, 255);
private int delta = 0;
private BufferedImage img;
public Game2() {
img = createMyImage();
setBackground(Color.BLACK);
new Timer(TIMER_DELAY, new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
delta++;
repaint(delta - 10, delta - 10, DELTA_WIDTH + 20, DELTA_WIDTH + 20);
}
}).start();
}
private BufferedImage createMyImage() {
BufferedImage myImg = new BufferedImage(DELTA_WIDTH, DELTA_WIDTH,
BufferedImage.TYPE_INT_ARGB);
Graphics g = myImg.getGraphics();
g.setColor(HELLO_COLOR);
g.drawString("Hello", 12, 12);
g.setColor(Color.red);
g.drawLine(10, 10, 30, 30);
g.dispose();
return myImg;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(img, delta, delta, this);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Game2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new Game2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}