I have a program where i create balls that bounce around. When two balls collide, both should split into two smaller balls, start moving in different directions.
This is how I handle collision
public boolean intersects (Ball b) {
double distance = Math.sqrt(Math.pow((this.x - b.x), 2) + Math.pow((this.y - b.y), 2));
if (this.size / 2 + b.size / 2 >= distance && !(this.equals(b))) {
return true;
} else return false;
I am looking for an idea, that will help to decide where to place smaller balls, so that they don't immediately collide again. I have tried different maneuvers but they all end up too close to each other so they all start splitting a bouncing and it become a chaos.
Here is the class Ball
public Ball(double x, double y, double size, double dx, double dy) {
this.x = x;
this.y = y;
this.size = size;
this.dx = dx;
this.dy = dy;
To move the balls I do the following
b.x = b.x + b.dx;
b.y = b.y + b.dy;
For the moment when the balls collide, i have two Ball Objects. I know the coordinates of their centers: x, y , speed dx with which they move along the x-axis and speed dy along the y-axis
I leave out the code that handles the view, cause I basically need a solution, how to change dx, dy, x and y for 4 balls, so that all of them move away from each other and do not immediately collide.
I don't really need code-solution , but rather a general idea.
I think you might have two problems. The first is that your four "new" balls are all starting at or near the point of collision, and your collision detector might immediately perceive them as colliding. To solve this, you could mark the "new" balls as unable to collide with each other for a pulse or two of your collision detector. I'd need to see the code to give a better solution.
Secondly, you'll probably want to randomize the result vector of the four "new" balls. Just set dx and dy randomly for each and that should be good enough.
Related
im a programming beginner and i have do to for a game we are coding a shotgun shot but have a problem and dont know how to do it
i want to add a bullet in the game that when you shoot it, it spits itself into a few and small bullets in small different directions, so basically a shotgun shot.
i already have a normal bullet with his position,vector and velocity , and you can shoot it already. but my problem is or the thing i dont understand is how i can split that one bullet after i shoot it in many bullets and how every of it gets it own position and moving vector
Bullet class{
Vector2 moveVector;
float speed =15;
public void setMoveVector(float x, float y) {
moveVector = new Vector2(x,y);}
// in that area here its for the bullet how it moving/acting including if the path is free or blocked by walls or something
if(map.pathFree(getX(), getY(), getX()+ moveVector.x * speed, getY() + moveVector.y * speed, this)) {
setPosition(getX() + moveVector.x * speed, getY() + moveVector.y * speed);
//somewhere here sould come the code splitting the bullet
//removing the bullet after a distance
DistanceIndex += speed;
if(DistanceIndex >= 1000) {
remove();
}
}
else
HitWall();
if(outsideMap()) this.remove();
}
....
}
Obj Class
//class/object/gamefigure using/creating the bullet
.....
public void shootingMethod(){
......
double direction_x = Math.cos(Math.toRadians(rotation));
double direction_y = Math.sin(Math.toRadians(rotation));
Bullet bullet = new Bullet();
....
bullet.setMoveVector((float)direction_x, (float)directoin_y);
}
Picture of my problem i mean
Just make a bunch of smaller bullets start off at the same position and travel in slightly different directions. You could rotate the velocity vectors slightly for each bullet to achieve this. If they aren't already, you can make the bullets sensors so overlapping is not a problem
I'm trying to do some basic trigonometry with Java and LibGDX on android.
I've spent a long time googling "How to find an angle in right triangles".
I still don't really understand :(
I want to give an Actor subclass a random direction to follow. So what is the angle - and what should I set xSpeed and ySpeed to, in order to move at the correct angle.
I started writing an app to help me see how it works.
There are two objects - An origin point and a touch point. User presses screen, touchPoint moves to where user touched. Methods fire to figure out the appropriate values. I know the XDistance and YDistance between the two points. That means I know the Opposite length and the Adjacent length. So all I need to do is tan-1 of (opposite / adjacent), am I right?
I just don't understand what to do with the numbers my program spits out.
Some code:
In create event of main class:
stage.addListener(new ClickListener() {
#Override
public void touchDragged(InputEvent event, float x, float y, int pointer) {
touchPoint.setX(x);
touchPoint.setY(y);
touchPoint.checkDistance(); // saves x and y distances from origin in private fields
atan2D = getAtan2(touchPoint.getYDistance(), touchPoint.getXDistance());
tanhD = getTanh(touchPoint.getYDistance(), touchPoint.getXDistance());
xDistanceLbl.setText("X Distance: " + touchPoint.getXDistance());
yDistanceLbl.setText("Y Distance: " + touchPoint.getYDistance());
atan2Lbl.setText("Atan2: " + atan2D);
tanhLbl.setText("Tanh: " + tanhD);
angleLbl.setText("Angle: No idea");
}
})
...
private double getAtan2(float adjacent, float opposite) {
return Math.atan2(adjacent, opposite);
}
private double getTanh(float adjacent, float opposite) {
return Math.tanh((adjacent / opposite));
}
These two functions give me numbers between (atan2: -pi to pi) and (tanh: -1.0 to 1.0)
How do I turn these values into angles from which I can then work backwards and get the opposite and adjacent again?
Doing this should allow me to create and object with a random direction, which I can use in 2D games.
atan2 gives you direction in radians. Direction from origin (0,0) to touchPoint. If you need direction from some object to touchPoint, then subtract object coordinates. Perhaps you also want to see direction in degrees (this is only for human eyes)
dx = x - o.x
dy = y - o.y
dir = atan2(dy, dx)
dir_in_degrees = 180 * dir / Pi
I you have direction and want to retrieve coordinate differences, you need to store distance
distance = sqrt(dx*dx + dy*dy)
later
dx = distance * cos(dir)
dy = distance * sin(dir)
But note that often storing dx and dy is better, because some calculations might be performed without trigonometric functions
Just noticed - using tanh is completely wrong, this is hyperbolic tangent function, it has no relation to geometry.
You can use arctan, but it gives angle in half-range only (compared with atan2)
I started learning LibGdx and Java recently, and it has been going well so far.
I'm facing an issue with collision detection.
I have two sprites which can be represented as two shapes, a polygon and a circle, which will collide/intersect at any given moment. Once these two shapes collide, something will get triggered.
So far, this is what I have done. It kinda works but it is not accurate. This is called inside the Render() function:
public boolean CollectPowerUp(PowerUps powerUp) {
if (powerUp.position.dst(position) < Constants.PLAYER_HEIGHT -3) {
Gdx.app.log("Collected PowerUp", "TRUE");
EnablePowerUp(powerUp);
return true;
}
return false;
I have searched many websites, and most of the solutions include other softwares like 2DCube or PhysicsEditor. Is it possible to perform this intersection solely by using LibGdx and Java? If so, what should I look into?
Thanks
Intersector class having many static method that can be used for collision detection.
If your polygon is rectangle you can use :
Intersector.overlaps(Circle c, Rectangle r)
else
Polygon polygon=new Polygon();
polygon.setVertices(new float[]{0,0,.......});
Circle circle=new Circle(x, y, radius);
float points[]=polygon.getTransformedVertices();
for (int i=0;i<points.length;i+=2){
if(circle.contains(points[i],points[i+1])){
System.out.println("Collide");
}
}
EDIT
Above code only detect collision if polygon vertices are inside circle, what if
circle is completely inside polygon
some part of circle is inside polygon but vertices are outside the circle
Create a polygon for circle that act as circle in view and polygon in model
float radius=100;
FloatArray floatArray=new FloatArray();
int accuracy=24; // can be use 1 for complete circle
for (int angle=0;angle<360;angle += accuracy){
floatArray.add(radius * MathUtils.cosDeg(angle));
floatArray.add(radius * MathUtils.sinDeg(angle));
}
Polygon circle=new Polygon(floatArray.toArray()); // This is polygon whose vertices are on circumference of circle
float[] circularPoint=circle.getTransformedVertices();
for (int i=0;i<circularPoint.length;i+=2){
if(polygon.contains(circularPoint[i],circularPoint[i+1])){
System.out.println("Collide With circumference");
break;
}
}
There's a nice article on collision detection on www.gamedevelopment.blog which shows how to detect collisions with most shapes. This is the Libgdx circle, polygon collision detection method shown in the article.
public boolean contains (Polygon poly, Circle circ) {
final float[] vertices = poly.getTransformedVertices(); // get all points for this polygon (x and y)
final int numFloats = vertices.length; // get the amount of points(x and y)
// loop through each point's x and y values
for (int i = 0; i < numFloats; i += 2) {
// get the first and second point(x and y of first vertice)
Vector2 start = new Vector2(vertices[i],vertices[i + 1]);
// get 3rd and 4th point (x and y of second vertice) (uses modulo so last point can use first point as end)
Vector2 end = new Vector2(vertices[(i + 2) % numFloats], vertices[(i + 3) % numFloats]);
// get the center of the circle
Vector2 center = new Vector2(circ.x, circ.y);
// get the square radius
float squareRadius = circ.radius * circ.radius;
// use square radius to check if the given line segment intersects the given circle.
return Intersector.intersectSegmentCircle (start, end, center, squareRadius);
}
}
There are many useful methods in the Intersector class which can be used for collision detection.
So I can't seem to find an answer to this, but I am trying to fire bullets into a circle. I have a simple class for a circular path that I attach to a bullet and it reads from that class a position when given a time value. The bullet simply increments this time value, constantly updating its position to the next. This can be improved but until I get the logic down this is what I have. I know this method works because I tried it with a linear path. The problem is applying it to a circular path.
I want the bullet to circle around a point (say Point 'Center') with a given radius and speed. I want all bullets to travel at the same speed no matter the radius of the circle so a larger circle will take longer to complete than a shorter one. Currently what is happening is I have the CircularPath object giving saying x = r * cos(t) and y = r * sin (t) where t is in radians, but this is making a circle that increases in speed as the radius increases and the radius and center of this circle is completely off. The bullets are starting in the correct position, except the radius and speeds are off. I hope I am describing this adequately. I will post the code for anyone to inspect.
package io.shparki.tetris.go;
import io.shparki.tetris.util.Point2D;
import java.awt.Color;
import java.awt.Graphics2D;
public class CircularPath extends Path{
private double radius;
// Where Start is the center and end is the location of mouse
// Radius will be distance between the two
public CircularPath(Point2D start, Point2D end) {
super(start, end);
radius = normalToEnd.getLength();
color = Color.YELLOW;
}
public Point2D getPointAtTime(double time){
double px = start.getX() + radius * Math.cos(Math.toRadians(time));
double py = start.getY() - radius * Math.sin(Math.toRadians(time));
return new Point2D(px, py);
}
public double getFinalTime() { return 0; }
public CircularPath getClone() { return new CircularPath(start.getClone(), end.getClone()); }
public void update(){
super.update();
radius = normalToEnd.getLength();
}
public void render(Graphics2D g2d){
super.render(g2d);
g2d.drawLine((int)start.getX(), (int)start.getY(), (int)end.getX(), (int)end.getY());
//g2d.drawOval((int)(start.getX() - radius), (int)(start.getY() - radius), (int)radius * 2, (int)radius * 2);
}
}
x = r * cos(t/r)
y = r * sin(t/r)
The other solution is to model 2d momentum and impose a "gravitational force" toward the center point (or ellipsoidal focus, more generally) that you want the moving object to orbit around.
(The classic Space Wars game was implemented on a machine too slow to handle the trig computations in realtime, so they precomputed a 2d array each for the x and y components of the gravity field; they could then just do a table lookup based on the ship's last position and use that to update its momentum, which was then used to update its position. Slower machines forced more clever solutions.)
I'm making pretty simple game. You have a sprite onscreen with a gun, and he shoots a bullet in the direction the mouse is pointing. The method I'm using to do this is to find the X to Y ratio based on 2 points (the center of the sprite, and the mouse position). The X to Y ratio is essentially "for every time the X changes by 1, the Y changes by __".
This is my method so far:
public static Vector2f getSimplifiedSlope(Vector2f v1, Vector2f v2) {
float x = v2.x - v1.x;
float y = v2.y - v1.y;
// find the reciprocal of X
float invert = 1.0f / x;
x *= invert;
y *= invert;
return new Vector2f(x, y);
}
This Vector2f is then passed to the bullet, which moves that amount each frame.
But it isn't working. When my mouse is directly above or below the sprite, the bullets move very fast. When the mouse is to the right of the sprite, they move very slow. And if the mouse is on the left side, the bullets shoot out the right side all the same.
When I remove the invert variable from the mix, it seems to work fine. So here are my 2 questions:
Am I way off-track, and there's a simpler, cleaner, more widely used, etc. way to do this?
If I'm on the right track, how do I "normalize" the vector so that it stays the same regardless of how far away the mouse is from the sprite?
Thanks in advance.
Use vectors to your advantage. I don't know if Java's Vector2f class has this method, but here's how I'd do it:
return (v2 - v1).normalize(); // `v2` is obj pos and `v1` is the mouse pos
To normalize a vector, just divide it (i.e. each component) by the magnitude of the entire vector:
Vector2f result = new Vector2f(v2.x - v1.x, v2.y - v1.y);
float length = sqrt(result.x^2 + result.y^2);
return new Vector2f(result.x / length, result.y / length);
The result is unit vector (its magnitude is 1). So to adjust the speed, just scale the vector.
Yes for both questions:
to find what you call ratio you can use the arctan function which will provide the angle of of the vector which goes from first object to second object
to normalize it, since now you are starting from an angle you don't need to do anything: you can directly use polar coordinates
Code is rather simple:
float magnitude = 3.0; // your max speed
float angle = Math.atan2(y,x);
Vector2D vector = new Vector(magnitude*sin(angle), magnitude*cos(angle));