Java shoot towards mouse - java

I have a top down 2d game where you walk around shooting bad guys. I want to be able to shoot towards the mouse, no mater what direction it is but I have absolutely no idea how to do this.
Here is my bullet class:
public class bullet {
public double x, y,dy,dx,mx,my;
public int dir;
public Rectangle r = new Rectangle((int) x, (int) y, 5, 5);
public bullet(double x, double y) {
this.x = x+10;
this.y = y+10;
this.mx = Comp.mx;
this.my = Comp.my;
r = new Rectangle((int) x, (int) y, 5, 5);
if (x < mx+play.camx) {
dx = 1;
}
if (x > mx+play.camx) {
dx = -1;
}
if (y < my+play.camy) {
dy = 1;
}
if (y > my+play.camy) {
dy = -1;
}
}
public void tick() {
x+=dx;
y+=dy;
r = new Rectangle((int) x - play.camx, (int) y - play.camy, 5, 5);
}
public void render(Graphics g) {
g.setColor(Color.black);
g.fillRect((int) x - play.camx, (int) y - play.camy, 5, 5);
}
}

Basicially, you need calculate the angel between the start point and end point, something like...
angle = -Math.toDegrees(Math.atan2(startX - endX, startY - endY)) + 180;
As an example:
Rotating a triangle around a point java
Java make a directed line and make it move
mouse motion listener only in one direction
Java: Move image towards mouse position
To track the mouse, use a MouseListener and MouseMotionListerner
Take a look at:
How to write a MouseListener
How to write a MouseMotionListener

Try using MouseInfo.getPointerInfo().getPosition() ( http://download.oracle.com/javase/1.5.0/docs/api/java/awt/PointerInfo.html#getLocation%28%29) It will return a point object.
Use a timer and on every timer event you'll move your bullet a specific length (which you would want it to move) towards the mouse position provided by aforementioned method.
You could do it like reducing difference of x- and y- Variables of mouse position and bullet position.

Related

How to make a moving ball with mouse motion listener

addMouseMotionListener(new MouseAdapter() {
public void mouseMoved(MouseEvent e) {
relativeX = e.getX();
relativeY = e.getY();
System.out.println(relativeX + "," + relativeY);
System.out.println(x + "," + y);
x = x + speedX;
y = y + speedY;
repaint();
if (x > relativeX) {
speedX = speed * -1;
} else if (x < relativeX) {
speedX = speed;
}
if (y > relativeY) {
speedY = speed * -1;
} else if (y < relativeY) {
speedY = speed;
}
}
});
Hi everyone, I created one mouse motion listener and the ball will follow the direction where my mouse moved to. However, the ball will stop moving once I stop moving my mouse. Even though, there is a quite a distance between my mouse cursor and the ball's location, the ball just refuse to move to the location of my mouse. I think it is because of my motion listener stopped working, since I am no longer moving the mouse. Does anyone have any ideas of how to force the ball to move to the exact position of my mouse.(first time asking on stack overflow hope everyone bare with my grammar)
private void doDrawing(Graphics g) {
radius = 20;
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(red);
g2d.fillOval((int) x, (int) y, radius, radius);
}
And this is the moving ball.

how do I calculate the points in a 5-point polygon [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I have a class Demo with a button and when the user clicks the button called polygon a polygon is drawn starting from the point where they hit, The code works fine in drawing but unfortunately it draws the polygon in the wrong place.
The PolygonShape Class
class PolygonShape {
int x, y;
private Polygon p;
public PolygonShape(int x, int y) {
// the x, y sent to this constructor
//are the cordinates of the point where the user clicked
this.x = x;
this.y = y;
}
public void draw(Graphics g) {
p = new Polygon();
for (int i = 0; i < 5; i++)
p.addPoint((int) (x + y * Math.cos(i * 2 * Math.PI / 5)),
(int) (x + y * Math.sin(i * 2 * Math.PI / 5)));
g.drawPolygon(p);
}
}
Assuming x and y are the center of the polygon, you're using them wrong (you need to add x to the x coordinate and y to the y coordinate) and you're missing another important variable: r for radius. Instead of multiplying by y, you should multiply by r in your formulae.
In other words:
class PolygonShape {
int x, y, r;
private Polygon p;
public PolygonShape(int x, int y, int r) {
this.x = x;
this.y = y;
this.r = r;
}
// Provide a default radius of 100 pixels if no radius is given.
public PolygonShape(int x, int y) {
this(x, y, 100);
}
public void draw(Graphics g) {
p = new Polygon();
for (int i = 0; i < 5; i++) {
double angle = i * 2 * Math.PI / 5;
p.addPoint((int) (x + r * Math.cos(angle)),
(int) (y + r * Math.sin(angle)));
}
g.drawPolygon(p);
}
}
Another option is to set the translation on the graphics before drawing:
final Graphics2D g2 = (Graphics2D)g.create();
g2.translate(x, y);
g2.drawPolygon(p);
You may need to do -x, -y, you'll have to try it.
I am working on a new graphics object (g2) so that the translate is not permanent.
Advantage is, can draw same shape in multiple places, just vary x and y.

Shoot to the mouse direction

The problem:
I've got this "Shot" class. In the code, the target variables are the mouseX and mouseY.
So when i click the mouse button, my player class will create a new shot object.
But the shooting is inaccurate.
How can i calculate the correct dx and dy?
If i add the dx and dy to the "bullet's" x and y, the bullet will move to the mouse's direction.This is what i want. The mouse position is stored in targetX and targetY, when the object is created. This is the point what the oval wants to reach.
Links:
The game (finished)
The code (from Shot.java):
public class Shot extends Entity {
private float targetX, targetY;
public Shot(World world, float x, float y, int width, int height, Color color, float targetX, float targetY) {
super(world, x, y, width, height, color);
this.targetX = targetX;
this.targetY = targetY;
}
#Override
public void render(GameContainer gc, Graphics g, Camera camera) {
g.setColor(color);
g.fillOval(x - camera.getX(), y - camera.getY(), width, height);
}
#Override
public void update(GameContainer gc, int delta) {
float dx = targetX - x;
float dy = targetY - y;
x += dx * delta * .001f;
y += dy * delta * .001f;
}
}
I tried this, but still not work:
#Override
public void update(GameContainer gc, int delta) {
float length = (float) Math.sqrt((targetX - x) * (targetX - x) + (targetY - y) * (targetY - y));
double dx = (targetX - x) / length * delta;
double dy = (targetY - y) / length * delta;
x += dx;
y += dy;
}
I did it! Here is my solution:
The problem was that, the target was the window's mouse position, and not the world's mouse position.
This is how i calculated the world's mouse positions:
float mouseWorldX = x + (mouseX - screen_width / 2); // x = player's x position
float mouseWorldY = y + (mouseY - screen_height / 2); // y = player's y position
This is code from my game at the moment is used to move a unit to the mouse when the right mouse button is pressed:
length = Math.sqrt((target_X - player_X)*(target_X - player_X) + (target_Y - player_Y)*(target_Y - player_Y)); //calculates the distance between the two points
speed_X = (target_X - player_X) /length * player_Speed;
speed_Y = (target_Y - player_Y) /length * player_Speed;
This will move an object to the target in a line at a set speed.
Edit: this is the actual code right from my game
if(input.isMouseButtonDown(Input.MOUSE_RIGHT_BUTTON))
{
length = (float) Math.sqrt((player_waypoint_X - player_X)*(player_waypoint_X - player_X) + (player_waypoint_Y - player_Y)*(player_waypoint_Y - player_Y));
velocityX = (float) (player_waypoint_X - player_X) /length * (float) PlayerStats.player.db_player_Speed;
velocityY = (float) (player_waypoint_Y - player_Y) /length * (float) PlayerStats.player.db_player_Speed;
player_waypoint_X = input.getMouseX() - 2;
player_waypoint_Y = input.getMouseY() - 2;
}
For testing purposes the velocity's are defined in the init method along with length. Every time the right mouse is pressed the waypoints's X and Y are changed to the mouse location.
I learned this from this question
velocity calculation algorithm.
in order to make the bullets not all change direction every shot, create an array list so that each bullet fired has its own x and y velocity

Java: Rectangle2D and negative dimensions

I have a script in which the user clicks once to begin a Rectangle2D. When he moves the mouse, the rectangle is updated with the new coordinates. He clicks again to end it. It's then stored in an ArrayList, and all these items are painted. This all works fine; it's not the problem.
However, if the second click is less than the first (i.e. getWidth() is negative), the rectangle doesn't show up (as stated in the documentation). My script to fix this doesn't work. It's supposed to detect negative values, and then 1) decrement the position value and 2) make the negatives positive. Instead, it just moves the entire rectangle up or left (depending on which axis is negative) and keeps it at 1px.
What's wrong?
private void resizeRectangle(final MouseEvent e) {
double x = rectangle.getX(), y = rectangle.getY(), w = e.getX() - x, h = e.getY() - y;
if (w < 0) {
x = e.getX();
w = -w;
}
if (h < 0) {
y = e.getY();
h = -h;
}
rectangle.setRect(x, y, w, h);
}
Thanks!
UPDATE: This is closer, but still doesn't quite work:
double x = rectangle.getX();
double y = rectangle.getY();
double w = e.getX() - x;
double h = e.getY() - y;
if (w < 0) {
x = e.getX();
w = originalClickPoint.getX() - e.getX();
}
if (h < 0) {
y = e.getY();
h = originalClickPoint.getY() - e.getY();
}
rectangle.setRect(x, y, w, h);
Once you assign the new rectangle you also shift the origin (i.e.where the mouse button was pressed down initially) to the current point. You'll have to save this point in a separate field (not in the rectangle itself).
x = Math.min(e.getX(), originalClickPoint.getX());
w = Math.abs(originalClickPoint.getX() - e.getX());
y = Math.min(e.getY(), originalClickPoint.getY());
h = Math.abs(originalClickPoint.getY() - e.getY());
Another way is to not correct the negative widths/heights of the rectangle but create a new (corrected) one when you draw it.
Take a look at the Custom Painting Approaches. The source code for the DrawOnComponent example shows how I did this.

Move Minute hand in Android clock

I am trying to write a simple proof of concept app that allows a user to rotate minute hand of a clock. I am having hard time coming up with the right logic for OnTouchEvent.
So far I have the following code:
public boolean onTouchEvent(MotionEvent e) {
float x = e.getX();
float y = e.getY();
switch (e.getAction()) {
case MotionEvent.ACTION_MOVE:
//find an approximate angle between them.
float dx = x-cx;
float dy = y-cy;
double a=Math.atan2(dy,dx);
this.degree = Math.toDegrees(a);
this.invalidate();
}
return true;
}
protected void onDraw(Canvas canvas) {
super .onDraw(canvas);
boolean changed = mChanged;
if (changed) {
mChanged = false;
}
int availableWidth = getRight() - getLeft();
int availableHeight = getBottom() - getTop();
int x = availableWidth / 2;
int y = availableHeight / 2;
cx = x;
cy = y;
final Drawable dial = mDial;
int w = dial.getIntrinsicWidth() + 100;
int h = dial.getIntrinsicHeight() + 100;
boolean scaled = false;
if (availableWidth < w || availableHeight < h) {
scaled = true;
float scale = Math.min((float) availableWidth / (float) w, (float) availableHeight / (float) h);
canvas.save();
canvas.scale(scale, scale, x, y);
}
if (changed)
{
dial.setBounds(x - (w / 2), y - (h / 2), x + (w / 2), y + (h / 2));
}
dial.draw(canvas);
canvas.save();
float hour = mHour / 12.0f * 360.0f;
canvas.rotate(hour, x, y);
final Drawable hourHand = mHourHand;
if (changed) {
w = hourHand.getIntrinsicWidth() + 30;
h = hourHand.getIntrinsicHeight() + 30;
hourHand.setBounds(x - (w / 2), y - (h / 2), x + (w / 2), y + (h / 2));
}
hourHand.draw(canvas);
canvas.restore();
canvas.save();
float minute = mMinutes / 60.0f * 360.0f;
if (bearing == 0)
{
canvas.rotate(minute, x, y);
}
else
{
canvas.rotate((float)bearing, x, y);
}
final Drawable minuteHand = mMinuteHand;
if (changed) {
w = minuteHand.getIntrinsicWidth() + 30;
h = minuteHand.getIntrinsicHeight() + 30;
minuteHand.setBounds(x - w, y - h, x + w, y + h);
}
minuteHand.draw(canvas);
canvas.restore();
if (scaled) {
canvas.restore();
}
}
Then based on that, my OnDraw method rotates the minute hand to the specified "this.degree"(just calls canvas.rotate). I am assuming my math is off here. I tried to follow the example here: Calculate angle for rotation in Pie Chart, but that's still not rotating the minute hand correctly. Any help would be appreciated.
The math looks correct. Your calculations should give you the angle of the touch event, where a touch that is to the exact right of the center point should give you 0 degrees.
A few things to watch out for
Make sure that you're rotating in the correct direction. It is hard to keep this straight, and thus easy to screw it up
Make sure that you're taking into account that a value of 0 means that the minute hand should be pointing to the right. For example, if you start out with a minute hand that is pointing upwards, you would have to add/subtract 90 degrees to the result of your calculation (depending on the direction of rotation - not sure which is correct offhand)
Make sure that (cx, cy) is the center point around which you want to calculate the angle
When rotating, you'll need to either use the 3 arg Canvas.rotate(float, float, float) method, or add an additional translation seperately, to make sure that you are rotating around the correct point. Without any translation, it will rotate around (0,0) (the top left corner of the view)
More on rotation:
Rotation always happens around the "current" (0,0) point. By "current", I mean the (0,0) point after the current matrix has been applied. When you first enter onDraw, the (0,0) point should be the upper-left corner of the view. Whenever you apply a translation/scaling/etc, you will potentially change where the (0,0) point is, relative to the view.
I think something like the following should work, in regards to setting the correct center of rotation:
//first we save the initial matrix, so we can easily get
//back to this state after we're done rotating
canvas.save();
//I *think* you need to negate the center offsets here,
//because you are conceptually moving the canvas, rather
//than moving the center directly
canvas.translate(-cx, -cy);
//<perform the rotation and draw the clock hand>
//...
//and now restore the matrix back to the initial state
canvas.restore();
Your calculation is good for measuring angle for minutes hand to
rotate in corresponding quadrants in analog clock... here with little
bit changes can make either minutes or hours hand to rotate at the
touch position....call the below method in onTouch() method for action move
public float getRotationAngle(float x, float y) {
float dx = x - cx;
float dy = y - cy;
double a = Math.atan2(dy, dx);
double degree = Math.toDegrees(a)+90;
if(angle<0){
degree=degree+360;
}
return (float) degree;
}
i have this approach with as vectors concept for calculating the angle but if little bit more than your code if u want i will give that logic....

Categories

Resources