0

I have a mouse event handler and under mouseMoved I have this:

public void mouseMoved(MouseEvent e)
{
  if((e.getX()>=0 && e.getX()<=100) && (e.getY()>=0 && e.getY()<=100))
  {
    robot.mouseMove(mainOutput.getX()+200,mainOutput.getY()+200);
  }
}

What this does is that if the user tries to move towards the first 100x100 pixels of the frame, the pointer will translated. What I want to do however is recreate an "impassable wall".

Basically when the user attempts to go in the region it cannot pass the end points of the region. What I want to know is how would I go about doing this?

Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
SelfDeceit
  • 107
  • 1
  • 2
  • 13
  • You seem to have an idea of what you should be doing, so why don't you try to implement it? Also, [please don't ask the same question more than once](http://stackoverflow.com/questions/17017012/restricting-mouse-movement-in-java-eclipse). – Zong Jun 13 '13 at 01:10
  • That is directly from my program. I want to alter it to do what I'm wondering is possible. EDIT: Well I'm having trouble implementing it, maybe if I incorporate a cardinal system? – SelfDeceit Jun 13 '13 at 01:13
  • If it's in your code, then what is your question? You've stated how you went about doing it, and now you're asking how to go about doing it? – Zong Jun 13 '13 at 01:15
  • Are you doing this in swing? – Bnrdo Jun 13 '13 at 01:39
  • Yes, this is in Java swing. For those who don't know. I haven't achieved this effect yet. Right now all I can do is translate the pointer to a point once it's in a specified region. What I want to do is translate it in a way where it appears you've hit a wall. Similar to a pointer being in a locked-frame. – SelfDeceit Jun 13 '13 at 01:47
  • 2
    This is exactly would you should have added to your question. It's helpful to know what you tried and doesn't work, rather than let us guess what's even wrong, right? – Zong Jun 13 '13 at 01:58
  • My apologies +1 for being kind! – SelfDeceit Jun 13 '13 at 02:21

3 Answers3

1

I think you just need to clarify to yourself what the behaviour of a mouse hitting a wall would be, in terms of coordinates.
Hopefully this terrible image helps;

pls dont judge my bad pic

Whenever the mouse moves, you want to check if it's in the forbidden region (the region beyond the wall; the no man's land). To do this, just check if the x coordinate (assuming a horizontal wall in this example) of the mouse is beyond its limit (the x coordinate of the wall).
If it is, move the mouse back to the wall, preserving its y value (set its x coordinate to that of the wall)

FOR A CAGE:

The case of having a surrounding, square wall is a little bit more complicated, in terms of where to place the mouse when breaching the wall.
Observe that there are 8 different regions to consider where the mouse could enter the 'forbidden zone', and each boundary should translate the mouse differently.

The coordinate of the boundary corners are in red (and consist of 4 values; xL, xR, yT, yB for left, right, top, bottom respectively)).
The green text in each region describes the conditions that must all be true for the mouse to lie in that region (they're how you detect the mouse must be in that region) where x and y are the mouse coordinates.

not so bad pic

You can see that the four 'side' regions involve a simple translation; just altering one of the coordinates of the mouse (the x coordinate for a vertical wall, y for a horizontal wall) to match that of the wall.
The four 'corner' regions can entirely change the mouse coordinate (to their corner coordinate!)

Anti Earth
  • 4,671
  • 13
  • 52
  • 83
  • This method doesn't work even for his current case (square at top corner). What happens when both x and y are inside? Does it snap to the corner? Why should it? – Zong Jun 13 '13 at 02:07
  • I assumed he has the ability to translate this idea into a corner.. (ie; two walls). Why would anything happen when both x and y are inside? They're not past the boundary – Anti Earth Jun 13 '13 at 02:09
  • Well I placed it in the top corner just to test it out. The real "no-mans-land" will be closer to the center of the screen. So from all directions. EDIT: Okay, now I understand the image. I'm presuming this can be applied to the top and bottom walls BUT wouldn't that mean I'd have to create walls (lines ie. x=40) for every impassable region? I'm looking at 10 "no-mans-land" so that's 40 right there. Should I just bite the bullet and go for it? – SelfDeceit Jun 13 '13 at 02:10
  • @SelfDeceit Yes, I'll post an answer to illustrate the corner problem and how to mitigate it. – Zong Jun 13 '13 at 02:11
  • @SelfDeceit I've updated my answer, focusing on your 'square boundary' situation – Anti Earth Jun 13 '13 at 02:24
  • @AntiEarth Actually no, it's still no good. Why should a quadrant starting from a corner go to corner? What if it hits an edge diagonally? As it currently stands, he only reacts once the cursor is *inside the box*. What if a very fast movement occurs, and you go from one side to near exiting the opposite edge? (eg for small boundaries) – Zong Jun 13 '13 at 02:25
  • @ZongZhengLi can you please justify your criticism? It's almost offensive. SelfDeceit, 40 walls? What exactly is it that you're trying to make? A 'cage' for the mouse or a bunch of 'obstacles'? – Anti Earth Jun 13 '13 at 02:27
  • @ZongZhengLi What do you mean 'why sould a quadrant starting from a corner go to a corner?': that's the shortest distance for the mouse to be translated, and if you tested it out, gives the most 'real' impression of a boundary. The OP has not specified anything about diagonal edges (there's nothing deficient about hitting the edge diagonally? I think you need to test this for yourself...). Escaping the boundary for a split second is a very real and tolerable situation, present in most simple 2D / flash video games. – Anti Earth Jun 13 '13 at 02:33
  • @AntiEarth Let's say you detect the mouse inside the box near the corner. Where do you put it? Where did it come from? Sure you can save the previous location, but what if the cursor started in a corner, crossed one of your dotted lines directly into the box. What now? – Zong Jun 13 '13 at 02:36
  • @ZongZhengLi I think this solution would seem to work, I am aware of the velocity of the mouse affecting how the boundaries work. – SelfDeceit Jun 13 '13 at 02:37
  • @ZongZhengLi One of us misunderstands the problem... The OP is trying to contain the cursor INSIDE a box. The cursor can never leave the box... If moving inside the box, the cursor does not need to be moved... EDIT: Yes, I see your misunderstanding. This is a 'cage' for the box, rather than an 'obstacle' – Anti Earth Jun 13 '13 at 02:38
  • @AntiEarth Yes, in this situation there is only one of two possiblities. And I'd like invite you to re-read OP's specifications. – Zong Jun 13 '13 at 02:40
  • To clear things up. I am not using diagonal sided boundaries, only rectangles. Also @AntiHero I am trying to keep the mouse **outside** of the box, in other words an obstacle. Besides that, I'm sure we could alter your solution for an obstacle, no? – SelfDeceit Jun 13 '13 at 02:40
  • @ZongzhengLi Ah, I see (not a particular fan of the short, ambiguous wording in OP's specs..). You're right, this won't work for a closed obstacle. SelfDeceit, I'm afraid this can't be easily inverted to be an obstacle, you will have to consider the path of the cursor – Anti Earth Jun 13 '13 at 02:53
1

Assuming the impassable area is a JPanel, you can add a mouse listener to it that will respond whenever the mouse enters the area, and then do the relocation stuff that you already have.

   JPanel pnlArea = new JPanel();
   pnlArea .addMouseListener(new MouseAdapter() {
      @Override public void mouseEntered(MouseEvent arg0) {
         //execute some codes if the mouse pointer has enterd the area.
      }
   });
Bnrdo
  • 5,325
  • 3
  • 35
  • 63
  • This is a good suggestion, but I think he's past this stage and is trying to figure out the calculations. – Zong Jun 13 '13 at 02:12
  • He commented "_What I want to do is translate it in a way where it appears you've hit a wall_" to me sounds like he already can relocate the mouse pointer, he only needs the "hit the wall" event which I think is what I'm suggesting now. – Bnrdo Jun 13 '13 at 02:16
  • Well can I use `mouseEntered` to keep the mouse outside of the region thus creating the "wall" illusion? When I did research on this, this was brought up but the original poster did not explain how. – SelfDeceit Jun 13 '13 at 02:18
  • @SelfDeceit Your problem requires a bit of math, and I'll soon explain why in my answer. – Zong Jun 13 '13 at 02:19
  • @ZongZhengLi The only math I can think of is either Cardinal Directions or the use of the Distance Formula, but I'm interested to see what you've come up with. – SelfDeceit Jun 13 '13 at 02:22
1

Unfortunately, this is a bit more difficult than it seems. Let me first illustrate the problems with a simple move-to-outside-of-boundary approach.

enter image description here

As you can see, in this case the boundary approach will detect the mouse inside the boundary, and move it to the blue point in the corner. Let me emphasize this, it detects the location of the mouse. What we want is to capture the movement of the cursor, and have it end at the red point. There are also other problems with this method that may not be immediately apparent.

So how do we capture the movement of the mouse? We need to capture the mouse displacement (black arrow) as a vector by keeping track of the previous location as well. I assume you can do this. So how do we calculate the new location? Well, we can perform line intersection of the displacement vector with the lines that make up the edges of the box. As you're only dealing with horizontal and vertical lines, it is greatly simplified and can be done with just a bit of thinking. If you're lazy, copy a generalized line intersection algorithm.

You may think that this approach is too rigorous, but it is the most robust way. I can already think of two additional issues with the simpler approach. Also, you're actually doing 2D hitbox detection. This is quite a useful thing to know.

Zong
  • 6,160
  • 5
  • 32
  • 46
  • It seems like the boundary approach is coming from inside the region acting as a cage, I'm using the regions as an obstacle. Nevertheless it seems like I'll have to something similar. (I think?) – SelfDeceit Jun 13 '13 at 02:54
  • @SelfDeceit The boundary approach works well enough if there were no corners, no opposite sides to exit from, and no corners (of space) produced from having two boundaries next to each other. – Zong Jun 13 '13 at 02:56
  • My approach is from an entire misunderstanding of the question. Disregard :-) – Anti Earth Jun 13 '13 at 02:57
  • Thank you both for your effort and time. – SelfDeceit Jun 13 '13 at 03:10