I have a problem which I have to solve with my code. So I have a checkerboard and when I click on something I want to drag around (i.e. checker), I make visible a label which holds picture of it (I know it ain't the neat solution but I was told to do it so) in a proper place calculated by a fomula. I wanted to use the same formula to be able calculate coordinates of the checker under mouseDragged event but here's the problem. If I just set the location of the label by simple getX() or getY() from the event then it's top left corner is "jumping" under my mouse pointer as soon as I move the mouse. I'd like it to stick to the cursor in the place I clicked it, so I did something like this:
public void mouseDragged(MouseEvent evt) {
int col = (evt.getX() - 4) / 40;
int row = (evt.getY() - 4) / 40;
int setX = evt.getX()-(col*40);
int setY = evt.getY()-(row*40);
if (dragged)
inv.setLocation(evt.getX()-setX+42, evt.getY()-setY+37);
where col is the X coordinate of the column I want to drage the checker from (and so is the row) and setX is just a variable I'm using below. And these calculations seem to be ok to me, but they make me able only to drage the checker in a manner where it doesn't move at all (like I was dragging something transparent) and when I enter finally a new place on the board it's being painted there and so on. Not a fluent drag but it's being consequently drawn in the fields under my cursor during dragging.
The +42 and + 37 are just some numbers to calcualte it in proper place since the board isn't starting from (0,0).
The reason the corner of the checker is "jumping" to your mouse is because of the way images are drawn. When you set the coordinates of the image you are setting the point P(0,0) of the image, which is the top-left corner when drawn on a screen.
To fix this issue, in addition to keeping track of the row and column number, you need to keep track of the x and y offset (in pixels) you want to maintain though the mouse movement in each checker board "cell".
This means when you click, you might click the checker in row 2, column 3, with an (x, y) offset of (12,14). I am assuming your squares are larger than 14x14 pixels.
I turned your 42 into BOARD_X_OFFSET and 37 into BOARD_Y_OFFSET
I have added two doubles cellX and cellY which hold the offset within the cell.
This will make your set location look similar to this:
inv.setLocation(evt.getX()-setX+BOARD_X_OFFSET+cellX, evt.getY()-setY+BOARD_Y_OFFSET+cellY);
Related
Can anybody tell me how I can stop the rectangles from going off the panel (screen) in my game? The rectangles move side by side with keystrokes.
Here is what you should do :
1. Keep a track of (x,y) coordinates of your rectangles.
2. Ensure that x + width of your rectangle is not greater than width of the JPanel for checking the collision with right edge
3. Ensure that x is not less than 0 to check the collision left edge.
4. Ensure that y + height is not greater than height of the JPanelto check the collision with bottom edge
Can you guess what it will be for the top edge ?
Don't use a KeyListener. Swing was designed to be used with Key Bindings.
See Motion With the Keyboard for working examples. The examples will also do boundary checking to make sure the component is contained within its parents bounds.
I am writing a Java program that closely mimics Microsoft Paint. It can draw four different shapes: Lines, Ovals, Rectangles, and Squares. I am very close to finishing this but I am stuck on the logic for drawing squares.
There are two Points involved while drawing these shapes. The first Point(point1) is when the user presses the mouse button and the second Point(point2) is while the user drags the mouse across the canvas. I believe drawing Rectangles and Squares should be quite similar but the part that has confused me is when drawing a square the sides are equal length so point2 isn't exactly where the mouse is.
Here is the fillRect() method header for reference:
fillRect(x, y, width, height)
My functioning code for drawing rectangles is as follows:
g.fillRect((((point1.x < point2.x) ? point1.x : point2.x)),
((point1.y < point2.y) ? point1.y : point2.y),
Math.abs(point2.x - point1.x),
Math.abs(point2.y - point1.y));
I tried using the same code for drawing squares except changing the height parameter to be equal to the width parameter because squares have equal length sides:
g.fillRect((((point1.x < point2.x) ? point1.x : point2.x)),
((point1.y < point2.y) ? point1.y : point2.y),
Math.abs(point2.x - point1.x),
Math.abs(point2.x - point1.x)); //same as width
I don't know what the problem is with making both width and height equal. It works when drawing downwards to the left or right but of course the shape does not expand if you pull straight down. Clicking and dragging up does not work; the square simply moves up with the mouse along the Y axis instead of expanding.
Could anyone point me in the right direction regarding the logic for drawing square from two points?
I can explain my code a bit better if need be.
If I were using a tool to draw a square, I would expect that my mouse cursor would remain on one of the sides of the square while drawing. If you always use the x distance as the side, then if I've drawn farther down than across, the cursor will be outside the square.
I think, while the dragging is going on, the code would need to calculate whether the x distance or the y distance to the origin is the longer, and use that as the side of the square-in-progress. Then the cursor will be on one of the sides, and that side will extend out beyond the cursor to the corner of the square-in-progress.
I don't know why the drawing is going awry -- it is difficult to be sure I understand what you say is going wrong.
You should do two calculations in your MouseDragged method -- first you should calculate the two corner Points of the rectangle, p1, and p2, and only then should you calculate the width. Point p1 is easy -- it's always the first Point pressed, but p2 will require a simple calculation. Once these are clarified, your calculations should fall out correctly.
i.e., something like:
int width = Math.abs(pointA.x - pointB.x);
int height = Math.abs(pointA.y - pointB.y);
width = Math.max(width, height);
height = width;
int x = pointA.x > pointB.x ? pointA.x - width : pointA.x;
int y = pointA.y > pointB.y ? pointA.y - width : pointA.y;
g.fillRect(x, y, width, height);
I am developing a first person shooter in Java and I want to implement controls in which movement of the mouse rotates the player. However in Java, I can only get mouse coordinates by using MouseListener events, so the coordinates will stop changing once the mouse cursor leaves the monitor edge and I will be unable to turn the player's view.
Any tips/suggestions on how to do that? Thanks.
I tried using a java.awt.Robot as AerandiR suggests, but there were a couple of problems I ran into, and it's possible other people will run into them as well, so I will elaborate.
If your goal is to keep the cursor in one position (preferably the center of the screen), then you will want to call something like robot.mouseMove(width/2, height/2); at the end of your mouseMoved() method. With this implementation, every time the mouse is moved off center, the Robot will move it back to the center.
However, when the Robot re-centers the mouse, the player will turn back to where it was. In effect, the player will stutter between the original position and a turned position.
To fix this, instead of defining how far your player turns on the difference between where the mouse is now and where it was, define it as the distance from the center.
Like so: turnAmountX += e.getX() - width/2;
Now, if the Robot re-centers the mouse, e.getX() - width/2 will always yield zero.
Recap:
void mouseMoved(MouseEvent e) {
turnAmountX += e.getX() - width/2;
turnAmountY += e.getY() - height/2;
robot.mouseMove(this.getLocationOnScreen().x + width/2,
this.getLocationOnScreen().y + height/2;
}
In some games, on every mouse movement event the cursor is moved back to the middle of the screen, and the view moves with the corresponding magnitude and direction of the mouse event. You can get that vector by calculating the offset of the cursor position to the center of the screen prior to centering the cursor. To move the cursor back to the center of the screen you can try using the java.awt.Robot class.
Since you're building a first person shooter, you'll probably want to hide the center locked cursor, and draw your own crosshair where the player is intending to aim. That will also involve keeping track of where the cursor should be based on the running total of previous mouse movement events.
If you want to achieve behaviour where the view will continue moving relative to the starting position of the mouse (even once the mouse has stopped moving), you could keep a moving sum of all the previous mouse movement vectors, and move the view correspondingly once every frame. However, this probably applies more to something like a flight simulator than a first person shooter.
Alright, I know HOW to do but It's doing something weird.
I am trying to get the correct X Y coords for a JMenu to appear. I've found a way but it's only a hack. All the right-clicking takes place on the JList, for now until I add character panel, so let's say you right-click near the top-left. You expect the Y coord to be around 40~ pixels and the Y coord to be around 100~ pixels right? Because you're clicking on the near left where the JList is. Wrong. The x y coords count from the top left of the JList when I want it to count from the top left of the WHOLE application. :S
So, what did I do? Since the Y coord is correct, I added 512 pixels to the X coord so it's always in the JList. Like so:
int newMouseX = 512+e.getX();
popup.show(tileOffline.this, newMouseX, e.getY()); // show item at mouse
However, as you can tell I will not be right-clicking in the JList forever.
How can I make it so I get the exact X Y coords of the mouse from the WHOLE applet?
Here's a pic to describe the situation WITHOUT the 512 hack:
I wonder if you're making this harder than it needs to be. The popup menu will position itself relative to the component you pass into the show method (JPopupMenu API). You should just be able to show the popupmenu doing something like this in order to get it to show at the correct location:
popup.show(myJList, e.getX(), e.getY());
SwingUtilities has methods suitable for converting to and from screen coordinates, as well as among Components.
You can use convertPointToScreen in javax.swing.SwingUtilities to convert to screen coordinates - just pass in the component that you're clicking!
convertPointToScreen(Point p, Component c)
http://download.oracle.com/javase/6/docs/api/javax/swing/SwingUtilities.html
Use the MouseEvent.getXOnScreen() and MouseEvent.getYOnScreen() methods.
The MouseEvent that gets generated when you move or click a mouse contains the absolute coordinates on the screen. Use these two methods to get them.
I need ideas about how to move an object (a circle which represents a robot in my application).
The surface the object will be moving on consists of Tiles of BufferedImage of 3 rows and 3 columns ( represented in arrays). All the Tiles are equal in sizes (160 X 160).The 3rd row and the 3rd column are the track rails on which the object must be moving on.
It means that the object(robot) can move horizontal (forward and backward) and vertical (upwards and downwards).
The Tile at the position [2][2] (please am counting from top. so the top row will be 0 the next afterward is 1 etc.. ) is a crossing which the robot will use to change to the vertical track rails or to the horizontal track rails.
My problem now is how to move the object to a specific Tile after the crossing has turned. For instance the robot will be in the Tile at position [2][1] and want to move to the tile at position [1][2] after the crossing is turned and then move further upwards. Or it can be at [1][2] and want to move to [2][1] after the crossing is turned and then move further backwards .
How can i move the robot from one Tile to another Tile? Which way can i refer to a specific Tile in the BufferedImage that i can place the object. All what i want is give me the ideas how i can do it.
Please this is my first time of doing such project so forgive me if my question is too elementary. With your explanation and help i will learn more from it.
Thank you very much.
In order to display your image you need to figure out the bounds of the grid you want to put your image into. I usually create two helper methods, one to translate grid coordinates into display coordinates and the other one to go the other direction.
private Point convertGridToDisplay(int x, int y) {
return new Point(x * 160, y * 160);
}
private Point convertDisplayToGrid(int x, int y) {
return new Point(x / 160, y / 160);
}
convertGridToDisplay() will give you the upper left hand coordinate where you should draw your image to.
For example:
Point point = convertGridToDisplay(2, 1);
graphics.drawImage(img, null, point.x, point.y)
will draw your image at grid (2, 1).
convertDisplayToGrid() will come in handy when you want to figure out which grid a mouse click was made in.