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 LibGDX Top down car rotation very weird and buggy  (Read 1615 times)
0 Members and 2 Guests are viewing this topic.
Offline elaguy

Junior Newbie





« Posted 2017-04-05 23:16:12 »

Hi, I've been working on a top down 2D racing game in Java with LibGDX. I've spent the last several days trying to implement some kind of rotation system for the car, following several forum posts and websites. I'm using an X and Y 2D Vector for velocity, and the Up and Down arrow keys add acceleration to the velocity X and Y. The Left arrow key subtracts the rotation angle from the rotationStep, and the Right arrow key adds it. Then friction is accounted for and the positions for the car are set based on the rotation angle and the velocity. Right now, pressing up makes the car go forward at a 45 degree angle, and pressing down makes the car move at a 225 degree angle, but still forward. However, if you press the left or right arrow keys to rotate, everything gets crazy; the car rotates way too fast (which I've tried lowering the rotationStep but it doesn't do much), and when the car rotates, the angle changes as indicated by some print calls, but it moves in a small circle for a time and when you press the up or down arrows the rotation angle goes back to 45 degrees or 225 degrees. If someone can figure out what the heck is going on, it would be much appreciated! Thanks!

Also, the car is oriented from west to east, with the front of the car pointing towards the west; 180 degrees. Maybe that has something to do with anything?  Clueless

Here's the Track1 class that has all the movement code for the car in it.
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  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.math.Vector2;

public class Track1 implements Screen {
   
   private CORGame game;
   private OrthographicCamera cam;
   
   private Texture background;
   private Texture trackTex;
   private Texture playerCarTex;
   
   private Sprite track;
   private Sprite playerCar;
   
   private float trackX;
   private float trackY;
   
   private Vector2 velocity;
   private float acc; // acceleration
   private float friction;
   private float rotation;
   private float rotationStep;
   private float topVelocity;
   
   public Track1(CORGame game) {
      this.game = game;
     
      cam = new OrthographicCamera(game.getScreenWidth(), game.getScreenHeight());
      cam.update();
     
      loadAssets();
     
      track = new Sprite(trackTex);
      playerCar = new Sprite(playerCarTex);
     
      trackX = (-track.getWidth()/2) - 90;
      trackY = (game.getScreenHeight()/2) - (playerCar.getHeight()/2);
     
      track.setPosition(trackX, trackY);
      playerCar.setPosition((game.getScreenWidth()/2) - (playerCar.getWidth()/2),
            (game.getScreenHeight()/2) - (playerCar.getHeight()/2));
     
      velocity = new Vector2(0, 0);
      acc = 0.1f;
      friction = 0.01f;
      rotation = 0;
      rotationStep = 0.1f;
      topVelocity = 50;
   }

   @Override
   public void show() {
     
   }

   @Override
   public void render(float delta) {
      Gdx.gl.glClearColor(0/255f, 0/255f, 0/255f, 0/255f);
      Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
     
      game.batch.begin();
     
      game.batch.setProjectionMatrix(cam.combined);
     
      game.batch.draw(background, trackX, trackY, background.getWidth(), background.getHeight());
      game.batch.draw(track, trackX, trackY);
      game.batch.draw(playerCar, playerCar.getX(), playerCar.getY(), playerCar.getOriginX(),
            playerCar.getOriginY(), playerCar.getWidth(), playerCar.getHeight(), 1, 1, playerCar.getRotation());
     
      game.batch.end();
     
      update(delta);
   }
   
   private void update(float delta) {
     
      if(Gdx.input.isKeyPressed(Input.Keys.UP)) {
         velocity.x += acc;
         velocity.y += acc;
      }
     
      if(Gdx.input.isKeyPressed(Input.Keys.DOWN)) {
         velocity.x -= acc;
         velocity.y -= acc;
      }
     
      if(Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
         rotation -= rotationStep;
         velocity.rotate(rotation);
         playerCar.rotate(velocity.angle());
      }
     
      if(Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {
         rotation += rotationStep;
         velocity.rotate(rotation);
         playerCar.rotate(velocity.angle());
      }
     
      if(Math.abs(velocity.x) < 0.1 || Math.abs(velocity.y) < 0.1) {
         velocity.x = 0;
         velocity.y = 0;
      }
     
      velocity.x *= (1 - friction);
      velocity.y *= (1 - friction);
     
      playerCar.setOriginCenter();
     
      playerCar.setX((float) (playerCar.getX() + (Math.cos(velocity.angle()) * velocity.x)));
      playerCar.setY((float) (playerCar.getY() + (Math.sin(velocity.angle()) * velocity.y)));
     
      cam.position.set(playerCar.getX() + (playerCar.getWidth()/2), playerCar.getY() + (playerCar.getHeight()/2), 0);
      cam.update();
   }

   @Override
   public void resize(int width, int height) {
      game.viewport.update(width, height);
   }

   @Override
   public void pause() {
     
   }

   @Override
   public void resume() {
     
   }

   @Override
   public void hide() {
     
   }

   @Override
   public void dispose() {
     
   }
   
   private void loadAssets() {
      background = game.mgr.get("img/backgrnd_1.png", Texture.class);
      trackTex = game.mgr.get("img/track1.png", Texture.class);
      playerCarTex = game.mgr.get("img/car1.png", Texture.class);
   }

}
Offline dfour
« Reply #1 - Posted 2017-04-06 11:08:29 »

Hi elaguy ,

You're currently setting the both x and y velocity when the the player presses up or down. This is causing your car to move in those angles.

Instead of setting the velocity of the car directly you could update the car speed from the user input and then calculate the velocity based on the angle of rotation of the car. e.g:

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  
private void update(float delta) {
     
      if(Gdx.input.isKeyPressed(Input.Keys.UP)) {
         speed+=1f ;
         if(speed > 2){
            speed = 1;
         }
      }
     
      if(Gdx.input.isKeyPressed(Input.Keys.DOWN)) {
         speed-=1f;
         if(speed < 0){
            speed = 0;
         }
      }
     
      if(Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
         playerCar.rotate(+3);
      }
     
      if(Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {
         playerCar.rotate(-3);
      }
     
      playerCar.setOriginCenter();
     
      Vector2 vel = getVelocity(speed,playerCar.getRotation());
      playerCar.setX(playerCar.getX() + vel.x);
      playerCar.setY(playerCar.getY() + vel.y);
     
      System.out.println("Rotation:"+playerCar.getRotation());
     
      cam.position.set(playerCar.getX() + (playerCar.getWidth()/2), playerCar.getY() + (playerCar.getHeight()/2), 0);
      cam.update();
   }
   
   private Vector2 getVelocity(float sp, float rotation){
      Vector2 vel = new Vector2();
      float vx = (float) Math.cos(Math.toRadians(rotation)) * sp;
      float vy = (float) Math.sin(Math.toRadians(rotation)) * sp;
      vel.x = vx;
      vel.y = vy;
      return vel;
   }
Offline elaguy

Junior Newbie





« Reply #2 - Posted 2017-04-06 20:41:47 »

Thank you, dfour! That clears everything up nicely. I'll try that when I can and see what happens.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline elaguy

Junior Newbie





« Reply #3 - Posted 2017-04-07 21:23:15 »

Alright, so I implemented everything and now rotation works like a charm. I had to fix a few things regarding friction but now my car is moving just fine now. Thanks again.
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!