mouse motion listener only in one direction

后端 未结 4 923
粉色の甜心
粉色の甜心 2020-12-07 00:28

i have been working on mouse motion listener in Java couldn\'t sort it out completely because i want the object to move towards the direction where ever on the screen the mo

相关标签:
4条回答
  • 2020-12-07 00:45

    This:

      if (xpos < 0) {
    

    means "if the cursor is outside of the panel".

    This:

      xpos = getX();
    

    does not get a mouse coordinate.

    Change your event to something like this:

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

    Now it rotates counter-clockwise if the cursor is on the left side of the panel and clockwise if the cursor is on the right side.

    This:

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

    will not do anything to change the image because you are doing your transforming after drawing it.

    This:

      Graphics2D g2d = (Graphics2D) g;
    

    is a bad idea because you are applying transforms to the global graphics context which would carry on to subsequent repaints of other components.

    Change your paint to something like this:

    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();
    }
    

    Further reading:

    • Painting in AWT and Swing
    • How to Write a Mouse Listener
    0 讨论(0)
  • 2020-12-07 00:46

    From here:

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

    It seems you update only the xpos. You should update also the variable ypos. You might want to do it with something like this:

    ypos=e.getY();
    if (this.ypos<0){
     this.polyrot--;
    }else if (this.ypos>0) {
     this.polyrot++;
    }
    this.repaint();
    
    0 讨论(0)
  • 2020-12-07 00:58

    Your problem is with this line:

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

    That returns the x position of the applet not the mouse cursor. You need to use your MouseEvent object, e and instead get the mouse's position. Change it to:

    xpos = e.getX();
    

    Please don't ignore the comment that I made to your question. Please remember that we're volunteers who help on our free time. Please don't make it any more difficult than it has to be to help you.


    I've tried to edit your code so that it compiles, and now is indented. Consider creating a Swing application, not an AWT application, since Swing apps are more flexible, powerful and robust.

    0 讨论(0)
  • 2020-12-07 01:06

    There are a few things...

    In your keyPressed and mousePressed events, are are only ever process the out of bounds conditions, for example...

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

    But you never process what it should do when it's within the acceptable bounds (0-359)...

    Instead, you could simply add or subtract the amount from polyrot and allow the API to deal with it (surprisingly, it's capable for dealing with angles < 0 and > 359), for example...

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

    Now, I'm not sure what you mean by "object to move towards the direction where ever on the screen the mouse is pointed". Does this mean that the object should actually change it's x/y coordinates or should it just "look" at the mouse cursor...

    Based on the fact that you actually have no movement code and you basically have the object painted in a fixed location, I'm assuming "look at"...

    Basically, you need to know where the mouse is and where the object is, then determine the angle between them...

    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();
    }
    

    You should note that I changed 'polyrot' to 'double'

    Your paint method is also wrong. Basically, you are painting your object BEFORE you've transformed it, instead, you should be using something more like...

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

    You should also be calling super.paint(g) before you apply you own custom painting...

    As a side note, you should avoid overriding paint of top level containers, like JApplet, but instead, create a custom component, extending from something like JPanel and override it's paintComponent method, performing your custom painting there (don't forget to call super.paintComponent). Take a look at Performing Custom Painting for more details

    You should also avoid using KeyListener and instead use the Key Bindings API as it doesn't suffer from the same focus issues that KeyListener does...

    Updated with runnable example

    So I had a play around with code and produced this simple example...

    enter image description here

    Basically, I tossed out Polygon in favour of Path2D, basically because it provides much greater functionality and is easy to deal with when scaling ;)

    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
        }
    }
    
    0 讨论(0)
提交回复
热议问题