我有一个名为“ MapObject”的类,该类可让您定义它的用途。我最近在此添加了文本,但效果很好,但是碰撞是一个矩形,在某些情况下并不可怕,但是我更希望有一个与文本匹配的碰撞盒(也就是检查1x1矩形是否与文字,但仍可以在字母之间)
我尝试了以下方法:
GlyphVector vec = ob.font.createGlyphVector(new Canvas().getFontMetrics(ob.font).getFontRenderContext(), ob.text);
Shape textSh = vec.getOutline();
Area obSh = new Area(new Rectangle(x,y,o.width,o.height));
obSh.intersect(new Area(textSh));
boolean inter = !obSh.isEmpty();
但是,由于位置原因,我认为它不起作用,但是我不知道如何在其中添加位置。 谢谢。
答案 0 :(得分:0)
您可能需要做的一件事是将GlyphVector
或Rectangle
转换为正确的上下文。
我的意思是,GlyphVector
仅代表0x0
的原点上的文本,因此,如果文本显示在屏幕上的其他位置,那么您将无法获得正确的表示形式
幸运的是,实际上有人想到了这个用例,并提供了一些功能来做到这一点。有关更多详细信息,请参见GlyphVector#getOutline(float, float)
。
然后您可以使用类似...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private List<Rectangle> boxes;
private Map<Rectangle, Point> vectors;
public TestPane() {
boxes = new ArrayList<>(25);
vectors = new HashMap<>(25);
Random random = new Random();
for (int index = 0; index < 10; index++) {
int x = random.nextInt(400 - 10);
int y = random.nextInt(400 - 10);
Rectangle box = new Rectangle(x, y, 10, 10);
boxes.add(box);
int xDelta = random.nextBoolean() ? 1 : -1;
int yDelta = random.nextBoolean() ? 1 : -1;
vectors.put(box, new Point(xDelta, yDelta));
}
Timer timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
for (Rectangle box : boxes) {
Point delta = vectors.get(box);
if (delta == null) {
int xDelta = random.nextBoolean() ? 1 : -1;
int yDelta = random.nextBoolean() ? 1 : -1;
delta = new Point(xDelta, yDelta);
}
int x = box.x + delta.x;
int y = box.y + delta.y;
if (x < 0) {
x = 0;
delta.x *= -1;
} else if (x + box.width > getWidth()) {
x = getWidth() - box.width;
delta.x *= -1;
}
if (y < 0) {
y = 0;
delta.y *= -1;
} else if (y + box.height > getHeight()) {
y = getHeight() - box.height;
delta.y *= -1;
}
box.setLocation(x, y);
vectors.put(box, delta);
}
repaint();
}
});
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 200);
}
protected Shape getTextShape() {
Graphics2D g2d = (Graphics2D) getGraphics();
if (g2d == null) {
return null;
}
Font font = new Font("Arial", Font.BOLD, 48);
g2d.setFont(font);
FontRenderContext frc = g2d.getFontRenderContext();
GlyphVector gv = font.createGlyphVector(frc, "Cats with hats");
Rectangle2D box = gv.getVisualBounds();
// Calclate the location of the text and offset the glyph shape...
float x = (float) (getWidth() - box.getWidth()) / 2f;
float y = (float) (((getHeight() - box.getHeight()) / 2f) + (-box.getY()));
return gv.getOutline(x, y);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
Shape shape = getTextShape();
g2d.setColor(Color.BLACK);
g2d.fill(shape);
g2d.setColor(Color.RED);
g2d.draw(shape);
for (Rectangle box : boxes) {
g2d.setColor(Color.BLACK);
if (shape.intersects(box)) {
g2d.setColor(Color.RED);
}
g2d.draw(box);
}
}
}
}