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

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);   }}`
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;   }`
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.
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 JavaFXby philfrei2019-12-19 19:35:12Java Gaming Resourcesby philfrei2019-05-14 16:15:13Deployment and Packagingby philfrei2019-05-08 15:15:36Deployment and Packagingby philfrei2019-05-08 15:13:34Deployment and Packagingby philfrei2019-02-17 20:25:53Deployment and Packagingby mudlee2018-08-22 18:09:50Java Gaming Resourcesby gouessej2018-08-22 08:19:41Deployment and Packagingby gouessej2018-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