derive the trajectory by a vector with libgdx? - java

Hello everyone ,
I am developing a game where two points, one is A, and the other is B , the point A is a cannon and the other is the point where there is a touch of the user.
how can I do to get the line , say infinite to proceed with the bullet starting from point A ?
My math skills are a bit scarce : /
Someone who can recommend a way to do it with libgdx / java ?

You need the vector position of B minus the vector position of A, which will give the vector pointing from A to B. Try having a read through this, a basic knowledge of vectors is indispensible if you are going to be making games

To represent state, you can use something like following.
public class Bullet extends Actor {
private Vector2 position;
private Vector2 velocity;
public Bullet(Vector2 position, Vector2 velocity) {
this.position = position;
this.velocity = velocity;
}
#Override
public void act(float delta) {
super.act(delta);
// Since newPosition = oldPosition + velocity * time elapsed
this.position.mulAdd(this.velocity, delta / 1000);
}
// Override draw method to handle rendering.
}
Now, you can initialize a new Bullet at each touch event (or whenever you wish)
Bullet createBullet(Vector2 canonPosition, Vector2 touchPosition) {
return new Bullet(canonPosition.cpy(), //Initial position of bullet.
touchPosition.sub(canonPosition).nor()); // Velocity
}
Now just add the Bullet to the stage and have fun.
Hope this helps.
Good luck.

Related

How to split a bullet to many bullets after shooting

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

How to make LibGDX Actions moveTo() animate from one point to another in a curved line?

I am working on a project in LibGDX, and I am using Scene2D actors for some of my sprites. In this regard, I have a sprite, which is spawning somewhere on the screen and needs to move to another position on the screen. To do this I am using the moveTo(xPos, yPos, duration, interpolation) method in the Actions, to make the move animation.
However, when I use this approach, the actor moves like I told it to, but it only moves in a straight line, from point A to B. I have tried several Interpolation options, like Circle interpolation and such, but it seems only to impact the speed of the animation line.
So now my question: How do I make my animation make a smooth curved line (See picture), from A to B?
I am currently using this code to make the Actions animation:
adultCustomerPointActor.addAction(Actions.sequence(
Actions.moveTo(300, 200, 2f, Interpolation.circle)
));
Thanks in advance for your help :)
It's a geometry problem. Using vectors, find the point halfway between the two points:
vec1.set(bx, by).sub(ax, ay).scl(0.5f).add(ax, ay);
Get another vector that is 90 or 270 to from the vector between the points:
vec2.set(bx, by).sub(ax, ay).rotate90().add(vec1);
This vec2 can be scaled to adjust how extreme curvature of the arc is. If you leave it alone, you'll have a quarter circle. You can also scale it negative to reverse the curvature.
Then add the second vector to the first to find the center point of your arc, which we can call point C.
vec1.set(bx, by).sub(vec2); // CB
vec3.set(ax, ay).sub(vec2); // CA
float angle = vec1.angle(vec3);
Now you need a vector that points from point C to point A. You will rotate this vector until it reaches point B. So you need the angle between CA and CB.
So here's a very simplistic class that implements this. It doesn't account yet for deciding if you want the arc to go up or down and if you want to scale how extreme it looks. You could add those as additional parameters with getters/setters. I haven't tested it, so it may need some debugging.
public class ArcToAction extends MoveToAction {
private float angle;
private final Vector2 vec1 = new Vector2(), vec2 = new Vector2(), vec3 = new Vector2();
#Override
protected void begin () {
super.begin();
float ax = target.getX(getAlignment()); // have to recalculate these because private in parent
float ay = target.getY(getAlignment());
vec1.set(getX(), getY()).sub(ax, ay);
vec2.set(vec1).rotate90();
vec1.scl(0.5f).add(ax, ay);
vec2.add(vec1);
vec1.set(bx, by).sub(vec2); // CB
vec3.set(ax, ay).sub(vec2); // CA
angle = vec1.angle(vec3);
}
protected void update (float percent) {
if (percent >= 1){
target.setPosition(getX(), getY(), getAlignment());
return;
}
vec1.set(vec3).rotate(percent * angle);
target.setPosition(vec1.x, vec1.y, getAlignment());
}
}
If you want to support automatic pooling, you can add a method like this:
static public ArcToAction arcTo (float x, float y, float duration, Interpolation interpolation) {
ArcToAction action = Actions.action(ArcToAction .class);
action.setPosition(x, y);
action.setDuration(duration);
action.setInterpolation(interpolation);
return action;
}

3D rotation on 3 axis; Java

I'm working on a 3d game engine (LWJGL3) and I'm really stuck on rotation object around parent.
Here is some outline:
Each GameObject can have other GameObject as child.
Each GameObject has a Transform class:
public Vector3f translation;
public Quaternion rotation;
public Vector3f scale;
public Transform() {
this.translation = new Vector3f(0.0f);
this.rotation = new Quaternion();
this.scale = new Vector3f(1.0f);
}
The Quaternion class extends the Quaternionf from JOML lib with some extra methods, but you can consider it as a pure JOML class. When I add a GameObject to another, it updates its local transforms so it inherits parents translation, rotation and scale:
public void updateToParent(GameObject parent) {
this.translation.add(parent.getWorldTransform().translation);
rotateAroundParent(parent.getWorldTransform());
this.scale.mul(parent.getWorldTransform().scale);
}
private void rotateAroundParent(Transform transform) {
this.translation.sub(transform.translation);
this.translation.rotateZ(-transform.rotation.z);
this.translation.rotateY(-transform.rotation.y);
this.translation.rotateX(-transform.rotation.x);
this.translation.add(transform.translation);
this.rotation.add(transform.rotation);
}
And this part "works" OK. Parent rotated 45 in x,y and z axis with children:
.
"Magic" starts when I try to apply rotation:
public void rotateAroundPoint(float dx, float dy, float dz, Transform transform) {
this.translation.sub(transform.translation);
this.translation.rotateZ(-(float)Math.toRadians(dz));
this.translation.rotateY(-(float)Math.toRadians(dy));
this.translation.rotateX(-(float)Math.toRadians(dx));
this.translation.add(transform.translation);
this.rotation.add(dx, dy, dz);
}
(Please Note! This is my latest try to implement it and I know it's not working)
When Parent object, and therefore the children, has no rotation applied (at least on different axis than rotation) this rotation works but only on one axis at a time. When ever I try to apply rotation on 2 or 3 axis or on rotated object it fails hard:
I've tried implementing Quaternion rotation, changing order of rotation etc. etc. Basically everything I could find here and on uncle Google, yet still couldn't solve this issue. I know it has something with Gimbal Lock, "rotating the rotation" axis and so on.
I was also thinking it might be the problem with ModelViewMatrix, but after sitting on this issue with over a week I have no idea what is good and what isn't :P
public static Matrix4f getModelViewMatrix(Model model) {
Quaternion rotation = model.getTransform().rotation;
MODEL_VIEW_MATRIX.identity()
.translate(model.getTransform().translation)
.rotateX(-rotation.x)
.rotateY(-rotation.y)
.rotateZ(-rotation.z)
.scale(model.getTransform().scale);
viewCurrent.set(VIEW_MATRIX);
return viewCurrent.mul(MODEL_VIEW_MATRIX);
}
What I want to achieve is: When a GameObject rotates - each of his child rotates together with him as a one part.
I would appreciate every help you can guys give me :)

What does Vector2.scl method do in LibGdx

I've been following a a tutorial recently and really new to game development. There is a method called scl of the Vector2 class in LibGdx. Here is the fragment of my code. My question is. What does it do. If you can do a detailed explanation. Please add some.
public void update(float dt){
if(position.y > 0)
velocity.add(0, GRAVITY);
velocity.scl(dt);
Gdx.app.log("scl dt 1", Float.toString(velocity.y));
position.add(0, velocity.y, 0);
if(position.y < 0)
position.y = 0;
velocity.scl(1/dt);
}
scl() is overloaded method of Vector2 class.
1. public Vector2 scl(float scalar)
Scales your vector by a scalar quantity and return.
2. public Vector2 scl(float x,float y)
Multiplies your vector by a scalar and return itself.
3. public Vector2 scl(Vector2 v)
Scales your vector by another vector and return itself.
In above your code you are scaling your vector by dt unit.
What is dt ?
dt is the time between the start of the previous and the start of the current call to render(). It just takes the current time and subtracts the previous time from it. The unit of this value is seconds.

Firing projectiles in a circle

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.)

Categories