我正在学习java游戏编程的基础知识,我对一些事情感到困惑。 我知道你使用“canvas”类创建一个空白画布,然后使用paint方法创建东西。
但Graphics2D
是什么?我见过人们使用grahpics2d类来创建一个画布,例如
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLACK);
现在为什么他们使用grahpics2d而不是画布?
我也看到人们通过使用:
创建像矩形的形状Rectangle r = new Rectangle();
但有些人创建了它们:
Shape shape = new Rectangle2D.Double(value1,valu2,valu3,valu4);
这两者之间有什么区别?
提前致谢。
的问候,
答案 0 :(得分:3)
首先,我不会使用Canvas对象而是使用JPanel,而且我会在paintComponent方法覆盖中绘制,而不是绘制方法。可以把JPanel看作是一个画布画布,而将Graphics或Graphics2D看作是你用来画画的画笔。换句话说,您需要两者来创建绘图。
对于Rectangle vs. Rectangle2D,当Graphics2D出现时,2D形状是Graphics的新增功能的一部分。它们基于Shape界面,可以为您的绘图提供更多的灵活性和OOP。
有关详细信息,请查看:
修改强>
回答你的问题:
问:所以你会使用JPanel作为我的空画布和Graphics2D g2d =(Graphics2D)g;创建一种可用于更改JPanel的画笔。因此这个g2d.setColor(Color.BLACK);更改JPanel画布的背景颜色。这是对的吗?
是。您甚至可以通过
更改Graphics2D对象的笔划g2d.setStroke(new BasicStroke(...));
问:也可以向我解释一下" Shape"你用它做什么用?
请查看我上面链接的第二个教程,因为它将详细介绍Shape代表什么以及如何使用它。它总结了所有Xxxxx2D类(如Rectangle2D和Ellipse2D)使用的接口。它允许所有人共享某些属性,包括可填写,可绘制,可转换等等。
编辑2
例如:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import javax.swing.*;
@SuppressWarnings("serial")
public class RotateFoo extends JPanel {
private static final int PREF_WIDTH = 800;
private static final int PREF_HEIGHT = 600;
private static final Color STAR_COLOR = Color.red;
private static final int ROTATE_TIMER_DELAY = 20;
private static final int POINTS = 5;
private static final int RADIUS = 50;
private static final String TITLE = "Press \"r\" to rotate";
private static final float TITLE_POINTS = 52f;
private Path2D star = new Path2D.Double();
private Timer rotateTimer = new Timer(ROTATE_TIMER_DELAY, new RotateTimerListener());
public RotateFoo() {
double x = 0.0;
double y = 0.0;
double theta = 0.0;
for (int i = 0; i <= POINTS; i++) {
x = RADIUS + RADIUS * Math.cos(theta);
y = RADIUS + RADIUS * Math.sin(theta);
if (i == 0) {
star.moveTo(x, y);
} else {
star.lineTo(x, y);
}
theta += 4 * Math.PI / POINTS;
}
double tx = (getPreferredSize().getWidth() - star.getBounds().getWidth()) / 2;
double ty = (getPreferredSize().getHeight() - star.getBounds().getHeight()) / 2;
AffineTransform at = AffineTransform.getTranslateInstance(tx, ty);
star.transform(at );
int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
InputMap inputMap = getInputMap(condition);
ActionMap actionMap = getActionMap();
String rotateOn = "rotate on";
String rotateOff = "rotate off";
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_R, 0, false), rotateOn);
actionMap.put(rotateOn, new AbstractAction() {
public void actionPerformed(ActionEvent arg0) {
if (rotateTimer != null && !rotateTimer.isRunning()) {
rotateTimer.start();
}
}
});
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_R, 0, true), rotateOff);
actionMap.put(rotateOff, new AbstractAction() {
public void actionPerformed(ActionEvent arg0) {
if (rotateTimer != null && rotateTimer.isRunning()) {
rotateTimer.stop();
}
}
});
//rotateTimer.start();
JLabel titleLabel = new JLabel(TITLE, SwingConstants.CENTER);
titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD, TITLE_POINTS));
add(titleLabel);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_WIDTH, PREF_HEIGHT);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(STAR_COLOR);
if (star != null) {
g2.draw(star);
}
}
private class RotateTimerListener implements ActionListener {
private static final double BASE_THETA = Math.PI / 90;
@Override
public void actionPerformed(ActionEvent e) {
double anchorx = getPreferredSize().getWidth() / 2;
double anchory = getPreferredSize().getHeight() / 2;
AffineTransform at = AffineTransform.getRotateInstance(BASE_THETA, anchorx, anchory);
star.transform(at);
repaint();
}
}
private static void createAndShowGui() {
RotateFoo mainPanel = new RotateFoo();
JFrame frame = new JFrame("RotateFoo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
答案 1 :(得分:2)
你必须做出一定的改变:
所以 - 你有两个不同的课程用于不同的目的!我花了一段时间才明白......
原谅我微不足道的英语...