Actually, what you said about using the elapsed is fairly accurate. If you're familiar with C#, and aren't already doing so, I would highly recommend you look into either XNA or if you're willing to spend a little money, Dark GDK .NET by "TheGameCreators".
Anyway, the idea is that for each game loop, you update any "live" objects using the elapsed time since the last update. "Live" objects being anything that is still considered active and needs updating, (e.g., enemies, players, bullets in mid flight, explosions that are still going off, etc). You determine what the next state, position, health, etc each object should have based on the elapsed time, collisions, damage from fire, etc and then implement that next state. Finally, you then call the draw process for each of these objects, and render them in their new states.
For something like a player shooting, here is something you could do. Note, this is more pseudo code than anything. Hope it gives you an idea.
//Generic Game Class
public class MySweetGame : Game
{
Player _player = new Player(this);
List<Bullet> _bullets = new List<Bullet>();
public List<Bullet> AllBullets()
{
get { return _bullets; }
}
public void Update()
{
//You would obviously need some keyboard/mouse class to determine if a click took place
if(leftMouseButtonClicked)
{
_player.Shoot();
}
//This would be assuming you have an object collection or array to hold all the bullets currently 'live' like the above '_bullets' collection
//This is also assuming elapseGameTime is some built in game time management, like in XNA
foreach(Bullet blt in _bullets)
{
blt.Update(elapsedGameTime);
}
}
}
//Generic Player Class
public class Player()
{
Vector2 _position = new Vector2(0,0);
int _ammunition = 50;
MySweetGame _game;
public Player(MySweetGame game)
{
_game = game;
}
public void Shoot()
{
if(_ammunition > 0){
_game.AllBullets.Add(new Bullet(50, _position));
_ammunition--;
}
}
}
//Generic Bullet Class
public class Bullet()
{
float _metersPerSecond = 0;
Vector2 _position = new Vector2(0, 0);
public Bullet(float metersPerSecond, Vector3 position)
{
_metersPerSecond = metersPerSecond;
_position = position;
}
//Here is the meat you wanted
//We know the speed of the bullet, based on metersPerSecond - which we set when we instantiated this object
//We also know the elapsedGameTime since we last called update
//So if only .25 seconds have passed - we only moved (50 * .25) - and then update our position vector
public void Update(float elapsedGameTime)
{
distanceTraveled = metersPerSecond * elapsedGameTime;
_position.x += distanceTraveled;
}
}