Eiffer
|
|
« 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
|
|
« 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: 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
|
|
« 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
|
|
« 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
|
|
« 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
|
|
« 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
|
|
« 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
|
|
« 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
|
|
« 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? 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
|
|
« 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
|
|
« 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: 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
|
|
« 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
|
|
« 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
|
|
« 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
|
|
« 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
|
|
« 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
|
|
« 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
|
|
« 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
|
|
|
|
|