Java-Gaming.org Hi !
Featured games (91)
games approved by the League of Dukes
Games in Showcase (808)
Games in Android Showcase (239)
games submitted by our members
Games in WIP (872)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  [SOLVED] Move one game object to another (moving) game object with libGDX  (Read 5324 times)
0 Members and 1 Guest are viewing this topic.
Offline phunni

Senior Newbie


Exp: 17 years



« Posted 2017-07-31 13:56:29 »

I need to do what I thought would be a fairly simple and common task - move one game object (some sort of throwing/shooting weapon) to another object (the target of the shot).  The target will be moving slowly and I want the attack to always hit.

I googled extensively for this, but only found a few things that might help and none of them were Java or libGDX specific.  The resources I did find were this one and this one. The last one references libGDX, but the answer doesn't seem to me to be libGDX specific.

As a result of trying to translate those solutions into libGDX/Java I now have the following in the class representing the object to be moved:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
Vector2 direction;

    public void init(TigerActor target) {
        this.target = target;
        direction = new Vector2();
        direction.x = target.getX() - position.x;
        direction.y = target.getY() - position.y;
        direction = direction.nor();
    }

@Override
    public void act() {
        position.x += direction.x;
        position.y += direction.y;
    }


The class TigerActor is a purely custom class inspired by a Scene2D actor but not a Scene2D Actor because I'm not using a Stage here.

The code above doesn't work - it simply causes the moving object to fly along very quickly on a horizontal line.

Any suggestions on how to improve on this code or how to do it properly from "scratch" would be very much appreciated.

Thanks in advance.
Offline dfour
« Reply #1 - Posted 2017-07-31 15:27:04 »

The code itself is fine, I have tested it in libgdx with this code:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
package com.mygdx.gtest;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.math.Vector2;

public class Test extends ApplicationAdapter{
   Bullet b;
   TigerActor t;
   
   @Override
   public void create() {
      b = new Bullet();
      t = new TigerActor();
      b.init(t);
   }
   

   @Override
   public void render() {
      b.act();
   }


   @Override
   public void dispose() {
      super.dispose();
   }
   
   private class Bullet {
      TigerActor target;
      Vector2 direction;
      Vector2 position = new Vector2(40,40);
     
      public void init(TigerActor target) {
         this.target = target;
         direction = new Vector2();
         direction.x = target.getX() - position.x;
         direction.y = target.getY() - position.y;
         direction = direction.nor();
         System.out.println(direction);
      }
     
      public void act(){
         position.x += direction.x;
         position.y += direction.y;
         System.out.println(position);
      }
   }
   
   private class TigerActor{
      int x = 10;
      int y = 10;
     
      public int getX(){
         return this.x;
      }
      public int getY(){
         return this.y;
      }
   }
}


Try printing out or debugging the code and inspect the target position and direction.
Offline phunni

Senior Newbie


Exp: 17 years



« Reply #2 - Posted 2017-07-31 17:09:08 »

Thanks for that - at least if it's working for you, I know I must be close...

I tried adding some debugging:

1  
2  
3  
4  
if (Gdx.app.getLogLevel() == Application.LOG_DEBUG) {
            Gdx.app.debug(TAG, "bullet: " + position.x + " : " + position.y);
            Gdx.app.debug(TAG, "target: " + target.getX() + ": "  + target.getY());
        }


and, sure enough, the bullet moves (infinitely) along x, but not at all along y. I can't see what I'm doing differently to you, but at least I have something to work with now!
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline phunni

Senior Newbie


Exp: 17 years



« Reply #3 - Posted 2017-07-31 17:46:02 »

OK, I think the way I'm calculating the direction (and possibly everything else as well...) is wrong.  Having logged the result of calculating the direction I can see it's 1.0 : 0.0 - which explains the horizontal movement...
Offline dime26

JGO Wizard


Medals: 90
Projects: 7
Exp: 12 years


Should traffic wardens be armed?


« Reply #4 - Posted 2017-07-31 23:38:22 »

Just dug out some very old code from a Bullet class, this took the start position of the bullet and the mouse cursor position to create a new vector:
 
double rad = Math.atan2(destX - startX, startY - destY);
dx = (float) Math.sin(rad) * speed;
dy = -(float) Math.cos(rad) * speed;

I think I looked at Catacomb Snatch source at the time: https://github.com/Maescool/Catacomb-Snatch/blob/3fe9b83d3fe2213ed4fbb252b2cebaa8403ec5c9/src/main/java/com/mojang/mojam/entity/Bullet.java

Was it long time ago!
Offline dfour
« Reply #5 - Posted 2017-08-01 11:44:42 »

Quote
Having logged the result of calculating the direction I can see it's 1.0 : 0.0

This looks like your float values are being converted to Integers. Are any of the values you use such as Target.getX() or Position Integers? I assumed they would all be Vector2.
Offline phunni

Senior Newbie


Exp: 17 years



« Reply #6 - Posted 2017-08-01 12:13:45 »

They are all either floats or Vector2
Offline dfour
« Reply #7 - Posted 2017-08-01 13:40:54 »

I can't see any reason in the code you provided that would make the bullet object go horizontally other than the target being in a position horizontal to the bullet. I suggest monitoring the values of all items in the init method for each step to see what the values are at each step.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
public void init(TigerActor target) {
        this.target = target;
        System.out.println("TargetValStart"+target.getX()+":"target.getY()); // maybe init is being called before target x and y has been set
        System.out.println("PositionValStart"+position.x+":"position.y);
        direction = new Vector2();
        direction.x = target.getX() - position.x;
        direction.y = target.getY() - position.y;
        System.out.println("b4Nor:"+direction);
        direction = direction.nor();
        System.out.println("AfterNor:"+direction);
    }


For reference I looked back into a project I had weapons in and found this snippet:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
public void baseShoot(Entity ent,float targetX,float targetY, Array<Bullet> activeBullets,boolean playSound){
      float shooterX = ent.getBody().getPosition().x; // get shooters x pos
      float shooterY = ent.getBody().getPosition().y;  // get shooters y pos
      float velx = targetX - shooterX; // get distance from shooter to target on x axis
      float vely = targetY - shooterY; // get distance from shooter to target on y axis
      float length = (float) Math.sqrt(velx * velx + vely * vely); // get distance to target direct
      // normalise
      if (length != 0) {
            velx = velx / length;
            vely = vely / length;
      }
      // get bullet from pool
      Bullet bullet = (Bullet) bp.obtain();
      // add to array for rendering
      activeBullets.add(bullet);
      // activate bullet (set start pos, velocity, and owener)
      bullet.activate(new Vector2(shooterX,shooterY), new Vector2(velx*speed,vely*speed), ent);

      if(playSound){
         this.shootSound();
      }
      // update weapon shot timer
      this.hasShot();
   }

Offline phunni

Senior Newbie


Exp: 17 years



« Reply #8 - Posted 2017-08-03 14:09:40 »

OK - I'm getting very close!

I can currently get the projectile (a shuriken) moving towards the target (a ninja) and it looks smooth even though the ninja is moving(slowly.)

The code that's working is as follows and is based on examples by @dfour in the previous post and also from the accepted answer here.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
...
private float remainingFlightTime = 10f;
...
float deltaTime = Gdx.graphics.getDeltaTime();
        remainingFlightTime -= deltaTime;

        //get distance to target x & y
        float velocityX = (target.getX() - getX()) / remainingFlightTime,
                velocityY = (target.getY() - getY()) / remainingFlightTime;
        float distance = (float) Math.sqrt(velocityX * velocityX + velocityY * velocityY);

        //normalise
        if (distance != 0) {
            velocityX /= distance;
            velocityY /= distance;
        }

        if (!arrived) {
            position.x += velocityX * deltaTime;
            position.y += velocityY * deltaTime;
            Rectangle ninjaRectangle = target.getBoundingRectangle();
            Rectangle shurikenRectangle = getBoundingRectangle();
            if (ninjaRectangle.overlaps(shurikenRectangle)) {
                arrived = true;
            }
        }


The code after the ellipsis is run every frame to account for the fact that the target is moving.

The only problem now is that my attempts to control the speed aren't working.  If I remove all reference to remainingFlightTime then the shuriken flies at a ridiculous speed, but, otherwise, it moves far too slowly - regardless of what I set remainingFlightTime to.  In fact, if I set it to 5 then it turns around and goes backwards part way through the flight and disappears off the screen.

So the main challenge is met - I just need to figure out how to have more control over the speed of the projectile...
Offline dfour
« Reply #9 - Posted 2017-08-03 14:43:39 »

Since velocityX and velocityY are normalised you can multiply them by the amount of units you want the object to travel per second.

So if you want the unit to travel at 5 units per second you can use

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
        float speedPerSecond = 5;
        //normalise
        if (distance != 0) {
            velocityX /= distance;
            velocityY /= distance;
        }

        if (!arrived) {
            position.x += (velocityX * speedPerSecond)  * deltaTime;
            position.y += (velocityY * speedPerSecond)  * deltaTime;
            Rectangle ninjaRectangle = target.getBoundingRectangle();
            Rectangle shurikenRectangle = getBoundingRectangle();
            if (ninjaRectangle.overlaps(shurikenRectangle)) {
                arrived = true;
            }
        }


This is dependant on your banana units, if you are using pixel perfect units then you will travel at 5 pixels per second, if you're using 16pixels per world unit then it 16 * 5 per second.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline phunni

Senior Newbie


Exp: 17 years



« Reply #10 - Posted 2017-08-04 14:26:57 »

Excellent - thanks, that's nailed it!
Pages: [1]
  ignore  |  Print  
 
 

 
Riven (848 views)
2019-09-04 15:33:17

hadezbladez (5799 views)
2018-11-16 13:46:03

hadezbladez (2605 views)
2018-11-16 13:41:33

hadezbladez (6215 views)
2018-11-16 13:35:35

hadezbladez (1501 views)
2018-11-16 13:32:03

EgonOlsen (4736 views)
2018-06-10 19:43:48

EgonOlsen (5794 views)
2018-06-10 19:43:44

EgonOlsen (3278 views)
2018-06-10 19:43:20

DesertCoockie (4176 views)
2018-05-13 18:23:11

nelsongames (5503 views)
2018-04-24 18:15:36
A NON-ideal modular configuration for Eclipse with JavaFX
by philfrei
2019-12-19 19:35:12

Java Gaming Resources
by philfrei
2019-05-14 16:15:13

Deployment and Packaging
by philfrei
2019-05-08 15:15:36

Deployment and Packaging
by philfrei
2019-05-08 15:13:34

Deployment and Packaging
by philfrei
2019-02-17 20:25:53

Deployment and Packaging
by mudlee
2018-08-22 18:09:50

Java Gaming Resources
by gouessej
2018-08-22 08:19:41

Deployment and Packaging
by gouessej
2018-08-22 08:04:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!