Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (539)
Games in Android Showcase (132)
games submitted by our members
Games in WIP (603)
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 3
  ignore  |  Print  
  Car rotation problem in top down  (Read 9341 times)
0 Members and 1 Guest are viewing this topic.
Offline deadly72

Junior Devvie





« Posted 2011-02-21 02:42:34 »

Hi everyone,
First off let me say that I've been browsing this forum as a guest for a while now, and the community really seems to be friendly compared to some places I've seen in the past and I hope that I can contribute as much as I've seen people do.  It really is a pleasure not seeing anyone being flamed because of the level of intellect they may or may not have Smiley

Moving on to business then.  As much as I've scoured the internet in search of information concerning Java game programming, I've found that this forum in addition to some other sources are close enough to the best you can be lead to.  I've got a problem with positioning and rotation in a top down car game I'm building and all the resources I've seen so far do not go through as much detail as I would hope concerning certain aspects.

The following code is what I have presently, and it would be of great help if someone could point me in the right direction or tell me what is actually being done wrong.

This is where I render my drawing from the game loop.
1  
2  
3  
4  
5  
6  
7  
8  
9  
   
public void render(Graphics2D g) {
        ...
   g.rotate(rotation,x,y);
   g.drawImage(carImage, x, y, null);
     
   g.setColor(Color.GRAY);
   g.drawRect(getBounds().x, getBounds().y, getBounds().width, getBounds().height);
}


This is where i update the drawing for the render process
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
public void update(int deltaTime) {
   if ((Map.getGameArea().contains(getBounds()))) {
      if (speed >= 0) {
         if (slowdown)
            speed -= .1;
           
              move();
      }        
   }

        ...


This is when keys are pressed
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
public void keyPressed(KeyEvent evt) {
   slowdown = false;
     
   if (evt.getKeyCode() == KeyEvent.VK_UP) {
      speed += acceleration;
   }
   if (evt.getKeyCode() == KeyEvent.VK_DOWN) {
      speed -= acceleration;
   }
   if (evt.getKeyCode() == KeyEvent.VK_RIGHT) {
      rotation += rotationStep * (speed/TOPSPEED);
   }
   if (evt.getKeyCode() == KeyEvent.VK_LEFT) {
      rotation -= rotationStep * (speed/TOPSPEED);
   }
}


These are variables that are used to determine the angle

private double rotation = 0;
private double rotationStep = 1.1;

And finally the most important? method to actually change the coordinates
1  
2  
3  
4  
5  
6  
7  
   
private void move() {  
   double ax = Math.sin(rotation * (Math.PI/180)) * speed;
   double ay = Math.cos(rotation * (Math.PI/180)) * speed * -1;
   x += ax;
   y += ay;
}


The variables for speed and acceleration are initialized with 0 and .3 respectively

The actual problem seems the lie in the move method as the x constantly remains 0, and in all honesty I don't understand why.
Thanks for your time!
Offline ra4king

JGO Kernel


Medals: 356
Projects: 3
Exp: 5 years


I'm the King!


« Reply #1 - Posted 2011-02-21 05:25:02 »

What primitive type is X? int or double?

Offline deadly72

Junior Devvie





« Reply #2 - Posted 2011-02-21 05:40:00 »

x and y are both int's seeing as you can't have a pixel being a double or float or even at that matter a long Smiley
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline ra4king

JGO Kernel


Medals: 356
Projects: 3
Exp: 5 years


I'm the King!


« Reply #3 - Posted 2011-02-21 06:20:23 »

Well there is your problem Cheesy
If you keep adding a double to an int, the decimal part gets chopped off. So if you start out with 0, you add 0.5 to it, x is still 0!
Change x and y to double then in your render() method, use (int)Math.round(x) and (int)Math.round(y) in your drawImage() method Smiley

Offline deadly72

Junior Devvie





« Reply #4 - Posted 2011-02-21 07:22:20 »

Ahhhh! that seems to have fixed the problem somewhat, but I believe there is still a problem relating with the rotation of the image in the render? In addition to that, it the movement for the rotation doesn't feel smooth, and I think the problem for that is because it doesn't move in the direction the sprite is headed towards.  Can you think of any idea why?
BTW, I should have thought of changing the x and y variables then typecasting them to integers inside my render but I've been on this problem for quite a while, at least a week and I couldn't figure out why! so I guess a second pair of eyes really do help! Smiley
Offline ra4king

JGO Kernel


Medals: 356
Projects: 3
Exp: 5 years


I'm the King!


« Reply #5 - Posted 2011-02-21 08:09:30 »

By the looks of it, the rotation is dependent on the speed. The faster you go, the more you rotate; the slower you go, the less you rotate.
Try making the rotation constant.

Offline deadly72

Junior Devvie





« Reply #6 - Posted 2011-02-21 17:37:42 »

Hahaha the problem was indeed the rotation!, but if you notice my call to the rotation function in the graphics2d class used degrees instead of radians, which required a simple solution Math.toRadians(rotation) and voila the trick is done.  Everything seems to be fine for now, I'll just run a few tests a see what gives!

Thanks a bunch!
Offline ra4king

JGO Kernel


Medals: 356
Projects: 3
Exp: 5 years


I'm the King!


« Reply #7 - Posted 2011-02-21 18:32:54 »

You could also call Math.toRadians(rotation) in your move method Cheesy

Glad to help!

Offline pjt33
« Reply #8 - Posted 2011-02-21 23:02:32 »

...And finally the most important? method to actually change the coordinates
1  
2  
3  
4  
5  
6  
7  
   
private void move() {  
   double ax = Math.sin(rotation * (Math.PI/180)) * speed;
   double ay = Math.cos(rotation * (Math.PI/180)) * speed * -1;
   x += ax;
   y += ay;
}


The variables for speed and acceleration are initialized with 0 and .3 respectively...
You'll probably find that the movement feels very strange at the moment, because you're using a one-dimensional speed which rotates with the car. I don't have any worthwhile experience with car games, but I would guess that you'll want to use a full vectorial speed and then add a friction component to damp speed perpendicular to the facing of the car so that you corner in a way which feels right.
Offline deadly72

Junior Devvie





« Reply #9 - Posted 2011-02-22 19:11:55 »

...And finally the most important? method to actually change the coordinates
1  
2  
3  
4  
5  
6  
7  
   
private void move() {  
   double ax = Math.sin(rotation * (Math.PI/180)) * speed;
   double ay = Math.cos(rotation * (Math.PI/180)) * speed * -1;
   x += ax;
   y += ay;
}


The variables for speed and acceleration are initialized with 0 and .3 respectively...
You'll probably find that the movement feels very strange at the moment, because you're using a one-dimensional speed which rotates with the car. I don't have any worthwhile experience with car games, but I would guess that you'll want to use a full vectorial speed and then add a friction component to damp speed perpendicular to the facing of the car so that you corner in a way which feels right.

Actually movement on the level of acceleration in any angle feels relatively smooth, but the actual problem is while steering the car left or right.  It feels choppy and I think thats due to the rotation step, but I don't know how to calculate a smooth rotation other then trial and error.  Any ideas?

EDIT: Also forgot to mention something about handling acceleration and reverse for the car.  I think this is probably a bad way to handle things but here it is anyway.  If you also have any ideas how to handle this any better, please share  Smiley
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
if (Math.round(currentSpeed) > 0) {
   if (slowdown)
      currentSpeed -= .1;
     
   move();
}
if (Math.round(currentSpeed) < 0) {
   if (slowdown)
      currentSpeed += .1;
           
   move();
}


First if statement used when accelerating, and second is reverse. I need to round the currentSpeed seeing as it will either keep accelerating or in reverse if the speed is > or < without rounding.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline ra4king

JGO Kernel


Medals: 356
Projects: 3
Exp: 5 years


I'm the King!


« Reply #10 - Posted 2011-02-22 20:30:27 »

...And finally the most important? method to actually change the coordinates
1  
2  
3  
4  
5  
6  
7  
   
private void move() {  
   double ax = Math.sin(rotation * (Math.PI/180)) * speed;
   double ay = Math.cos(rotation * (Math.PI/180)) * speed * -1;
   x += ax;
   y += ay;
}


The variables for speed and acceleration are initialized with 0 and .3 respectively...
You'll probably find that the movement feels very strange at the moment, because you're using a one-dimensional speed which rotates with the car. I don't have any worthwhile experience with car games, but I would guess that you'll want to use a full vectorial speed and then add a friction component to damp speed perpendicular to the facing of the car so that you corner in a way which feels right.

Actually movement on the level of acceleration in any angle feels relatively smooth, but the actual problem is while steering the car left or right.  It feels choppy and I think thats due to the rotation step, but I don't know how to calculate a smooth rotation other then trial and error.  Any ideas?
It seems that trial and error is the best way here. Try lowering the rotation step and analyzing the output.

EDIT: Also forgot to mention something about handling acceleration and reverse for the car.  I think this is probably a bad way to handle things but here it is anyway.  If you also have any ideas how to handle this any better, please share  Smiley
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
if (Math.round(currentSpeed) > 0) {
   if (slowdown)
      currentSpeed -= .1;
     
   move();
}
if (Math.round(currentSpeed) < 0) {
   if (slowdown)
      currentSpeed += .1;
           
   move();
}


First if statement used when accelerating, and second is reverse. I need to round the currentSpeed seeing as it will either keep accelerating or in reverse if the speed is > or < without rounding.
Why the slowdown boolean variable?

Offline deadly72

Junior Devvie





« Reply #11 - Posted 2011-02-22 20:38:12 »

When I release my key, I want it to decelerate to 0, thus the slowdown variable, although I could just shove the speed -= acceleration in the keyreleased which would probably increase performance... hmmm, well good eye! Smiley

EDIT: Actually removing the variable wouldn't work because there would be no deceleration and I can't just currentSpeed -= .1 inside keyReleased since the action is only being done once.
Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11
Exp: 10 years


Game Engineer


« Reply #12 - Posted 2011-02-22 21:32:15 »

When I release my key, I want it to decelerate to 0, thus the slowdown variable, although I could just shove the speed -= acceleration in the keyreleased which would probably increase performance... hmmm, well good eye! Smiley

EDIT: Actually removing the variable wouldn't work because there would be no deceleration and I can't just currentSpeed -= .1 inside keyReleased since the action is only being done once.
You don't want -=, you want *=, as per usual with friction. Then set it to 0 if it gets too low.

ex.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
public void moveCar()
{
    double friction = 0.05;
    car.velocity.x *= (1 - friction);
    car.velocity.y *= (1 - friction);
    car.velocity.x += acceleration.x;
    car.velocity.y += acceleration.y;

    // dampen velocity so that objects will actually be at rest eventually
    car.velocity.x = Math.abs(car.velocity.x) < 0.01 ? 0 : car.velocity.x;
    car.velocity.y = Math.abs(car.velocity.y) < 0.01 ? 0 : car.velocity.y;
}

See my work:
OTC Software
Offline ra4king

JGO Kernel


Medals: 356
Projects: 3
Exp: 5 years


I'm the King!


« Reply #13 - Posted 2011-02-22 21:32:58 »

The best to do this is to have an update() method that is called at a regular interval. Then when a user presses a key, you set the rotation and acceleration accordingly so they would be updated next time udpate() is called. When a user releases a key, you set it so next time update() is called, you start decelerating.

Offline ra4king

JGO Kernel


Medals: 356
Projects: 3
Exp: 5 years


I'm the King!


« Reply #14 - Posted 2011-02-22 21:34:41 »

1  
2  
3  
4  
5  
6  
7  
8  
public void moveCar()
{
    double friction = 0.05;
    car.velocity.x *= (1 - friction);
    car.velocity.y *= (1 - friction);
    car.velocity.x += acceleration.x;
    car.velocity.y += acceleration.y;
}


Don't you mean:
1  
2  
    acceleration.x *= (1 - friction);
    acceleration.y *= (1 - friction);

Cheesy

Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11
Exp: 10 years


Game Engineer


« Reply #15 - Posted 2011-02-22 21:36:05 »

The best to do this is to have an update() method that is called at a regular interval. Then when a user presses a key, you set the rotation and acceleration accordingly so they would be updated next time udpate() is called. When a user releases a key, you set it so next time update() is called, you start decelerating.
Conceptually I disagree with you. In my opinion, friction should be applied at all times, given that it is in fact friction. Even when you are accelerating you are under the effect of a small amount of friction (like 0.05). When you are decelerating, you would be increasing the friction (you're hitting the brakes), but that doesn't change that friction should always be applied.

See my work:
OTC Software
Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11
Exp: 10 years


Game Engineer


« Reply #16 - Posted 2011-02-22 21:39:29 »

1  
2  
3  
4  
5  
6  
7  
8  
public void moveCar()
{
    double friction = 0.05;
    car.velocity.x *= (1 - friction);
    car.velocity.y *= (1 - friction);
    car.velocity.x += acceleration.x;
    car.velocity.y += acceleration.y;
}


Don't you mean:
1  
2  
    acceleration.x *= (1 - friction);
    acceleration.y *= (1 - friction);

Cheesy
No, I don't, that wouldn't work. Friction does not affect the acceleration applied by the engine, friction is a separate source of force, so it affects velocity. http://en.wikipedia.org/wiki/Friction

Also just thinking purely in a "what will work" approach, if you are constantly reducing the acceleration then the vehicle will still never stop, because nothing is curbing the velocity.

See my work:
OTC Software
Offline ra4king

JGO Kernel


Medals: 356
Projects: 3
Exp: 5 years


I'm the King!


« Reply #17 - Posted 2011-02-22 21:44:12 »

The best to do this is to have an update() method that is called at a regular interval. Then when a user presses a key, you set the rotation and acceleration accordingly so they would be updated next time udpate() is called. When a user releases a key, you set it so next time update() is called, you start decelerating.
Conceptually I disagree with you. In my opinion, friction should be applied at all times, given that it is in fact friction. Even when you are accelerating you are under the effect of a small amount of friction (like 0.05). When you are decelerating, you would be increasing the friction (you're hitting the brakes), but that doesn't change that friction should always be applied.
Yes, in the update() method, you would apply friction and all the other variables.

1  
2  
3  
4  
5  
6  
7  
8  
public void moveCar()
{
    double friction = 0.05;
    car.velocity.x *= (1 - friction);
    car.velocity.y *= (1 - friction);
    car.velocity.x += acceleration.x;
    car.velocity.y += acceleration.y;
}


Don't you mean:
1  
2  
    acceleration.x *= (1 - friction);
    acceleration.y *= (1 - friction);

Cheesy
No, I don't, that wouldn't work. Friction does not affect the acceleration applied by the engine, friction is a separate source of force, so it affects velocity. http://en.wikipedia.org/wiki/Friction

Also just thinking purely in a "what will work" approach, if you are constantly reducing the acceleration then the vehicle will still never stop, because nothing is curbing the velocity.
Would friction affect the acceleration, which in turn would be added to the velocity?
Or am I so sleepy that I am misunderstanding this whole thing? Cheesy

Offline deadly72

Junior Devvie





« Reply #18 - Posted 2011-02-23 04:04:01 »

I'm starting to think I did it the wrong way since I'm not using vectors... adding the friction messes it up if I multiply it instead of subtracting it.  I don't understand what is wrong.

Would you mind explaining what isn't correct about having these two functions?
1  
2  
3  
4  
5  
6  
private void move() {   
    double ax = Math.sin(Math.toRadians(carAngle)) * currentSpeed;
    double ay = Math.cos(Math.toRadians(carAngle)) * currentSpeed * -1;
    x += ax;
    y += ay;
}


and

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
public void update(int deltaTime) {
   if ((Map.getGameArea().contains(getBounds()))) {
      if (Math.round(currentSpeed) > 0) {
         if (slowdown)
            currentSpeed -= .1;
         
         move();
      }
      if (Math.round(currentSpeed) < 0) {
         if (slowdown)
                 currentSpeed += .1;
           
         move();
      }
   }
        ...


I know using Math.round(currentSpeed) is probably not the smartest thing, but its what halts my vehicle once the speed gets near 0.  In addition, what would be the proper way of implementing friction, should I change to use vectors? I'm sure that would simplify the process, but would that work without using a grid?
Offline ra4king

JGO Kernel


Medals: 356
Projects: 3
Exp: 5 years


I'm the King!


« Reply #19 - Posted 2011-02-23 05:38:40 »

1. Do you only call move() when you start slowing down?
2. Friction is best implemented by taking a tiny percentage off the currentSpeed, eg. currentSpeed *= 0.95;
3. Let us focus on what is malfunctioning. Is the rotation still not working?

Offline deadly72

Junior Devvie





« Reply #20 - Posted 2011-02-23 07:07:20 »

1. Do you only call move() when you start slowing down?

No, move is called when currentSpeed > 0 or < 0

Quote
2. Friction is best implemented by taking a tiny percentage off the currentSpeed, eg. currentSpeed *= 0.95;

Implementing this makes my coordinates go 'wako'.

Quote
3. Let us focus on what is malfunctioning. Is the rotation still not working?

Rotation is functioning but is 'choppy' as I stated earlier.  I would have thought there would be a better way then trial and error, but the rotation really doesn't feel smooth.  And well reverse is fixed but like I said, I'm sure there is a better way for doing it instead of rounding currentSpeed.
Offline ra4king

JGO Kernel


Medals: 356
Projects: 3
Exp: 5 years


I'm the King!


« Reply #21 - Posted 2011-02-23 07:14:28 »

1. Do you only call move() when you start slowing down?

No, move is called when currentSpeed > 0 or < 0
Oh yes that's what I meant Tongue
I was wondering if the calls to move() you showed us are the only ones or not.

Quote
2. Friction is best implemented by taking a tiny percentage off the currentSpeed, eg. currentSpeed *= 0.95;

Implementing this makes my coordinates go 'wako'.
How does this make your coordinates go 'wako'? Tongue

Quote
3. Let us focus on what is malfunctioning. Is the rotation still not working?

Rotation is functioning but is 'choppy' as I stated earlier.  I would have thought there would be a better way then trial and error, but the rotation really doesn't feel smooth.  And well reverse is fixed but like I said, I'm sure there is a better way for doing it instead of rounding currentSpeed.
There really is no reason to round. If the car is not moving then the currentSpeed == 0. If the speed is between 0.0 and 0.5, your code will interpret that as stationary when you're actually moving.

I also just noticed: Why do you subtract 1 from the ay after the Math.cos()?

Offline deadly72

Junior Devvie





« Reply #22 - Posted 2011-02-23 07:41:24 »

1. Yup move is only called within the update function, as this is the only class which has everything to do with the car.

2. If I change the move method to integrate friction as Eli Delventhal mentioned giving
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
private void move() {   
       
    x *= (1-friction);
    y *= (1-friction);
     
    double ax = Math.sin(Math.toRadians(carAngle)) * currentSpeed;
    double ay = Math.cos(Math.toRadians(carAngle)) * currentSpeed * -1;
    x += ax;
    y += ay;

    x = Math.abs(x) < 0.01 ? 0 : x;
    y = Math.abs(y) < 0.01 ? 0 : y;
}

then the x and y coordinates seem to radically shift in one update loop.  I don't know if you understand what I mean, but I can post my whole class here if need be to illustrate? what is actually happening when I use friction.  Note that it's very possible I'm the one messing something up, since my math skills aren't exactly up to par.  Grin

As for not rounding... I know in a normal situation you probably wouldn't need to, but if I consider not rounding inside my update function, the car still travels with minimal speed whether it be in forward or in reverse.  Undecided

And I multiply* but -1 so that my y coordinate travels in the proper direction, instead of going backwards (or in a car someone might think of it as going in reverse)
Offline Bonbon-Chan

JGO Coder


Medals: 12



« Reply #23 - Posted 2011-02-23 07:56:05 »

If you want, take a look to "Google Map Race". It is a full top-down race prototype game in java 2d with sources. It can give you ideas.
Offline ra4king

JGO Kernel


Medals: 356
Projects: 3
Exp: 5 years


I'm the King!


« Reply #24 - Posted 2011-02-23 08:48:12 »

1. Yup move is only called within the update function, as this is the only class which has everything to do with the car.

2. If I change the move method to integrate friction as Eli Delventhal mentioned giving
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
private void move() {   
       
    x *= (1-friction);
    y *= (1-friction);
     
    double ax = Math.sin(Math.toRadians(carAngle)) * currentSpeed;
    double ay = Math.cos(Math.toRadians(carAngle)) * currentSpeed * -1;
    x += ax;
    y += ay;

    x = Math.abs(x) < 0.01 ? 0 : x;
    y = Math.abs(y) < 0.01 ? 0 : y;
}

then the x and y coordinates seem to radically shift in one update loop.  I don't know if you understand what I mean, but I can post my whole class here if need be to illustrate? what is actually happening when I use friction.  Note that it's very possible I'm the one messing something up, since my math skills aren't exactly up to par.  Grin
I still don't understand why you would apply the friction to the x and y! Friction is applied to acceleration! Grin

And I multiply* but -1 so that my y coordinate travels in the proper direction, instead of going backwards (or in a car someone might think of it as going in reverse)
I should get some sleep cause my eyes can't see properly Tongue

Offline dishmoth
« Reply #25 - Posted 2011-02-23 10:04:19 »

2. If I change the move method to integrate friction as Eli Delventhal mentioned giving
1  
2  
    x *= (1-friction);
    y *= (1-friction);
Eli suggested doing that to the velocity, not the position (or the acceleration).

I think there are two problems which might explain your choppy rotation.  First, you should just use the keyPressed()/keyReleased() functions to set/clear boolean variables leftPressed, upPressed, etc.  Never put code that updates game objects in those functions.  Move your 'maths' code into the move()/update() functions instead, and make it use leftPressed, etc.

Second, you've got a value deltaTime that you're not using.  I'm assuming from that that your game loop uses variable time steps, i.e., the time between calls to update() may be different each time.  (You could try printing out the value of deltaTime to check this.)  If so, you will need to multiply speeds and accelerations by (something proportional to) deltaTime to compensate.  For example, if the car is moving at one metre per second, but the time between calls to update() is sometimes one second, sometimes ten seconds, you can see that the amount you need to move the car isn't simply equal to the current speed.

Simon

Offline Eli Delventhal

JGO Kernel


Medals: 42
Projects: 11
Exp: 10 years


Game Engineer


« Reply #26 - Posted 2011-02-23 16:12:55 »

I'm starting to think I did it the wrong way since I'm not using vectors... adding the friction messes it up if I multiply it instead of subtracting it.  I don't understand what is wrong.

Would you mind explaining what isn't correct about having these two functions?
1  
2  
3  
4  
5  
6  
private void move() {   
    double ax = Math.sin(Math.toRadians(carAngle)) * currentSpeed;
    double ay = Math.cos(Math.toRadians(carAngle)) * currentSpeed * -1;
    x += ax;
    y += ay;
}


and

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
public void update(int deltaTime) {
   if ((Map.getGameArea().contains(getBounds()))) {
      if (Math.round(currentSpeed) > 0) {
         if (slowdown)
            currentSpeed -= .1;
         
         move();
      }
      if (Math.round(currentSpeed) < 0) {
         if (slowdown)
                 currentSpeed += .1;
           
         move();
      }
   }
        ...


I know using Math.round(currentSpeed) is probably not the smartest thing, but its what halts my vehicle once the speed gets near 0.  In addition, what would be the proper way of implementing friction, should I change to use vectors? I'm sure that would simplify the process, but would that work without using a grid?

You are essentially using vectors split out into components, that's fine. You don't want to add or subtract .1, you want to multiply by 0.9 or 0.95.

And friction is not applied to acceleration, it's a separate force upon the object, so you apply it to the closest thing we have to cumulative force - velocity. Force is just velocity times mass, so we're merely taking mass out of the picture as it's rarely needed for simpler physics simulations like this. The car's acceleration from its engine and the friction applied from the ground are separate forces (aka separate changes in velocity) so they are applied separately.

dishmoth has all good points, definitely try to implement what he's talking about.

See my work:
OTC Software
Offline ra4king

JGO Kernel


Medals: 356
Projects: 3
Exp: 5 years


I'm the King!


« Reply #27 - Posted 2011-02-23 18:11:46 »

Yeah, for some reason I always interchange acceleration and velocity.
In my mind, I am visualizing the car's velocity with 2 forces on it: acceleration and friction.

And multiplying the velocity by 0.9 or 0.95 instead of adding or subtract 0.1 is exponential, which is the closest to real life, rather than linear.

dishmoth's ideas are the norm today, since I use them and I'm sure others do too.

Offline deadly72

Junior Devvie





« Reply #28 - Posted 2011-02-24 01:32:35 »

Alright so I fixed up the code to use 4 booleans for the keys pressed and came out with this.  I know the proportion isn't included because I'm not sure to go about it.  If anyone code share some thoughts on it I'd appreciate it!  Smiley
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  
private void move(int deltaTime) {
   acceleration = .1;
   friction = 0.03;
   seconds += (deltaTime / 1000.0);      
     
   if (up) {
      if (currentSpeed < topspeed)
         currentSpeed += acceleration * seconds;
      else
         currentSpeed = topspeed;
   }
     
   if (down) {
      if (currentSpeed > -3)
         currentSpeed -= acceleration * seconds;
   }
     
   if (right) {
      carAngle += rotationStep * (currentSpeed/topspeed);
      currentSpeed -= .02;
   }
     
   if (left) {
      carAngle -= rotationStep * (currentSpeed/topspeed);
      currentSpeed -= .02;
   }
     
   currentSpeed *= (1-friction);
        currentSpeed = Math.abs(currentSpeed) < 0.03 ? 0 : currentSpeed;
       
   double ax = Math.sin(Math.toRadians(carAngle)) * currentSpeed;
        double ay = Math.cos(Math.toRadians(carAngle)) * currentSpeed * -1;
       
        x += ax;
        y += ay;

}
Offline ra4king

JGO Kernel


Medals: 356
Projects: 3
Exp: 5 years


I'm the King!


« Reply #29 - Posted 2011-02-24 02:07:21 »

That whole thing with the seconds variable looks weird.
Multiplying acceleration (0.1) with seconds (which is likely to be less than 1) is going to output an even smaller number, causing your acceleration to be tiny.

deltaTime is the difference of time between the last iteration and this iteration of the call to move().
You should be checking to see if the deltaTime is different from the actual deltaTime you want, eg, 60 times a second or 16-17 milliseconds (preferably 16,667 nanoseconds)
Then have a scale variable to adjust accordingly.

1  
2  
3  
4  
5  
double scale = (deltaTime/16667);
....
currentSpeed += acceleration*scale;
...
currentSpeed -= acceleration*scale;

Pages: [1] 2 3
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

rwatson462 (35 views)
2014-12-15 09:26:44

Mr.CodeIt (26 views)
2014-12-14 19:50:38

BurntPizza (54 views)
2014-12-09 22:41:13

BurntPizza (87 views)
2014-12-08 04:46:31

JscottyBieshaar (49 views)
2014-12-05 12:39:02

SHC (64 views)
2014-12-03 16:27:13

CopyableCougar4 (67 views)
2014-11-29 21:32:03

toopeicgaming1999 (127 views)
2014-11-26 15:22:04

toopeicgaming1999 (118 views)
2014-11-26 15:20:36

toopeicgaming1999 (34 views)
2014-11-26 15:20:08
Resources for WIP games
by kpars
2014-12-18 10:26:14

Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50
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!