How to create the illusion of particles been left behind in libgdx - java

I am making an endless runner game were the camera is static and the environment is moving from top to bottom, the player is a rocket facing upwards that can only move left or right. When the player collides with an obstacle it spawns particles to show an explosion. What i want is to show the illusion of the particles been left behind as the camera is moving up. But since my camera is static i have to move them backwards myself to give an illusion of the camera going up how do i go about doing that?
Here is my code:
public Particle(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
rotDirection = MathUtils.random.nextBoolean() ? -1 : 1;
dx = MathUtils.cos(MathUtils.random(MathUtils.PI2));
dy = MathUtils.sin(MathUtils.random(MathUtils.PI2));
xSpeed = MathUtils.random(MIN_SPEED, MAX_SPEED);
ySpeed = MathUtils.random(MIN_SPEED, MAX_SPEED);
rotation = MathUtils.random(360);
rotationSpeed = MathUtils.random(MIN_ROT_SPEED, MAX_ROT_SPEED);
}
public void update(float delta){
x += dx * xSpeed * delta;
y += dy * ySpeed * delta;
rotation += rotDirection * rotationSpeed * delta;
}

You are using randoms to set dy and ySpeed.
Then you change the y value using these 2 random values and deltaTime.
If you want to move the particle in a specific direction you cannot use random values to move it.
Try having a float yMoveSpeed and add it to y.
public void update(float delta){
x += dx * xSpeed * delta;
y += dy * ySpeed * delta;
rotation += rotDirection * rotationSpeed * delta;
y += yMoveSpeed * delta;
}
That should at least make it move in a direction.
Another solution could be to use the particle system and editor bundled with libgdx. (in gdx-tools)
Game From Scratch tutorial

Related

Libgdx Player rotation messing up

I'm trying to program a player that rotates towards the mouse and travels towards the mouse at a certain speed. I am using an orthographic camera, however as soon as I set the camera's position to equal the players position, the player rotation stops working and goes all over the place. I believe it might have something to do with the mouse coordinates using the screen and not the world x and y. I have tried unprojecting Gdx.inout.getY/X to no prevail. Any help is much appreciated.
I am using this code to follow player:
cam.position.x = player.getX();
cam.position.y = player.getY();
cam.update();
And this code for rotation:
float mouseX = Gdx.input.getX();
float mouseY = (480 - Gdx.input.getY());
float originX = getWidth() / 2 + position.x;
float originY = getHeight() / 2 + position.y;
double angle = Math.atan2(mouseY - originY, mouseX - originX) * (180/Math.PI) + 90;
if (angle < 0)
angle += 360;
rotation = (float) angle;
direction.x = mouseX - position.x;
direction.y = mouseY - position.y;
double hyp = Math.sqrt(direction.x * direction.x + direction.y * direction.y);
direction.x /= hyp;
direction.y /= hyp;
position.x += direction.x * 2;
position.y += direction.y * 2;
Have you tried projecting (or unprojecting) the points?
ViewPort viewPort = new ... // which ever ViewPort you're using
Vector2 worldPoint = new Vector2(x, y);
Vector2 projected = viewPort.project(worldPoint);
or
Vector2 screenPoint = new Vector2(x, y);
Vector2 unprojected = viewPort.unproject(screenPoint);

Accounting for gravity when shooting an arrow at a coordinate

So I am making a 2D android game where you aim with your cursor and your character shoots where your cursor clicks.
When the arrow is created this method is called
private final float GRAVITY = 100, SPEED = 50f;
public Arrow(float dx, float dy, float x1, float y1, float x2, float y2,)
{
destination = new Vector2(dx, dy);//mouse clicked here
//x1 and y1 are the starting coordinates
bounds = new Polyline(new float[]{x1, y1, x2, y2});
double r = Math.atan2(dy-y1, dx-x1);//calculate angle
velocity = new Vector2();
velocity.x = (float)(Math.cos(r) * SPEED);
velocity.y = (float)(Math.sin(r) * SPEED) + ACCOUNT FOR GRAVITY;
acceleration= new Vector2(0, GRAVITY);
}
and this is the update method, pretty straight forward
public void update(float delta)
{
velocity.add(acceleration.cpy().scl(delta));
position.add(velocity.cpy().scl(delta));
}
How do I account for gravity? If gravity is set to 0 the arrow travels in a straight line to the coordinates the mouse clicked, but with gravity it always falls short. Im not sure how to account for gravity. I think delta might be screwing me up.
This is more of a math / physics question than a programming question. So first of all, you know the horizontal velocity of the arrow is constant (unless you have air resistance, in which case it is a lot more complicated). You can calculate the time it will take for the arrow to reach it's destination's x coordinate.
let (dx, dy) = displacement from launcher to destination
let c = cos(angle), s = sin(angle), vx = c * speed, vy = s * speed
vx * t = dx
t = dx / vx
With this value, you can compute the vertical displacement
dy = 0.5*acc * t^2 + V0 * t
dy = 0.5*acc * (dx/vx)^2 + vy*t
dy = 0.5*acc * (dx/(c*speed))^2 + (s*speed)*(dx/(c*speed))
since sin = sqrt(1 - cosine^2),
dy = 0.5*acc * (dx/(c*speed))^2 + (sqrt(1-c^2)*speed)*(dx/c*speed))
Now you have an equation with only known values (acc, dy, dx, speed) and c. If you solve for c, you know the cosine and you can find the sin.

Rendering 3-d lines in Java?

Ok, I have a little problem: I'm trying to code an engine capable of rendering 3d lines onto a 2d plane, but I'm having some trouble with it.
I have a point3d class, which takes x y and z coords, a line3d class, which takes two point3d endpoints, and I have a world object containing an arraylist of line3d's. I also have point2d and line2d, which are just like their 3d counterparts, except that they lack a z coordinate.
Here's the render method:
public void render(){
for(Line3d line : world.lines){ //for every 3d line in the world
panel.l3d(line, world.main); //render that line
}
panel.repaint(); //repaint the graphic
}
Which calls upon the l3d method:
public void l3d(Line3d line, Camera view){
Point2d start = p3Top2(line.start, view), end = p3Top2(line.end, view); //convert 3d points to 2d points
if(start==null || end==null)return; //if either is null, return
lineAbs(new Line2d(start, end)); //draw the line
}
Which calls upon p3Top2:
public Point2d p3Top2(Point3d point, Camera view){ //convert 3d point to 2d point on screen
int relativeZed = point.z - view.z; //difference in z values between camera and point
if(relativeZed <= 0)return null; //if it's behind the camera, return
int sx, sy, ex, ey, tx, ty; //begin declaring rectangle formed from extending camera angle to the z coord of the point(angle of 1 = 90 degrees)
sx = (int) (view.x - (width / 2) - relativeZed * (width * view.angle)); //starting x of rectangle
ex = (int) (view.x + (width / 2) + relativeZed * (width * view.angle)); //ending x
sy = (int) (view.y - (height / 2) - relativeZed * (height * view.angle)); //starting y
ey = (int) (view.y + (height / 2) + relativeZed * (height * view.angle)); //ending y
tx = point.x - sx; //difference between point's x and start of rectangle
ty = point.y - sy; //same for y
float px = (float)tx / (float)(ex - sx), py = (float)ty / (float)(ey - sy); //px and py are the ratios of the point's x/y coords compared to the x/y of the rectangle their in
return new Point2d((int)(px * width), (int)(py * height)); //multiply it by the width and height to get positions on screen
}
And also on lineAbs:
public void lineAbs(Line2d line){
Point2d start = line.start;
Point2d end = line.end;
if(start.x>end.x){
start = line.end;
end = line.start;
}
int y = start.y; //starting y point
int white = 0xffffff;
for(int x = start.x; x<end.x; x++){ //for each x in the line
if(x < 0 || y < 0 || x > canvas.getWidth() || y > canvas.getHeight())continue; //if the point is outside of the screen, continue
y += line.getSlope().slope; //increment y by the slope
canvas.setRGB(x, y, white); //draw the point to the canvas
}
}
'canvas' is a BufferedImage being drawn to the screen. With an arbitrary camera and angle of 1, as well as a few arbitrary lines thrown in, I do see each line, but they don't appear to be rendered properly. For example, when I have three point3d's as vertices, and three lines, each with a different combination of two of the points, the lines don't appear to meet at all, although each one is visible.
I suspect the issue is in my p3Top2, but I'm not sure where, can you tell?

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

How to make my Image move in a random direction?

I have an image that rotating in a counter clockwise direction. Now, I want it to move in a random direction during or whenever it touch the wall. The problem is I can't do it, please help me about this matter.
This is my code :
private double x;
private double y;
private double speed;
public void move(long dt)
{
double dt_s = dt / 1e9;
double dx = speed * dt_s;
double dy = speed * dt_s;
final double right_border = 100;
final double up_border = 100;
final double down_border = 0.0;
final double left_border = 0.0;
x += dx;
if (x >= right_border)
{
x = right_border;
if (y >= down_border)
{
y += dy;
}
}
if (y > up_border)
{
y = up_border;
if (x >= left_border)
{
speed *= -1;
}
}
if (x <= left_border)
{
x = left_border;
if (y <= up_border)
{
y += dy;
}
}
if (y < down_border)
{
y = down_border;
if (x <= right_border)
{
speed *= -1;
}
}
}
First you must solve the problem of your class being directionless - you have speed, but your direction is fixed at 45 degree north east (increment x and y the same).
Add direction to your class as follows:
...
private double speed;
private double angle; // in radians - makes math easier
public void move(long dt) {
...
double dx = speed * dt_s * Math.sin(angle);
double dy = speed * dt_s * Math.cos(angle);
...
Now to head in a random direction:
myObject.setAngle(Math.PI * 2 * Math.random()); // Math.PI * 2 = 360 degrees
If hitting a wall, you will have to limit your angle to an angle that's away from the wall you are hitting. I'll leave that to you, but it will take the form of:
myObject.setAngle(minAngle + ((maxAngle - minAngle) * Math.random()));
This is one possible solution.
Generate a random point (x,y) on one of the boundaries (other than the boundary that the image just hit), and make the image move towards that point. All you have to do is, find the slope between the point P1(x1,y1) it just hit, and the random point just generated P2(x2,y2). Using the slope you can find the equation of the line, it has to travel in. You're done!!

Categories

Resources