I have a ArrayList of X & Y coordinates which are located in a View. Now I want to check if the user touches the view, if some of the stored X & Y coordinates are in a certain radius (Like 20 Pixel) around the touched point. How would I be able to implement this?
Best regards
Use the Pythagorean formula.
if(Math.sqrt(Math.pow(stored_x - touched_x, 2) + Math.pow(stored_y - touched_y, 2)) <= 20){
//do thing
}
Related
I am working on a java game, in which I want to implement some combat. the way I want to implement the combat is through a single button, and depending on where the mouse cursor is, I want to attack in that direction. The problem is, i can't detect the direction relative to the player with just the x and y coordinates. if i did this without any math or anything else, i would get these kind of quadrants to measure directions from:
^^ These wouldn't work because that would get me: up-left, up-right, down-left, and down-right.
I want instead have up, down, left, and right, like this: where if the mouse is in one of these quadrants, it would attack in that direction. this would get me up, right, down, left (following the quadrants shown above)
Heres the information I have: Mouse x coordinate, Mouse Y coordinate, player X coordinate, player Y coordinate.
Im sure there is some math to convert these quadrants into these quadrants so that I can detect which direction the mouse is, relative to the player.
Here is an example of the code I would use to detect the mouse direction (this code is for the format, because I cant figure out the other one):
private Direction getMouseRelativeDirection() {
if(mouseX > x && mouseY < y)
return Direction.topRight;
if(mouseX > x && mouseY > y)
return Direction.bottomRight;
if(mouseX < x && mouseY < y)
return Direction.topLeft;
if(mouseX < x && mouseY > y)
return Direction.bottomLeft;
//to prevent errors if the mouse isn't in a quadrant, just return null
return null;
}
I hope I gave enough information for someone to figure out the direction math, but let me know if you need more info!
EDIT:
I fixed this with some searching on google and troubleshooting of my own.. turns out using lines formulas to get each line relative to the mouse is the way to go.
Maybe it would help you calculate the angle between the two points.
double angle = Math.toDegrees(Math.atan2(mouseY - y, mouseX - x));
if(angle < 0) { angle += 360; } // angle always >= 0
I am trying to get my player to shoot a spell and it travels to where ever the player clicked. I can easily accomplish this by doing the following.
if(position.x >= destination.x - 1 && position.x <= destination.x + 1)
reachedX = true;
if(position.y >= destination.y - 1 && position.y <= destination.y + 1)
reachedY = true;
However if the players origin is at, for example, 0,0 and I click at 10,300 then it travels right and up but when the spell reaches an x of 10 it travels directly upwards. I want the spell to travel at an angle that it will reach the x coordinate at the same time as the y coordinate. Here is an image showing what happens and what I want to happen.
In the first picture it looks like the spell goes 45° until it reaches the right x-coordinate. This sounds like the x and y speed are equals, no matter where the destination point is.
You shuld instead have a direction and depending on that a x and y speed.
For that you first need to get the point, the player is clicking.
Therefore you can implement InputProcessor and it's touchDown(int screenX, int screenY, int pointer, int button).
The screenX and screenY arguments are given in screen coordinates (pixels) and therefore need to be converted to your world-coordinates. This can be done using the camera or the viewport and it's unproject(Vector2 screenCoords). This method returns a Vector2 giving the world-coordinates.
Now you need to find out the direction Vector2 between you and the clicked point. The direction Vector is calculated like this:
new Vector2(otherPos.x - myPos.x, otherPos.y - myPos.y).nor();
This returns the normalized direction Vector between the two points.
Now you only need to move the spell by dir.x*spellSpeed*delta in x-direction and dir.y*spellSpeed*delta in y-direction and it should look like in your second picture.
I am trying to shoot an object(a spell) depending on the rotation of the players arm. The spell is supposed to come out of the hand and shoot towards where the mouse cicked(the arm rotates and points to where the mouse is). This is how the arm rotates in game.
public boolean mouseMoved(int screenX, int screenY) {
tmp.x = screenX;
tmp.y = screenY;
tmp.z = 0;
cam.unproject(tmp);
rot = MathUtils.radiansToDegrees * MathUtils.atan2((float)tmp.y - (float)player.getArmSprite().getY() - player.getArmSprite().getHeight(),
tmp.x -player.getArmSprite().getX() - player.getArmSprite().getWidth());
if (rot < 0) rot += 360;
//Last right or left means if hes looking left or right
if(player.lastRight)
player.setObjectRotation(rot + 80);
if(player.lastLeft)
player.setObjectRotation(-rot - 80);
And this is how the spell is supposed to shoot based off rotation
//destination is a vector of where on screen the mouse was clicked
if(position.y < destination.y){
position.y += vel.y * Gdx.graphics.getDeltaTime();
}
if(position.x < destination.x){
position.x += vel.x * Gdx.graphics.getDeltaTime();
}
However this is very wonky and never really reacts the way it supposed to with a few exceptions. It fires from the hand and then if the y axis is equal it completely evens out and goes till it reaches the x position, I want it to fire from the hand to the position clicks perfectly straight from point a to point b, this is clearly a rotation problem that I just can't seem to figure out how to tackle.
Here is an image of what is happening
Example image
The red indicates where I clicked, as you can see it reached the x pos first and now is traveling to the y when it should have reached the x and y pos of where I clicked first
Any help with this problem is extremely appreciated!
I'm pretty bad at radians and tangents but luckily we have vectors.
Since you have the rot ation in degrees of the arm. I advice to use Vectors to use for any Vector related math now.
//A vector pointing up
Vector2 direction = new Vector2(0, 1);
//Let's rotate that by the rotation of the arm
direction.rotate(rot);
Now direction is the direction the arm is pointing. If your rotation is calculated where up = 0. So you might need to rotate it 180, 90 or -90 degrees. Or in the case you did something silly any degrees.
Your spell should have a Vector too for it's position. Set that to the hand or wherever you want to start from. Now all you need to do is scale that direction since it's currently has a length of 1. If you want to move 5 units each frame you can do direction.scl(5) now it is of length 5. But technically speaking it's no direction anymore now everybody calls it velocity so let's do.
//when you need to fire
float speed = 5;
Vector2 velocity = direction.cpy().scl(speed);
//update
position.add(velocity);
draw(fireballImage, position.x, position.y);
I copied direction first, otherwise it would also be scaled. Then I just added the velocity to the position and draw using that Vector.
And to show Vectors are awesome you should see this awesome badlogic vs mouse program I created. https://github.com/madmenyo/FollowMouse there are just a view lines of my own code. It just takes a little bit of vector knowledge and it's very readable.
I have a system that generates chunks of 2d game map tiles. Chunks are 16x16 tiles, tiles are 25x25.
The chunks are given their own coordinates, like 0,0, 0,1, etc. The tiles determine their coordinates in the world based on which chunk they're in. I've verified that the chunks/tiles are all showing the proper x/y coordinates.
My problem is translating those into screen coordinates. In a previous question someone recommended using:
(worldX * tileWidth) % viewport_width
Each tile's x/y are run through this calculation and a screen x/y coordinate is returned.
This works for tiles that fit within the viewport, but it resets the screen x/y position calculation for anything off-screen.
In my map, I load chunks of tiles within a radius around the player so some of the inner tiles will be off-screen (until they move around, tile positions on the screen are moved).
I tried a test with a tile that would be off screen:
Tile's x coord: 41
41 * 25 = 1025
Game window: 1024
1025 % 1024 = 1
This means that tile x (which, if the screen 0,0 is at map 0,0, should be at x:1025, just off the right-hand side of the screen) is actually at x:1, appearing in the top-left.
I can't think of how to properly handle this - it seems to me like I need take the tileX * tileWidth to determine it's "initial screen position" and then somehow use an offset to determine how to make it appear on screen. But what offset?
Update: I already store an x/y offset value when the player moves, so I know how to move the map. I can use these values as the current offset, and if someone saves the game I can simply store those and re-use them. There's no equation necessary, I would just have to store the cumulative offsets.
The modulo (worldX*tileWidth % screenWidth) is what's causing it to reset. Modulo (%) gives you the remainder of an integer division operation; so, if worldX * tileWidth is greater than screenWidth, it will give you the remainder of (worldX * tileWidth) / screenWidth; if worldX * tileWidth is screenWidth+1, remainder is 1: it starts over at the beginning of the row.
If you eliminate the modulo, it will continue to draw tiles past the edge of the screen. If your drawing buffer is the same size as the screen, you'll need to add a check for tiles at the edge of the screen to make sure you only draw the tile portion that will be visible.
If you're trying to keep the player centered on the screen, you need to offset each tile by the player's offset from tile 0,0 in pixels, minus half the screen width:
offsetX = (playerWorldX * tileWidth) - (screenWidth / 2);
screenX = (worldX * tileWidth) - offsetX;
x = ((worldX*tileWidth) > screenWidth) ? worldX*tileWidth : (worldX*tileWidth)%screenWidth;
That should work. Though I recommend implementing something like an interface and letting each tile decide where they want to be rendered. Something like this
interface Renderable {
void Render(Graphics2D g)
..
}
class Tile implements Renderable{
int x,y
//other stuff
Render(Graphics2D g){
if (!inScreen()){
return;
}
//...
//render
}
boolean inScreen(){
//if the map moves with the player you need to define the boundaries of your current screenblock in terms of the global map coordinates
//What you can do is store this globally in a singleton somewhere or pass it to the constructor of each tile.
//currentBlock.x is then player.x - screenWidth/2
//currentBlock.width is then player.x + screenWidth/2;
//similar for y
if(this.x < currentBlock.x || this.x > currentBlock.Width)
return false;
if (this.y < currentBlock.y || this.y > currentBlock.height)
return false;
return true;
//If the map are in blocks (think zelda on snes where you go from one screenblock to another) you still need to define the boundaries
//currentBlock.x = (player.x / screenWidth) (integer division) *screenWidth;
//currentBlock.width = (player.x /screenWidth) (...) * screenWidth + screenWidth;
//same for y
//Then perform above tests
}
I'm working on an android project, I want to move an object in a projectile path, but have no idea how to do that..
I got the initial X and initial Y, i.e. left bottom corner of the phone in landscape mode. Also I fetch the X and Y were the user touch the phone, so I can calculate the angle too by tan-1(y/x), but how to calculate the curve path i.e X and Y for the object.
Any help will be appreciated.
Thanks
You have initial point p1 (X, Y) where you throw your projectile. And you have a point where user touched the screen, say p2. So, find the direction vector, like dir = p2 - p1 and normalize it. Then do following:
You have initial velocity, v = speed * dir, where speed is scalar factor
Then, on every game tick append to your current position vector v = v + (0, -10); v *= dt, where (0, -10) is gravity factor and dt - time between game frames.
You can eliminate having to increment by time intervals by using the parametric form of the projectile equations.
All you'd need to do is determine how far across (left to right) the screen you want to travel. I'll call that the X direction. Then, for each position in the X direction (could be a pixel, could be some number of pixels), you calculate the corresponding position in the Y (down to up) direction.
You'll need to set a value for the downward acceleration due to gravity. Whatever value you choose, I'll just call it g. You'll also need to set a value for how fast the projectile begins it's motion. Whatever value you choose, I'll just call it V.
The parametric equation is then:
Y = X * tan(theta) - (g * X^2) / (2 * V^2 * (cosine(theta))^2)
So, once you have the user touch point, you can calculate the angle, theta, determine V, g, and the maximum value for X, then just iterate from 0 to max X and you'll get a point (X,Y) for each iteration.