Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411626 Posts in 69391 Topics- by 58447 Members - Latest Member: sinsofsven

May 11, 2024, 10:55:17 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Momentum and acceleration in 2d Shooter
Pages: [1]
Print
Author Topic: Momentum and acceleration in 2d Shooter  (Read 2641 times)
Eiffer
Level 0
**



View Profile
« on: January 16, 2010, 12:38:07 PM »

I'm working on a 2D dual stick shooter and I'm having trouble working out how to do the movement. I want the ship to feel kind of floaty and have momentum. By this I mean if you are moving and let go of the stick it should float a little bit in the direction you were moving and gradually slow down. It should also turn wide and take a second to do a 180 degree turn as the engines fight the momentum.

I made this work fairly well using just vectors like so:

Vector2 speed(the direction the ship is actually going), momentum(self evident), thrust(the direction you want the ship to go)
float maxSpeed(the fastest you want the ship to go), acceleration (value to multiply
the speed vector by to speed the ship up, for this let's say 1.25);

Update Loop
{
     momentum = speed;
     thrust = (vector based on left thumbstick position)
     speed = (thrust + momentum)* acceleration;
     if(speed.Length() > maxSpeed)
     {
          speed = speed.Normalize() * maxSpeed;
     }
}

This seems to work ok except for 3 things:

    1) The way I do acceleration seems really wrong, given that in physics
       speed = mass * acceleration, but this seemed the easiest way to do things
       with vectors and momentum.

    2) The ship doesn't move right when you completely reverse direction. It fights
       momentum and slowly reverses (which is how I want it to move) but the instant
       it starts moving in the correct direction it jumps up to max speed. I realize
       that this is likely due to 1)

    3) For some reason my collision is bouncy, and I think this has to do with the way I
       do movement. I mean that when the ship collides with the screen edges, it moves a 
       little past the edge and then rebounds a few pixels before the edge. This confuses
       me since I use the above formula to calculate the speed vector for the ship, then
       run the collision check using the player position plus the speed vector, then if it
       collides i modify the speed vector by how far the ship overshoots the screen edge.
       
       So if the ship's speed would put the left edge of the screen at X = -5, I subtract
       5 from the X component of the ship's speed and use that final vector to determine
       the character's position on the next frame.

If anyone could suggest a better way to handle this sort of movement I would really appreciate it.

I'm using XNA if that helps at all.
Logged
Tycho Brahe
Level 10
*****

λx.x


View Profile
« Reply #1 on: January 16, 2010, 12:58:33 PM »

ok, coupla things:

1) speed IS NOT mass * accelleration, FORCE = Mass * accelleration.

2) momentum = Mass*Velocity

3) thrust = force = mass*accelleration

Update Loop
{
     momentum = speed;
     thrust = (vector based on left thumbstick position)
     speed = (thrust + momentum)* acceleration;
     if(speed.Length() > maxSpeed)
     {
          speed = speed.Normalize() * maxSpeed;
     }
}

if you want to have it realistic like, try having it more like this:

Code:
Update loop
{
  Force = 1.25
  Mass = mass of the ship
  acceleration = Force/Mass
  speed = speed+ acceleration
  if(speed+acceleration<=maxSpeed)
  {
    speed = speed+acceleration
  }
}

this SHOULD help with about 90% of your problems, for doing edge collisions (assumming vertical and horizontal lines), when colliding the top or bottom, simply times the y component of the speed by -1, when colliding the left or right, times the x component by -1
« Last Edit: January 16, 2010, 01:09:02 PM by 14113 » Logged
Tycho Brahe
Level 10
*****

λx.x


View Profile
« Reply #2 on: January 16, 2010, 01:02:59 PM »

This is somthing I made a while ago, only with accelleration, not force or thrust, utilising the techniques I've got here.

http://www.mediafire.com/file/3jzjamdwy5n/ShockAndAwe version 0.02.zip

However, I'm guessing you want to go for more asteroids style movement, but this can be done using exactly the same techniques, but with a bit of trig for the force and stuff...
« Last Edit: January 16, 2010, 01:08:29 PM by 14113 » Logged
Eiffer
Level 0
**



View Profile
« Reply #3 on: January 16, 2010, 01:18:50 PM »

Thanks. I guess Asteroids is the type of movement I'm going for. I'm still not sure how to do that though. I follow how your loop works if you are moving the ship in a straight line, but how could you use if you are trying to fight momentum where the ship can move in 360 degrees?

Would I be correct in doing something like:

- store the momentum as a vector so that it contains both direction and magnitude
- calculate the magnitude of the ship's movement using your formula
- calculate the direction of the force from the thumbstick
- create a vector for movement in the direction from the thumbstick and of the magnitude from the formula
- add the momentum and movement vectors to get the vector by which to move the ship
Logged
Eiffer
Level 0
**



View Profile
« Reply #4 on: January 16, 2010, 01:21:14 PM »

I keep thinking in vectors because it seems like the simplest way to add forces that have both direction and magnitude. I'm also hoping to find a system that would make it easy to have the ship effected by gravity wells and such.
Logged
Tycho Brahe
Level 10
*****

λx.x


View Profile
« Reply #5 on: January 16, 2010, 01:28:05 PM »

Well, thinking in vectors is probably best, unless your rendering system is using polar coordinates, which i seriously doubt it is.

basically, what it boils down to is:

figure out all the stuff in a line, with an angle at which it is acting.

then use trigonometry to convert this line/angle to an x-component and a y-component

also, its important to stop trying to think about momentum. Its more or less irrelevant except for when you're doing collisions and need to maintain the same energy across the collision.

I'll try to work out some code for you, give me 5 mins and I'll have somthing done...
Logged
Eiffer
Level 0
**



View Profile
« Reply #6 on: January 16, 2010, 01:31:25 PM »

What I mean by momentum is that if the ship is moving up, and suddenly starts trying to move left, it will still be drifting upwards and turn in an arc rather that do an instant 90 degree turn and start moving left.
Logged
Tycho Brahe
Level 10
*****

λx.x


View Profile
« Reply #7 on: January 16, 2010, 01:48:19 PM »

True, but its easier to approximate with speed, forces and acceleration. Believe me, you only need momentum for collisions.
Logged
Eiffer
Level 0
**



View Profile
« Reply #8 on: January 16, 2010, 02:00:30 PM »

Ok I was approaching this the wrong way. I was getting stuck trying to have the ship gradually accelerate to a maximum speed and messing myself up there. How does this look?

Code:
Vector2 speed \\the direction and amount by which to adjust the ship's position
Vector2 momentum \\"drift"
Vector2 thrust \\a vector of length 0-1 from the thumbstick
float maxSpeed; \\the fastest the ship can move

Update{
    speed = thrust + momentum;
    if(speed.Length > maxSpeed)
          speed.Normalize();
          speed *= maxSpeed;
    momentum = speed;
    if(momentum.Length > 0.01)//reduce momentum due to friction/air resistance
       momentum -= momentum * 0.75;
    else
       momentum = Vector2.Zero;

}



Logged
Tycho Brahe
Level 10
*****

λx.x


View Profile
« Reply #9 on: January 16, 2010, 02:07:30 PM »

I think you mean

speed = maxspeed

instead of:

 speed *=maxspeed

apart from that, it looks pretty good.

[EDIT]

sorry, I think you're right actually, normalising makes it equal to one right?
« Last Edit: January 16, 2010, 02:18:18 PM by 14113 » Logged
Tycho Brahe
Level 10
*****

λx.x


View Profile
« Reply #10 on: January 16, 2010, 02:24:32 PM »

hmm, I've dug out the code that I used for the example I showed you, its more or less what you have:
Code:
if(LeftDown ==true){
if(XPlus>-MaxSpeed){
XPlus -= Speed;
}
}
if(RightDown == true){
if(XPlus<MaxSpeed){
XPlus += Speed;
}
}
if(UpDown == true){
if(YPlus<MaxSpeed){
YPlus += Speed;
}
}
if(DownDown == true){
if(YPlus>-MaxSpeed){
YPlus -= Speed;
}
}
//left hittest;
if(XCentre == LeftLimit+HWidth){
XPlus*=-1;
}
if(XCentre < LeftLimit+HWidth){
XPlus = XPlus/InertiaLoss;
XCentre = LeftLimit+HWidth-XPlus;
}
//right hittest
if(XCentre == RightLimit-HWidth){
XPlus*=-1;
}
if(XCentre > RightLimit-HWidth){
XPlus = XPlus/InertiaLoss;
XCentre = RightLimit-HWidth-XPlus;
}
//top hittest
if(YCentre == TopLimit-HWidth){
YPlus*=-1;
}
if(YCentre > TopLimit-HWidth){
YPlus = YPlus/-InertiaLoss;
YCentre = TopLimit-HWidth-YPlus;
}
//bottom hittest
if(YCentre == BottomLimit+HWidth){
YPlus*=-1;
}
if(YCentre < BottomLimit+HWidth){
YPlus = YPlus/-InertiaLoss;
YCentre = BottomLimit+HWidth-YPlus;
}
//
XCentre+=XPlus;
YCentre+=YPlus;


Logged
Eiffer
Level 0
**



View Profile
« Reply #11 on: January 16, 2010, 05:49:47 PM »

I think you mean

speed = maxspeed

instead of:

 speed *=maxspeed

apart from that, it looks pretty good.

[EDIT]

sorry, I think you're right actually, normalising makes it equal to one right?

Yes normalizing a vector gives you a vector with a length of one. So if you multiply a normalized vector by the maximum speed, you will get a vector that is as long as the maximum speed and so will move the player by the max speed.

Thanks for the help.
Logged
Tycho Brahe
Level 10
*****

λx.x


View Profile
« Reply #12 on: January 17, 2010, 04:15:48 AM »

Glad its appreciated, if you have any more trouble with physics stuff though, I reccomend you look at a couple of a-level/as-level physics revision guides, as everything I said was based of a-level and GCSE physics.
Logged
Lon
Level 4
****



View Profile
« Reply #13 on: January 18, 2010, 07:26:01 PM »

By this I mean if you are moving and let go of the stick it should float a little bit in the direction you were moving
This is known as Newtons First Law.  Essentially an object's velocity will not change unless an external force is acted upon this object.

and gradually slow down.
For it to slow down one may want to accelerate this object in the opposite direction of it's velocity.  Someone could have this 'resistance' (like friction or air drag) be dependent on the ships velocity.  For example Drag = -velocity/(drag constant).


It should also turn wide and take a second to do a 180 degree turn as the engines fight the momentum.
In order to make wide turns you could try limiting the angle that your ship may be accelerated by, or perhaps accelerating slowly may be decent, or both.

Glad its appreciated, if you have any more trouble with physics stuff though, I reccomend you look at a couple of a-level/as-level physics revision guides, as everything I said was based of a-level and GCSE physics.

This site may be useful to read up on for Physics: http://www.physicsclassroom.com/Class/, wikipedia is handy too.

Id also recommend using free body diagrams to help with Physics Modeling.  VERY USEFUL!  I can't stress enough in this post how useful they are when solving Physics problems involving multiple forces.

14113 has good advice.  
Calculating momentum really isn't required outside of modeling collisions.  Momentum generally is Mass*velocity.   Its units are usually: (kg*m)/s (mass times length per unit of time).  
I suggest keeping your units consistent.

Anyway, here is a quick, short, free body Diagram I drew.

An important assumption here: mass != 0.

Good luck with all your endeavors Eiffer.

« Last Edit: January 19, 2010, 09:48:01 AM by BigLon » Logged

“We all sorely complain of the shortness of time, and yet have much more than we know what to do with. Our lives are either spent in doing nothing at all, or in doing nothing to the purpose, or in doing nothing that we ought to do..." -Seneca
Tycho Brahe
Level 10
*****

λx.x


View Profile
« Reply #14 on: January 19, 2010, 11:31:56 AM »

Id also recommend using free body diagrams to help with Physics Modeling.  VERY USEFUL!  I can't stress enough in this post how useful they are when solving Physics problems involving multiple forces.

Seconded, even if they don't really help you with the hardcore mathsy side of things, they are an excellent way of getting your head round a problem...the number of times in exams I've sketched out one for a seemingly unsolvable problem only to suddenly have a idea of how to solve it.
Logged
Eiffer
Level 0
**



View Profile
« Reply #15 on: January 19, 2010, 08:28:55 PM »

Wow thanks for all the info. That should help me out a ton. Sad to think how much I've forgotten since Highschool physics.
Logged
Lon
Level 4
****



View Profile
« Reply #16 on: January 19, 2010, 11:20:18 PM »

Wow thanks for all the info. That should help me out a ton. Sad to think how much I've forgotten since Highschool physics.
Tell me about it, I forget so much just from semester to semester.

Glad we could help.
Logged

“We all sorely complain of the shortness of time, and yet have much more than we know what to do with. Our lives are either spent in doing nothing at all, or in doing nothing to the purpose, or in doing nothing that we ought to do..." -Seneca
Tycho Brahe
Level 10
*****

λx.x


View Profile
« Reply #17 on: January 20, 2010, 07:53:57 AM »

Its amazing the amount I forget on a week to week basis, especially if my class is going slow.

anyway, always happy to help.
Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic