【发布时间】:2022-01-17 02:35:07
【问题描述】:
所以我使用继承 JComponent 的名为 Ornament 的对象检测鼠标时遇到问题,并且我使用 java.awt.event.MouseEvent 获得鼠标点击。
我和我的团队最好的解决方案是比较每个饰品到鼠标的距离,如果它小于 50(这是饰品的半径),它会做一些事情。
private class ME implements MouseListener {
@Override
public void mouseClicked(MouseEvent e) {
for(int i = 0; i < ORNAMENT_AMOUNT; i++) {
Ornament current = oh.getOrnament(i);
int distance = (int)(Math.sqrt(((e.getX() - current.getX()) * (e.getX() - current.getX())) + ((e.getY() - current.getY()) * (e.getY() - current.getY()))));
if(distance <= 50) {
System.out.println("CIRCLE CLICKED!");
current.reset();
}
}
}
我遇到的问题是它无法正常工作。我在同一个地方点击了很多次,最终它会在其中一个装饰品上触发事件。它随机且令人困惑。
这里是装饰类
//ornament class to define the game object ornament
public class Ornament extends JComponent{
private int xPos;
private int yPos;
private int velocity;
private int screenWidth;
private int screenHeight;
private Random rand;
public Ornament(int screenWidth, int screenHeight, int velocity) {....}
public int getY() { return yPos; }
public int getX() { return xPos; }
@Override
public void paintComponent(Graphics graphics) {
float r = rand.nextFloat();
float g = rand.nextFloat();
float b = rand.nextFloat();
super.paintComponent(graphics);
graphics.setColor(new Color(r, g, b));
graphics.fillOval(0, 0, 50, 50);
}
....
public void reset() {
this.yPos = -(int)(Math.random()*500);
this.xPos = (int)(Math.random()*screenWidth);
this.velocity += 1;
update();
}
}
我对此的整个方法可能是错误的,但在我的脑海中似乎是正确的,因此我们将不胜感激! :)
*note oh 是我创建的一个 objecthandler 类,用于在具有一系列装饰品的不同线程中运行游戏循环
public class ObjectHandler implements Runnable {
private int size;
private Ornament[] list;
private GUI game;
public ObjectHandler(int size, GUI game) {
....
list = new Ornament[size];
//init object list
for(int i = 0; i < size; i++) {
list[i] = new Ornament(game.getFrameX(), game.getFrameY(), game.getStartingVel());
game.add(list[i]);
}
}
public Ornament getOrnament(int index) { return list[index]; }
public void run() {
while(true) {
try {
Thread.sleep(50);
} catch (InterruptedException e) { e.printStackTrace(); }
game.loadBackground();
for(int i = 0; i < size; i++) {
if(list[i].getY() >= game.getFrameY())
list[i].reset();
else
list[i].update();
}
}
}
}
【问题讨论】:
-
你在哪里添加你的
MouseListener? -
Ornament 应该是一个普通的 Java getter/setter 类。你创建了一张
JPanel并在JPanel上绘制你所有的精灵。 Oracle 教程Performing Custom Painting 将向您展示 Swing 绘图的工作原理。 -
@hfontanez 鼠标监听器在 JFrame 的构造函数中 addMouseListener(new ME());
-
绘画方法不应该使用随机逻辑。您无法控制 Swing 何时重新绘制组件,因此您不希望绘制随机更改。您在绘画方法之外设置组件的状态。查看:stackoverflow.com/questions/67443343/drag-a-painted-shape 的示例,该示例在使用鼠标时绘制形状并支持命中检测。
-
此外,我认为您不希望
JFrame有一个MouseListener,然后必须询问事件对象以确定哪个组件触发了事件。每个Ornament是一个JComponent(这是一个Container),因此,每个MouseListener都可以拥有自己的MouseListener。在我看来,这是最好的方法。每个产生的MouseEvent都会告诉你它属于哪个Ornament实例。
标签: java swing awt collision-detection collision