user3696181
user3696181

Reputation: 89

How can I find my issue with limiting my speed for my Java game?

I am currently making a game where you drive a tank and am currently working on the player class. I want the tank to have inertia for a tiny bit of realistic movement. I have this issue where the speed of my tank isn't topping out at the limit I'm setting. What is strange is that the angle velocity part works great as far as I can tell. Both chunks use the same logic. Right now the tank velocity will max out starting at 1.6, then somewhere between 2 and 3, then 5 and 6, every time you click backwards/forwards.

Here is the code:

final class Player extends GameObject {


private static final double ANGLE_VELOCITY_MAX = Math.PI / 60, ANGLE_VELOCITY_STEP = Math.PI / 900,
        ACCELERATION_STEP = .1, ACCELERATION_MAX = 1;
private double angle = 0, angleVelocity = 0, speed = 0, acceleration = 0;

@Override
public final void tick() {
    if (gc.getKey(KeyEvent.VK_W) && speed < ACCELERATION_MAX)
        if (acceleration + ACCELERATION_STEP > ACCELERATION_MAX)
            acceleration = ACCELERATION_MAX;
        else
            acceleration += ACCELERATION_STEP;
    else if (gc.getKey(KeyEvent.VK_S) && speed > -ACCELERATION_MAX)
        if (acceleration - ACCELERATION_STEP < -ACCELERATION_MAX)
            acceleration = -ACCELERATION_MAX;
        else
            acceleration -= ACCELERATION_STEP;
    else if (Math.abs(acceleration) < ACCELERATION_STEP)
        acceleration = 0;
    else
        acceleration -= Math.signum(acceleration) * ACCELERATION_STEP;
    if (gc.getKey(KeyEvent.VK_D) && angleVelocity < ANGLE_VELOCITY_MAX)
        if (angleVelocity + ANGLE_VELOCITY_STEP > ANGLE_VELOCITY_MAX)
            angleVelocity = ANGLE_VELOCITY_MAX;
        else
            angleVelocity += ANGLE_VELOCITY_STEP;
    else if (gc.getKey(KeyEvent.VK_A) && angleVelocity > -ANGLE_VELOCITY_MAX)
        if (angleVelocity - ANGLE_VELOCITY_STEP < -ANGLE_VELOCITY_MAX)
            angleVelocity = -ANGLE_VELOCITY_MAX;
        else
            angleVelocity -= ANGLE_VELOCITY_STEP;
    else if (Math.abs(angleVelocity) < ANGLE_VELOCITY_STEP)
        angleVelocity = 0;
    else
        angleVelocity -= Math.signum(angleVelocity) * ANGLE_VELOCITY_STEP;
    if (--treadCooldown <= 0) {
        if (++treadIndex >= treads.length)
            treadIndex = 0;
        treadCooldown = TREAD_COOLDOWN;
    }
    angle += angleVelocity;
    speed += acceleration;
    location.translate(Math.cos(angle) * speed, Math.sin(angle) * speed);
}

Upvotes: 0

Views: 74

Answers (1)

giorgiga
giorgiga

Reputation: 1778

My guess is that you ought introduce some limit for speed independent of ACCELERATION_MAX, edit the first ifs to something like:

     if (gc.getKey(KeyEvent.VK_W) && acceleration < ACCELERATION_MAX)
    ...
else if (gc.getKey(KeyEvent.VK_S) && acceleration > -ACCELERATION_MAX)
    ...

and at the end ensure speed is within acceptable limits.

BTW:

I have to admit your code above is really hard to read (let alone reason about) for me - I suggest reorganising to something like:

@Override
public final void tick() {
       if (gc.getKey(KeyEvent.VK_W)) accelerate(ACCELERATION_STEP);
  else if (gc.getKey(KeyEvent.VK_S)) accelerate(-ACCELERATION_STEP);
  else                               accelerate(- Math.signum(acceleration) * ACCELERATION_STEP);
  // etc.. you get the idea
}

private void accelerate(double delta) {
  setAcceleration(acceleration +delta);
}

private void setAcceleration(double value) {
  acceleration = roundToZero(constrain(value, -ACCELERATION_MAX, ACCELERATION_MAX), ACCELERATION_STEP);
}

private static double constrain(double value, double min, double max) {
  return value > max ? max : (value < min ? min : value);
}

private static double roundToZero(double value, double radius) {
  return Math.abs(value) < radius ? 0 : value;
}

Disclaimer: did not test the above, nor tried to compile it.

Upvotes: 1

Related Questions