Java-Gaming.org Hi !
Featured games (91)
games approved by the League of Dukes
Games in Showcase (804)
Games in Android Showcase (239)
games submitted by our members
Games in WIP (868)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: 1 [2]
  ignore  |  Print  
  Rotating a Box2D light/body based on mouse input?  (Read 27091 times)
0 Members and 1 Guest are viewing this topic.
Offline Elsealabs
« Reply #30 - Posted 2014-12-29 06:24:52 »

The method you just posted actually makes it spin no matter what. It does not stop once it reaches the drag position, which is what I am trying to get mine to do, and which is does, (most of the time, not always).

I don't know what is causing this in either, but:

Gif of your code: (see it moving without touching it)
Click to Play

Gif of my code:
Click to Play

Offline Riven
Administrator

« JGO Overlord »


Medals: 1371
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #31 - Posted 2014-12-29 10:59:27 »

I can't take it anymore Pointing

Rot2D.java
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  
public class Rot2D {
   public static Rot2D fromDegrees(double angle) {
      return fromRadians(Math.toRadians(angle));
   }

   public static Rot2D fromRadians(double angle) {
      return new Rot2D(Math.cos(angle), Math.sin(angle));
   }

   public static Rot2D fromVector(double dx, double dy) {
      float length = (float) Math.sqrt(dx * dx + dy * dy);
      return new Rot2D(dx / length, dy / length);
   }



   public double cos, sin;

   private Rot2D(double cos, double sin) {
      this.cos = cos;
      this.sin = sin;
   }

   public Rot2D load(Rot2D that) {
      this.cos = that.cos;
      this.sin = that.sin;

      return this;
   }

   public Rot2D copy() {
      return new Rot2D(cos, sin);
   }

   public Rot2D rotate(Rot2D that) {
      double cos = (this.cos * that.cos) - (this.sin * that.sin);
      double sin = (this.cos * that.sin) + (this.sin * that.cos);

      this.cos = cos;
      this.sin = sin;

      return this;
   }

   public static double cross(Rot2D a, Rot2D b) {
      return (a.cos * b.sin) - (a.sin * b.cos);
   }
}


TurnUI.java
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  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class TurnUI {
   public static void main(String[] args) {

      final Point item = new Point(400, 300);
      final Point target = new Point(350, 400);
      final Rot2D currAngle = Rot2D.fromVector(target.x - item.x, target.y - item.y);
      final Rot2D turnSpeedCW = Rot2D.fromDegrees(1.0);
      final Rot2D turnSpeedCCW = Rot2D.fromDegrees(-1.0);

      JPanel panel = new JPanel() {

         @Override
         protected void paintComponent(final Graphics g) {
            super.paintComponent(g);

            final Rot2D wantedAngle = Rot2D.fromVector(target.x - item.x, target.y - item.y);

            double cross1 = Rot2D.cross(currAngle, wantedAngle);
            if (cross1 > 0.0)
               currAngle.rotate(turnSpeedCW);
            else
               currAngle.rotate(turnSpeedCCW);
            double cross2 = Rot2D.cross(currAngle, wantedAngle);

            if (Math.signum(cross1) != Math.signum(cross2))
               currAngle.load(wantedAngle); // overshot!
           
           

            g.setColor(Color.BLACK);
            g.fillRect(item.x - 3, item.y - 3, 6, 6);
            g.drawLine(item.x, item.y, //
                  (int) (item.x + currAngle.cos * 64), //
                  (int) (item.y + currAngle.sin * 64));

            g.setColor(Color.RED);
            g.fillRect(target.x - 1, target.y - 1, 2, 2);



            // lousy game-loop:
            try {
               Thread.sleep(1000 / 50); // ~20fps
            } catch (InterruptedException exc) {
               // ok
            }
            this.repaint();
         }
      };

      panel.addMouseListener(new MouseAdapter() {
         @Override
         public void mousePressed(MouseEvent e) {
            if (e.getButton() == MouseEvent.BUTTON1) {
               target.x = e.getX();
               target.y = e.getY();
            }
         }
      });

      panel.setPreferredSize(new Dimension(800, 600));

      JFrame frame = new JFrame("Rot2D");
      frame.getContentPane().setLayout(new BorderLayout());
      frame.getContentPane().add(panel);
      frame.setResizable(true);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   }
}


Click to Play

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Offline Elsealabs
« Reply #32 - Posted 2014-12-30 00:18:26 »

Thanks for the code!

But I'm not really sure how I would implement it seeing as I am using LibGDX and not Swing, and am probably not good enough at math to transfer the concepts between frameworks. But I will definitely revisit this code again later in the project when I come back to refine the light movement.

Because there are a few things that need to change, but that I will revisit later so I can get on with the gaming process now

Needed changes:
  • If the mouse is being held down, the player should move towards it no matter what (It currently only moves forward if the angle changed, but someone should be able to hold their mouse down and move)
  • If someone clicks on the opposite side, it kind of just moves there instead of animating there,

But I managed to fix the spinning issues once and for all by adding "moving = false;" to the touchUp() method, so it automatically stops all movement when the person lets go, preventing any kind of "after the fact" spinning. But that method is a bit too trashy for me, so as I said, I will revisit it later.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline BurntPizza

« JGO Bitwise Duke »


Medals: 486
Exp: 7 years



« Reply #33 - Posted 2014-12-30 00:43:03 »

The core of it comes down to events that happen intermittently and things that must happen each frame:
- Mouse input updates a waypoint (which is stored persistently) intermittently
- Each frame the player rotates and moves towards the waypoint

So the physics will always be driven by the game loop (that's the whole point of the loop, plus rendering), but is supplied information by user input.

Now this can be implemented directly (literally just a waypoint), or it can be expanded to a queue of waypoints representing a path to follow: the player looks at the current waypoint and consumes it upon reaching it and then continuing on the next point if there is one, while the mouse input processor produces points to add to the queue. It's a standard producer-consumer problem. In fact the single-waypoint implementation is just a special case of the general queue, it is a single-element queue.
I think the path-following might look better and is only slightly more work. Depends on what behavior you want.

Once you have the architecture, all you need is the moveTowards(point) and rotateTowards(point), which are already supplied by Box2D in various ways that you can experiment with.

This is the same kind of architecture as pretty much every video game ever, and can be applied throughout, not just controlling a character based on mouse input.
Offline Riven
Administrator

« JGO Overlord »


Medals: 1371
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #34 - Posted 2014-12-30 08:34:01 »

Thanks for the code!

But I'm not really sure how I would implement it seeing as I am using LibGDX and not Swing, and am probably not good enough at math to transfer the concepts between frameworks. But I will definitely revisit this code again later in the project when I come back to refine the light movement.
There isn't anything that ties this to Swing, except the demo code that produces a UI Lips Sealed

It's about line 20-30 in TurnUI.java, everything else can be ignored... was meant to help you along, as opposed to scaring you off. There is no 'transfering between frameworks' at all.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Offline Elsealabs
« Reply #35 - Posted 2014-12-30 09:44:49 »

Ah. I went through it and attempted to bring it over to my project, but I am having some trouble at the very end when I am trying to transform the player to the new angle.

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  
      if (Gdx.input.isTouched())
      {
         // Set current touch
         touch_cur = new Vector2(Gdx.input.getX(), Gdx.input.getY());
         
         // Set default values
         if (touch_prev == null)
         {
            touch_prev = new Vector2(Gdx.input.getX(), Gdx.input.getY());
           
            touch_angleCur = Rot2D.fromVector(
               touch_cur.x - entity_player.getBody().getPosition().x,
               touch_cur.y - entity_player.getBody().getPosition().y
            );
         }
         
         // If they are holding down the mouse in one spot, move forward
         if (touch_prev == touch_cur)
         {
            // apply some kind of force
         }
         else
         {
            touch_angleWant = Rot2D.fromVector(
               touch_cur.x - entity_player.getBody().getPosition().x,
               touch_cur.y - entity_player.getBody().getPosition().y
            );
           
            double crossOne = Rot2D.cross(touch_angleCur, touch_angleWant);
           
            if (crossOne > 0.f) touch_angleCur.rotate(Rot2D.fromDegrees(1.0));
            else touch_angleCur.rotate(Rot2D.fromDegrees(-1.0));
           
            double crossTwo = Rot2D.cross(touch_angleCur, touch_angleWant);
           
            if (Math.signum(crossOne) != Math.signum(crossTwo))
               touch_angleCur.load(touch_angleWant);
           
            entity_player.getBody().setTransform(entity_player.getBody().getPosition(), /* How */);
         }
         
      }

Offline Riven
Administrator

« JGO Overlord »


Medals: 1371
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #36 - Posted 2014-12-30 10:19:15 »

I'm not familiar with Box2D, but if it demands an angle as one of the parameters to define a Transform, you can do:

1  
2  
3  
4  
5  
6  
7  
8  
9  
public class Rot2D {
   ...

+   public double getAngle() { // radians
+      return Math.atan2(sin, cos); // atan2(y, x)
+   }

   ...
}

1  
2  
3  
4  
entity_player.getBody().setTransform(
   entity_player.getBody().getPosition(),
   touch_angleCur.getAngle()
);

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Offline Elsealabs
« Reply #37 - Posted 2014-12-30 10:24:20 »

Getting some really weird behavior back. Going to try to figure it out.

Click to Play

Offline Riven
Administrator

« JGO Overlord »


Medals: 1371
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #38 - Posted 2014-12-30 10:34:53 »

Why would you only rotate on touch events?

1  
2  
3  
if (Gdx.input.isTouched()) {
   ...
}


From the gif animation it's (obviously Smiley) not clear when you're pressing and releasing mouse buttons. You can print out the values in your game-loop, to see what state it is in; mainly whether it reaches line 37: which detects whether we actually reached (and overshot) our target angle.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Offline Elsealabs
« Reply #39 - Posted 2014-12-30 10:54:14 »

I feel stupid for having to say this, but it's still not working...

Edit: Whenever it moves smoothly I am dragging, whenever it teleports I am clicking.

Click to Play


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  
      if (Gdx.input.isTouched())
      {
         touch_target = new Vector2(Gdx.input.getX(), Gdx.input.getY());
         
         touch_angleCur = Rot2D.fromVector(
            touch_target.x - entity_player.getBody().getPosition().x,
            touch_target.y - entity_player.getBody().getPosition().y
         );
      }
     
      if (touch_target != null)
      {
         touch_angleWant = Rot2D.fromVector(
            touch_target.x - entity_player.getBody().getPosition().x,
            touch_target.y - entity_player.getBody().getPosition().y
         );
         
         double cross1 = Rot2D.cross(touch_angleCur, touch_angleWant);
         
         if (cross1 > 0.0)
            touch_angleCur.rotate(Rot2D.fromDegrees(1.0));
         else
            touch_angleCur.rotate(Rot2D.fromDegrees(-1.0));
         
         double cross2 = Rot2D.cross(touch_angleCur, touch_angleWant);
         
         if (Math.signum(cross1) != Math.signum(cross2))
            touch_angleCur.load(touch_angleWant);
         
         entity_player.getBody().setTransform(entity_player.getBody().getPosition(), (float) touch_angleCur.getAngle());
      }

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Riven
Administrator

« JGO Overlord »


Medals: 1371
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #40 - Posted 2014-12-30 11:11:55 »

You flipped
touch_angleCur
and
touch_angleWant
on line 5.

When you provide input, you set the desired (wanted) angle. You slowly change the actual (current) angle to match it.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Offline Elsealabs
« Reply #41 - Posted 2014-12-30 11:15:01 »

You flipped
touch_angleCur
and
touch_angleWant
on line 5.

When you provide input, you set the desired (wanted) angle. You slowly change the actual (current) angle to match it.

Where/How and exactly what to should I set the current angle? Should I do it in the show() method before everything gets started? If so, what should I set it to?

Offline Riven
Administrator

« JGO Overlord »


Medals: 1371
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #42 - Posted 2014-12-30 11:16:07 »

The initial 'current angle' is entirely up to you.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Offline Elsealabs
« Reply #43 - Posted 2014-12-30 11:17:38 »

The initial 'current angle' is entirely up to you.

When you are setting the current angle, you do the following:

1  
final Rot2D currAngle = Rot2D.fromVector(target.x - item.x, target.y - item.y);


If I were to set this in the show() method, the target would not exist yet. What would I do instead to set the angle, say, pointing north.

Offline Riven
Administrator

« JGO Overlord »


Medals: 1371
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #44 - Posted 2014-12-30 11:18:29 »

Just make it
Rot2D.fromDegrees(0.0)
or any other angle you fancy.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Offline Elsealabs
« Reply #45 - Posted 2014-12-30 11:24:05 »

It rotates sporadically similar to the previous gifs even with the mentioned changes. I think this is just a sign for me to quit game dev because obviously I am doing something extremely incorrect, and at this point, I don't even remotely know what I am doing incorrectly.

1  
2  
3  
   private Vector2 touch_target = new Vector2(0, 0);
   private Rot2D touch_angleCur = Rot2D.fromDegrees(0.0);
   private Rot2D touch_angleWant;


Then in render...

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
         touch_angleWant = Rot2D.fromVector(
            touch_target.x - entity_player.getBody().getPosition().x,
            touch_target.y - entity_player.getBody().getPosition().y
         );
         
         double cross1 = Rot2D.cross(touch_angleCur, touch_angleWant);
         
         if (cross1 > 0.0)
            touch_angleCur.rotate(Rot2D.fromDegrees(1.0));
         else
            touch_angleCur.rotate(Rot2D.fromDegrees(-1.0));
         
         double cross2 = Rot2D.cross(touch_angleCur, touch_angleWant);
         
         if (Math.signum(cross1) != Math.signum(cross2))
            touch_angleCur.load(touch_angleWant);
         
         entity_player.getBody().setTransform(entity_player.getBody().getPosition(), (float) touch_angleCur.getAngle());

Offline Riven
Administrator

« JGO Overlord »


Medals: 1371
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #46 - Posted 2014-12-30 12:07:36 »

Don't give up so easily Smiley

It might simply be that Box2D has a different coordinate system (other orientation) and you simply need to flip the rotation, and potentially adding/subtracting 90deg:
1  
2  
3  
4  
entity_player.getBody().setTransform(
   entity_player.getBody().getPosition(),
  touch_angleCur.getAngle() * -1 + Math.PI * 0.5
);

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Offline Riven
Administrator

« JGO Overlord »


Medals: 1371
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #47 - Posted 2014-12-30 12:32:05 »

When you are visually debugging, you shouldn't click at arbitrary positions. Slowly click in a circular pattern around the light source, and check whether the rotation is applied in the opposite direction, whether there is merely an angle offset, or whether it's somehow behaving in another undesired way.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Offline lcass
« Reply #48 - Posted 2014-12-30 13:42:25 »

Your debugging is fairly bad, I would suggest using the good ol friend System.out.println(); print out the values that you need to debug such as the target position that it thinks the mouse is at, maybe you are trying to find the angle about the bottom left or upper left corner instead of the centre of the person, also use it to output the incremental rotation process. Click in a specific manor (like riven said) so that you can notice to what values that it works and at what values it doesnt work.

If I were doing this there are a few things that I would need to know , the position of rotation , current mouse position , the angular distance between the current angle of the mouse about the rotation point and the current rotation of the direction of the light perspective about the rotation point. The rotation point in your case is the centre of the entity you are moving so simply take that as the rotx and roty values . Calculating angular distance is almost as easy , Code from Riven :
1  
2  
3  
4  
entity_player.getBody().setTransform(
   entity_player.getBody().getPosition(),
   touch_angleCur.getAngle() * -1 + Math.PI * 0.5
);

that is the current angle around the point (thank you riven) of the mouse (hopefully).
I am no master of Box2d but I would assume you can do the same with the angle of the light from the entity position . * This may and most likely is where the bug could be so double check the values given by this section of code.
I assume you have a regular pulse that runs through your game , a tick , so to calculate how far your object should move each tick calculate  distance between the two angles (the angle between them) / tickrate , this gives it an accelerated feel if you dont want this then replace this value with a standard speed , then from this rotate the entity by this amount until its current rotation is equal to that of the mouse point.
Hypothetical demo of this:
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  
public float calc_rotation(Vertex2d entity_position,float rotation_entity , Vertex2d mouse_position,int tickrate){//returns the rotation increment 
      float rotation_mouse = rotate_about_point(entity_position,mouse_position);//fairly simple calculate the angle of point b about point a. Assume 0 is directly upward , we will work in degrees for now
      float absolute_distance = Math.max(rotation_entity,rotation_mouse) - Math.min(rotation_mouse,rotation_entity);//calculate the maximum possible distance between the two points
      if(absolute_distance <= 180){//if were going anti clockwise
         return -(absolute_distance / tickrate);
      }
      else{//if not
         absolute_distance = 360 - absolute_distance;//
         return absolute_distance/ tickrate;
      }
     
   }
   private float rotation_rate = 0;
   private boolean rotating = false;//update this as you require when the mouse is clicked
   private int rotate_tick = 0;//as we are doing this per second( ticks per second is the tickrate) then we use this to track the value
   public void setup(){
      rotation_rate = calc_rotation(your entity position, the amount its rotated, the current mouse position , current tickrate);
   }
   public void tick(){
      if(rotating){
         if(rotate_tick < tickrate){
            Entity.rotate_by(rotation_rate);//IE increase its current angle this can also be done by Entity.rotation += rotation_rate; Entity.rotate(Entity.rotation);
         }
         if(rotate_tick >= tickrate){//reset the variable once it reaches this point
            rotating = false;
            rotate_tick = 0;
         }
      }
   }

Hope this helps.
Thanks.
Offline Elsealabs
« Reply #49 - Posted 2014-12-30 20:45:39 »

Added print statements to the code to get some insight into what is going on, but from what I can see, the wanted angle and the current angle do event meet up with each other, but they do not go to the right place. I am going to try to figure out what is going on, but I figured I'd post this while I do that in case anyone has anything else to say.

This is the output after one click.

http://pastebin.com/uebW4qdq

This is the 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  
      if (Gdx.input.isTouched())
      {
         touch_target = new Vector2(Gdx.input.getX(), Gdx.input.getY());
         System.out.printf("[Touch] Just touched, setting new touch target.\n");
         System.out.printf("New touch target at (%f, %f)\n", touch_target.x, touch_target.y);
      }
     
      /** Touch handling */
         touch_angleWant = Rot2D.fromVector(
            touch_target.x - entity_player.getBody().getPosition().x,
            touch_target.y - entity_player.getBody().getPosition().y
         );
         
         System.out.printf("[Angle] touch_angleWant.getAngle() = %f\n", (float) touch_angleWant.getAngle());
         
         double cross1 = Rot2D.cross(touch_angleCur, touch_angleWant);
         
         if (cross1 > 0.0)
            touch_angleCur.rotate(Rot2D.fromDegrees(1.0));
         else
            touch_angleCur.rotate(Rot2D.fromDegrees(-1.0));
         
         double cross2 = Rot2D.cross(touch_angleCur, touch_angleWant);
         
         if (Math.signum(cross1) != Math.signum(cross2))
            touch_angleCur.load(touch_angleWant);
         
         System.out.printf("[Angle] touch_angleCur.getAngle() = %f\n", (float) touch_angleCur.getAngle());
         
         entity_player.getBody().setTransform(entity_player.getBody().getPosition(), (float) (touch_angleCur.getAngle()));

Offline Riven
Administrator

« JGO Overlord »


Medals: 1371
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #50 - Posted 2014-12-30 21:30:08 »

Does it always rotate in the wrong direction, or does it depend on the angles?

Anyway, can you run my Swing code? Does the problem show there? I cannot reproduce your issue.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Offline Elsealabs
« Reply #51 - Posted 2014-12-30 21:49:32 »

I just ran your Swing code and it works fine and as intended.

I'll go through the things that could possibly be wrong with my code.

I am pretty sure Body.setTransform(...) takes the angle in Radians due to this code I found in the tutorials, and your class is returning in Radians, so that's most likely fine.

1  
2  
3  
4  
#define DEGTORAD 0.0174532925199432957f
#define RADTODEG 57.295779513082320876f
 
  dynamicBody->SetTransform( b2Vec2( 10, 20 ), 45 * DEGTORAD );


--

Every time the screen is touched or dragged or any kind of movement involving touch happens, I update a Vector2 object containing the mouse position, like this

1  
touch_target = new Vector2(Gdx.input.getX(), Gdx.input.getY());


Then after that it finds the wanted angle like this

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
if (Gdx.input.isTouched())
{
   touch_target = new Vector2(Gdx.input.getX(), Gdx.input.getY());
   System.out.printf("[Touch] Just touched, setting new touch target.\n");
   System.out.printf("New touch target at (%f, %f)\n", touch_target.x, touch_target.y);
}

touch_angleWant = Rot2D.fromVector(
   touch_target.x - entity_player.getBody().getPosition().x,
   touch_target.y - entity_player.getBody().getPosition().y
);

System.out.printf("touch_angleWant = Rot2D.fromVector(\n\t%f - %f,\n\t%f - %f\n);\n",
   touch_target.x, entity_player.getBody().getPosition().x,
   touch_target.y, entity_player.getBody().getPosition().y
);

System.out.printf("touch_angleWant.getAngle() = %f\n", touch_angleWant.getAngle());


This is a section of the output of this code, right as I click: http://pastebin.com/Vt7QEaJa

It must be something where your code meets Box2D. Maybe it has something to do with transfering world coordinates to screen coordinates? I am very new to Box2D so I don't know much about it but Burnt mentioned something about unproject? That may be the issue? I'll look into what unproject does and if its useful here.

Offline Riven
Administrator

« JGO Overlord »


Medals: 1371
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #52 - Posted 2014-12-30 21:57:01 »

Render a sprite at touch_target and verify it actually is rendered where you click / drag.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings!
Offline BurntPizza

« JGO Bitwise Duke »


Medals: 486
Exp: 7 years



« Reply #53 - Posted 2014-12-30 21:58:00 »

It must be something where your code meets Box2D. Maybe it has something to do with transfering world coordinates to screen coordinates? I am very new to Box2D so I don't know much about it but Burnt mentioned something about unproject? That may be the issue? I'll look into what unproject does and if its useful here.

Yeah... change this line:

1  
2  
3  
4  
5  
6  
7  
8  
if (Gdx.input.isTouched())
{
-   touch_target = new Vector2(Gdx.input.getX(), Gdx.input.getY());
+   Vector3 tmp = camera.unproject(new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0));
+   touch_target = new Vector2(tmp.x, tmp.y);
   System.out.printf("[Touch] Just touched, setting new touch target.\n");
   System.out.printf("New touch target at (%f, %f)\n", touch_target.x, touch_target.y);
}


Box2D does everything in radians and meters. Gdx.input.getX() etc. return in pixels. Camera.unproject does the required conversion from pixels to meters (ever heard of dimensional analysis?) so that Box2D correctly interprets everything. Otherwise you might click at (500, 400) on your screen right next to your sprite, but Box2D thinks you just clicked a point 500 meters away in "world space," when it's actually less than a meter away.
Offline Elsealabs
« Reply #54 - Posted 2014-12-30 22:01:24 »

Oh lord... This was what was wrong the entire time. It works properly now. - bangs head against desk -

Thanks for all of your help Riven and BurntPizza. I really appreciate it. This forum is a great place and has a great community.

Now to work on getting it to change position as well.

Offline BurntPizza

« JGO Bitwise Duke »


Medals: 486
Exp: 7 years



« Reply #55 - Posted 2014-12-30 22:10:14 »

Also, a similar trick that can be of help, is setting your sprites' size in meters rather than pixels:

1  
2  
3  
4  
5  
6  
// width and height are in meters
public static Sprite makeSprite(String name, float width, float height) {
    Sprite s = atlas.createSprite(name); // this is using a texture atlas, but it doesn't matter where the sprite comes from
    s.setScale(width / s.getWidth(), height / s.getHeight()); // the sprite width/height methods return pixels
    return s;
}


So then to render you just:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
box2Dcamera.update(); // or viewport.apply();
batch.setProjectionMatrix(box2Dcamera.combined);

sprite.setCenter(box2Dbody.getPosition());
sprite.setRotation(Math.toDegrees(box2Dbody.getAngle()));

batch.begin();
sprite.draw(batch);
// more stuff, loop through and render entities, etc.
batch.end();


And it all just works. You can use the Box2D debug renderer to see that the sprites are the same size and in the same position as the bodies.
Offline Elsealabs
« Reply #56 - Posted 2014-12-30 22:17:08 »

So, just to make sure I am understanding fully, I have a question.

I am setting up my camera like this:

1  
2  
3  
camera = new OrthographicCamera();
viewport = new ScreenViewport(camera);
viewport.setUnitsPerPixel(1 / 32f);


And then loading the sprite like this:

1  
2  
sprite_floor = new Sprite(new Texture(Gdx.files.internal("wood.png")));
sprite_floor.setPosition(0, 0);


And then rendering the sprite like this.

1  
2  
3  
4  
batch.begin();
   sprite_floor.setSize(50, 50);
   sprite_floor.draw(batch);
batch.end();


If I use the setSize(50, 50), it looks fairly normal on the screen, as seen in the image below. But if I do not set a size, it is extremely large and pixelated.

I do not understand what is going on here. When feeding numbers to setSize(), what unit is being used? And how does this relate to .setUnitsPerPixel(1 / 32f)? If this is too much to explain you don't have to, I understand, I just don't have a very good conceptual grasp on the units, converting them, and how it works with the camera and sprites.

Offline BurntPizza

« JGO Bitwise Duke »


Medals: 486
Exp: 7 years



« Reply #57 - Posted 2014-12-30 22:29:05 »

It's in pixels, although how that relates to the camera/viewport is indeterminable from here as I do not know if you actually update the camera/viewport when needed.
Offline Elsealabs
« Reply #58 - Posted 2014-12-30 22:30:20 »

So if it takes pixels then how is only 50 pixels so large? That is what I am confused about.

Also:

1  
2  
3  
4  
5  
@Override
public void resize(int width, int height)
{
    viewport.update(width, height);
}

Offline Elsealabs
« Reply #59 - Posted 2015-01-06 01:59:10 »

Here again. The rotating code works fine, but I have tried and failed to create a way for the player to move towards the mouse click.

Using setTransform and some kind of interpolation would have it going straight through walls, so I figured I should apply some kind of force to the body. I tried doing this, but of course, I am no good at math, and it did not end up going too well. I've followed a few online tutorials, but none seem to work/do what I need.

Can anyone help?

Pages: 1 [2]
  ignore  |  Print  
 
 

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

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

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

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

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

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

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

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

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

nelsongames (5113 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!