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? :clue:
Here’s the Track1 class that has all the movement code for the car in it.
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);
}
}