鼠标运动监听器只在一个方向

我一直在研究Java中的鼠标运动监听器无法将其完全排序,因为我希望对象朝着鼠标所指向的屏幕方向移动但不幸的是当鼠标位于applet窗口内时,该对象只向单一方向移动。 这是我的代码如下..

import java.awt.*; import java.awt.geom.*; import java.util.*; import java.applet.*; import java.awt.event.*; import javax.swing.*; public class MouseOver extends Applet implements KeyListener, MouseListener, MouseMotionListener { private int[] Xpoints = { 0, -5, 5 }; private int[] Ypoints = { -10, -2, -2 }; private double xpos, ypos; private Polygon poly; int polyrot = 0; private int width; // !! added private int height; // !! added public void init() { poly = new Polygon(Xpoints, Ypoints, Xpoints.length); addKeyListener(this); addMouseListener(this); addMouseMotionListener(this); } public void paint(Graphics g) { Graphics2D g2d = (Graphics2D) g; AffineTransform id = new AffineTransform(); width = getSize().width; height = getSize().height; g2d.setColor(Color.BLACK); g2d.fillRect(0, 0, width, height); g2d.setColor(Color.RED); g2d.draw(poly); g2d.translate(width / 2, height / 2); g2d.rotate(Math.toRadians(polyrot)); g2d.scale(5, 5); } public void keyReleased(KeyEvent k) { } public void keyTyped(KeyEvent k) { } public void keyPressed(KeyEvent k) { switch (k.getKeyCode()) { case KeyEvent.VK_LEFT: if (polyrot  360) { polyrot = 0; polyrot--; } repaint(); break; } } public void mouseEntered(MouseEvent m) { } public void mouseExited(MouseEvent m) { } public void mouseReleased(MouseEvent m) { } public void mouseClicked(MouseEvent m) { } public void mousePressed(MouseEvent m) { switch (m.getButton()) { case MouseEvent.BUTTON1: if (polyrot  360) { polyrot = 0; polyrot++; } repaint(); break; } } public void mouseMoved(MouseEvent e) { xpos = getX(); if (xpos  0) { polyrot++; } repaint(); // !! break; // Doesn't belong here } @Override public void mouseDragged(MouseEvent e) { // You forgot this method } } 

你的问题在于这一行:

 public void mouseMoved(MouseEvent e){ xpos=getX(); // ****** if(xpos<0){polyrot--;} else if(xpos>0){polyrot++;} repaint(); break; } 

返回applet的x位置而不是鼠标光标。 你需要使用你的MouseEvent对象,而不是鼠标的位置。 将其更改为:

 xpos = e.getX(); 

请不要忽略我对您的问题所做的评论。 请记住,我们是帮助我们空闲时间的志愿者。 请不要让它比帮助你更困难。


我试图编辑你的代码,以便编译,现在缩进。 考虑创建一个Swing应用程序,而不是AWT应用程序,因为Swing应用程序更灵活,更强大,更强大。

这个:

  if (xpos < 0) { 

表示“如果光标位于面板之外”。

这个:

  xpos = getX(); 

没有获得鼠标坐标。

将您的活动更改为以下内容:

 public void mouseMoved(MouseEvent e) { xpos = e.getX(); if (xpos < getWidth() / 2) { polyrot--; } else { polyrot++; } repaint(); } 

现在,如果光标位于面板左侧,则逆时针旋转,如果光标位于右侧,则顺时针旋转。

这个:

  g2d.draw(poly); g2d.translate(width / 2, height / 2); g2d.rotate(Math.toRadians(polyrot)); g2d.scale(5, 5); 

不会做任何改变图像的事情,因为你在绘制之后正在进行转换。

这个:

  Graphics2D g2d = (Graphics2D) g; 

这是一个坏主意,因为您正在将变换应用于全局图形上下文,这将继续进行其他组件的后续重新绘制。

将你的油漆改成这样的东西:

 public void paint(Graphics g) { super.paint(g); Graphics2D g2d = (Graphics2D) g.create(); width = getSize().width; height = getSize().height; g2d.setColor(Color.BLACK); g2d.fillRect(0, 0, width, height); g2d.translate(width / 2, height / 2); g2d.rotate(Math.toRadians(polyrot)); g2d.scale(5, 5); g2d.setColor(Color.RED); g2d.draw(poly); g2d.dispose(); } 

进一步阅读:

  • 在AWT和Swing中绘画
  • 如何编写鼠标侦听器

有几件事……

在你的keyPressedmousePressed事件中,只会处理越界条件,例如……

 if (polyrot < 0) { polyrot = 359; polyrot++; } //... if (polyrot > 360) { polyrot = 0; polyrot--; } 

但是当它在可接受的范围内(0-359)时,你永远不会处理它应该做的事情……

相反,你可以简单地从polyrot添加或减去数量,并允许API处理它(令人惊讶的是,它能够处理角度<0和> 359),例如……

 public void mousePressed(MouseEvent m) { switch (m.getButton()) { case MouseEvent.BUTTON1: polyrot--; repaint(); break; case MouseEvent.BUTTON2: polyrot++; repaint(); break; } } 

现在,我不确定你的意思是“物体向鼠标指向的屏幕方向移动” 。 这是否意味着对象应该实际改变它的x / y坐标,或者只是“看”鼠标光标……

基于你实际上没有移动代码的事实,你基本上把对象画在一个固定的位置,我假设“看看”……

基本上,你需要知道鼠标的位置和对象的位置,然后确定它们之间的角度……

 public void mouseMoved(MouseEvent e) { int x = width / 2; int y = height / 2; Point mousePoint = e.getPoint(); int deltaX = mousePoint.x - x; int deltaY = mousePoint.y - y; polyrot = -Math.atan2(deltaX, deltaY); polyrot = Math.toDegrees(polyrot) + 180; repaint(); } 

您应该注意我将’polyrot’更改为’double’

你的paint方法也错了。 基本上,你在改造之前就是在画你的物体,相反,你应该使用更像……

 g2d.translate(width / 2, height / 2); g2d.rotate(Math.toRadians(polyrot)); g2d.draw(poly); 

在应用自己的自定义绘画之前,您还应该调用super.paint(g)

作为旁注,您应该避免覆盖顶级容器的paint ,例如JApplet ,而是创建一个自定义组件,从JPanel扩展并覆盖它的paintComponent方法,在那里执行自定义绘制(不要忘记调用super.paintComponent )。 有关更多详细信息,请参阅执行自定义绘画

您还应该避免使用KeyListener ,而是使用Key Bindings API,因为它不会遇到与KeyListener相同的焦点问题…

更新了runnable示例

所以我玩了代码并制作了这个简单的例子……

在此处输入图像描述

基本上,我抛弃了Polygon以支持Path2D ,主要是因为它提供了更多的function,并且在缩放时很容易处理;)

 import java.applet.Applet; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Polygon; import java.awt.Rectangle; import java.awt.Shape; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.geom.AffineTransform; import java.awt.geom.Path2D; public class MouseOver extends Applet implements KeyListener, MouseListener, MouseMotionListener { private double xpos, ypos; private Path2D poly; private double polyrot = 0; private int width; // !! added private int height; // !! added public void init() { poly = new Path2D.Double(); poly.moveTo(0, 10); poly.lineTo(5, 0); poly.lineTo(10, 10); poly.lineTo(0, 10); poly.closePath(); addKeyListener(this); addMouseListener(this); addMouseMotionListener(this); } public void paint(Graphics g) { super.paint(g);; Graphics2D g2d = (Graphics2D) g; AffineTransform id = new AffineTransform(); width = getSize().width; height = getSize().height; g2d.setColor(Color.BLACK); g2d.fillRect(0, 0, width, height); g2d.setColor(Color.RED); id.scale(5, 5); Shape scaled = poly.createTransformedShape(id); Rectangle bounds = scaled.getBounds(); g2d.translate((width - bounds.width) / 2, (height - bounds.height) / 2); g2d.rotate(Math.toRadians(polyrot), bounds.width / 2, bounds.height / 2); g2d.setStroke(new BasicStroke(5f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); g2d.draw(scaled); } public void keyReleased(KeyEvent k) { } public void keyTyped(KeyEvent k) { } public void keyPressed(KeyEvent k) { switch (k.getKeyCode()) { case KeyEvent.VK_LEFT: polyrot++; repaint(); break; case KeyEvent.VK_RIGHT: polyrot--; repaint(); break; } } public void mouseEntered(MouseEvent m) { } public void mouseExited(MouseEvent m) { } public void mouseReleased(MouseEvent m) { } public void mouseClicked(MouseEvent m) { } public void mousePressed(MouseEvent m) { switch (m.getButton()) { case MouseEvent.BUTTON1: polyrot--; repaint(); break; case MouseEvent.BUTTON2: polyrot++; repaint(); break; } } public void mouseMoved(MouseEvent e) { int x = width / 2; int y = height / 2; Point mousePoint = e.getPoint(); int deltaX = mousePoint.x - x; int deltaY = mousePoint.y - y; polyrot = -Math.atan2(deltaX, deltaY); polyrot = Math.toDegrees(polyrot) + 180; repaint(); } @Override public void mouseDragged(MouseEvent e) { // You forgot this method } } 

从这里:

 public void mouseMoved(MouseEvent e){ xpos=getX(); if(xpos<0){polyrot--;} else if(xpos>0){polyrot++;} repaint(); break; } 

看来你只更新了xpos。 您还应该更新变量ypos。 您可能希望使用以下内容执行此操作:

 ypos=e.getY(); if (this.ypos<0){ this.polyrot--; }else if (this.ypos>0) { this.polyrot++; } this.repaint();