Jump to content

  • Log In with Google      Sign In   
  • Create Account


#ActualKhatharr

Posted 07 January 2013 - 02:12 AM

I suspect that something is going on in the same place where you suspect that something is going on. I will mention in passing that the organization here is a bit choppy. You may want to sit down with a pen and paper and try to rethink how your objects are organized (vectors should not do math, you should do math on them), but I don't think that's what's causing lag here, so let's fix the bug first.

Let's see here...
int VelocityVector::xMove() {
  //wow, that's a lot of precision... Is it _really_ necessary to use a double here?
  double displacement;

  //what's going on here?
  displacement = (0.0 + timy.get_ticks());
  //and here?
  displacement /= (0.0 + 1000);

  //assuming 'speed' is some scalar, is its value sane at this point?
  displacement *= speed;

  //please don't use function-style casts. it frightens the children.
  displacement *= cos(double(angle));

  return (int)displacement;
}

int VelocityVector::yMove() {
  //floats are faster than doubles and I don't reckon we really need super-huge precision here
  float displacement = sin(angle);
  displacement *= speed;
  //hey, are we sure that timy hasn't advanced at all since the time when xMove() was called?
  displacement *= timy.get_ticks();

  //If you're concerned about precision:
  //when doing serial scalar operations (multiply and divide)
  //try to do division last to preserve precision for free:
  //(division reduces precision; multiplication amplifies inaccuracy,
  //so put the loss at the end to avoid amplifying it)
  //[note - this is not the problem in this case, just general advice]
  displacement /= 1000;

  ///////
  timy.start(); //HEY, WHERE'D THIS GUY COME FROM?!?
  ///////

  return (int)displacement;
}
We've got a couple problems. Firstly with that 'timy' fella. (He's always trouble.) From where I'm sitting it looks like any time 'timy' fails to get the necessary number of ticks you'll accomplish no movement whatsoever. Instead of telling 'timy' to 'start' (I'm assuming that means 'restart') every frame you should:
  • control 'timy' from outside the move functions
  • let 'timy' run continuously without restarting
  • at the start of a frame save your existing 'curTime' as 'prevTime', then capture 'timy' into 'curTime'
  • pass 'curTime' - 'prevTime' into the move functions to tell them how much time has passed
int curTime;
int prevTime;
int deltaTime;

prevTime = curTime;
curTime = timy.get_ticks();
deltaTime = curTime - prevTime;

float VelocityVector::xMove(int dTime) {
  float displacement = cos(angle); //normalized motion
  displacement *= speed; //scale for speed
  displacement = (displacement * dTime) / 1000; //scale for time delta
  return displacement;
}

void Object::move() {
  //I get that setXY() may be changing more than one thing,
  //but why do you need to call getXY() here instead of
  //referring to the members directly?
  setX(getX() + velo->xMove(deltaTime));
  setY(getY() + velo->yMove(deltaTime));
}
That will correct the skew in your angle because you'll be passing the same time difference to all functions that need it.

But the main concern is that when you use integer coordinates but want higher-than-integer precision you must store the coordinates in the higher precision type and then cast them to lower precision only when you need to. In other words, store x and y as floats and then just cast them as ints when you pass them to a function requiring ints. This way you don't end up with a situation like this where you don't actually move most of the time since 'timy' can't work up enough ticks to move a full pixel-width (since the move functions return int you completely lose that partial movement!).
float x;
float y;

//do all math and adjustment with x and y as floats

//only cast to int at the last possible moment:
SDL_Rect offset = {(int)x, (int)y, 0, 0};
SDL_BlitSurface(source, NULL, destination, &offset);
Always store values in the highest precision they need and then downcast only when needed. This prevents losing precision due to downcasting. Don't think of casting as a conversion. Think of it as a disguise. ph34r.png

#21Khatharr

Posted 07 January 2013 - 02:08 AM

I suspect that something is going on in the same place where you suspect that something is going on. I will mention in passing that the organization here is a bit choppy. You may want to sit down with a pen and paper and try to rethink how your objects are organized (vectors should not do math, you should do math on them), but I don't think that's what's causing lag here, so let's fix the bug first.

Let's see here...
int VelocityVector::xMove() {
  //wow, that's a lot of precision... Is it _really_ necessary to use a double here?
  double displacement;

  //what's going on here?
  displacement = (0.0 + timy.get_ticks());
  //and here?
  displacement /= (0.0 + 1000);

  //assuming 'speed' is some scalar, is its value sane at this point?
  displacement *= speed;

  //please don't use function-style casts. it frightens the children.
  displacement *= cos(double(angle));

  return (int)displacement;
}

int VelocityVector::yMove() {
  //floats are faster than doubles and I don't reckon we really need super-huge precision here
  float displacement = sin(angle);
  displacement *= speed;
  //hey, are we sure that timy hasn't advanced at all since the time when xMove() was called?
  displacement *= timy.get_ticks();

  //If you're concerned about precision:
  //when doing serial scalar operations (multiply and divide)
  //try to do division last to preserve precision for free:
  //(division reduces precision; multiplication amplifies inaccuracy,
  //so put the loss at the end to avoid amplifying it)
  //[note - this is not the problem in this case, just general advice]
  displacement /= 1000;

  ///////
  timy.start(); //HEY, WHERE'D THIS GUY COME FROM?!?
  ///////

  return (int)displacement;
}
We've got a couple problems. Firstly with that 'timy' fella. (He's always trouble.) From where I'm sitting it looks like any time 'timy' fails to get the necessary number of ticks you'll accomplish no movement whatsoever. Instead of telling 'timy' to 'start' (I'm assuming that means 'restart') every frame you should:
  • control 'timy' from outside the move functions
  • let 'timy' run continuously without restarting
  • at the start of a frame save your existing 'curTime' as 'prevTime', then capture 'timy' into 'curTime'
  • pass 'curTime - 'prevTime' into the move functions to tell them how much time has passed
int curTime;
int prevTime;
int deltaTime;

prevTime = curTime;
curTime = timy.get_ticks();
deltaTime = curTime - prevTime;

float VelocityVector::xMove() {
  float displacement = cos(angle); //normalized motion
  displacement *= speed; //scale for speed
  displacement = (displacement * deltaTime) / 1000; //scale for time delta
  return displacement;
}
That will correct the skew in your angle because you'll be passing the same time difference to all functions that need it.

But the main concern is that when you use integer coordinates but want higher-than-integer precision you must store the coordinates in the higher precision type and then cast them to lower precision only when you need to. In other words, store x and y as floats and then just cast them as ints when you pass them to a function requiring ints. This way you don't end up with a situation like this where you don't actually move most of the time since 'timy' can't work up enough ticks to move a full pixel-width (since the move functions return int you completely lose that partial movement!).
float x;
float y;

//do all math and adjustment with x and y as floats

//only cast to int at the last possible moment:
SDL_Rect offset = {(int)x, (int)y, 0, 0};
SDL_BlitSurface(source, NULL, destination, &offset);
Always store values in the highest precision they need and then downcast only when needed. This prevents losing precision due to downcasting. Don't think of casting as a conversion. Think of it as a disguise. ph34r.png

#20Khatharr

Posted 07 January 2013 - 02:05 AM

I suspect that something is going on in the same place where you suspect that something is going on. I will mention in passing that the organization here is a bit choppy. You may want to sit down with a pen and paper and try to rethink how your objects are organized (vectors should not do math, you should do math on them), but I don't think that's what's causing lag here, so let's fix the bug first.<br /><br />Let's see here...<pre class="_prettyXprint _lang-code _linenums:0">int VelocityVector::xMove() {
//wow, that's a lot of precision for something like this... Is it _really_ necessary to use a double here?
double displacement;

//what's going on here?
displacement = (0.0 + timy.get_ticks());
//and here?
displacement /= (0.0 + 1000);

//assuming 'speed' is some scalar, is its value sane at this point?
displacement *= speed;

//does angle _really_ need to be a double here?
//please don't use function-style casts. it frightens the children.
displacement *= cos(double(angle));

return (int)displacement;
}

int VelocityVector::yMove() {
//floats are a lot faster than doubles and I don't reckon we really need super-huge precision here
float displacement = sin(angle);
displacement *= speed;
//hey, are we sure that timy hasn't advanced at all since the time when xMove() was called?
displacement *= timy.get_ticks();

//If you're concerned about precision:
//when doing serial scalar operations (multiply and divide)
//try to do division last to preserve precision for free:
//(division reduces precision; multiplication amplifies inaccuracy,
//so put the loss at the end to avoid amplifying it)
//[note - this is not the problem in this case, just general advice]
displacement /= 1000;

///////
timy.start(); //HEY, WHERE'D THIS GUY COME FROM?!?
///////

return (int)displacement;
}</pre><br />We've got a couple problems, firstly with that 'timy' fella. (He's always trouble.) From where I'm sitting it looks like any time 'timy' fails to get the necessary number of ticks you'll accomplish no movement whatsoever (since you seem to be using integer coordinates). I don't know what 'timy' is up to on his free time though, so I could be wrong. Maybe if instead of telling 'timy' to 'start' (I'm assuming that means 'restart') every frame you should:<ul class="bbc"><li>control 'timy' from outside the move functions</li><li>let 'timy' run continuously without restarting</li><li>at the start of a frame save your existing 'curTime' as 'prevTime', then capture 'timy' into 'curTime'</li><li>pass 'curTime - 'prevTime' into the move functions to tell them how much time has passed</li></ul><pre class="_prettyXprint _lang-code _linenums:NaN">int curTime;
int prevTime;
int deltaTime;

prevTime = curTime;
curTime = timy.get_ticks();
deltaTime = curTime - prevTime;

float VelocityVector::xMove() {
float displacement = cos(angle); //normalized motion
displacement *= speed; //scale for speed
displacement = (displacement * deltaTime) / 1000; //scale for time delta
return displacement;
}</pre><br />That will correct the skew in your angle because you'll be passing the same time difference to all functions that need it.<br /><br />But the main concern is that when you use integer coordinates but want higher-than-integer precision you must store the coordinates in the higher precision type and then cast them to lower precision only when you need to. In other words, store x and y as floats and then just cast them as ints when you pass them to a function requiring ints. This way you don't end up with a situation like this where you don't actually move most of the time since 'timy' can't work up enough ticks to move a full pixel-width (since the move functions return int you completely lose that partial movement!).<br /><pre class="_prettyXprint _lang-code _linenums:0">float x;
float y;

//do all math and adjustment with x and y as floats

//only cast to int at the last possible moment:
SDL_Rect offset = {(int)x, (int)y, 0, 0};
SDL_BlitSurface(source, NULL, destination, &amp;offset);</pre><br />Always store values in the highest precision they need and then downcast only when needed. This prevents losing precision due to downcasting. Don't think of casting as a conversion. Think of it as a disguise. <img data-cke-saved-src="http://public.gamedev.net//public/style_emoticons/default/smile.png" src="http://public.gamedev.net//public/style_emoticons/default/smile.png" class="bbc_emoticon" title=":)" />

#19Khatharr

Posted 07 January 2013 - 01:49 AM

I suspect that something is going on in the same place where you suspect that something is going on. I will mention in passing that the organization here is a bit choppy. You may want to sit down with a pen and paper and try to rethink how your objects are organized (vectors should not do math, you should do math on them), but I don't think that's what's causing lag here, so let's fix the bug first.

Let's see here...
int VelocityVector::xMove() {
  //wow, that's a lot of precision for something like this... Is it _really_ necessary to use a double here?
  double displacement;

  //what's going on here?
  displacement = (0.0 + timy.get_ticks());
  //and here?
  displacement /= (0.0 + 1000);

  //assuming 'speed' is some scalar, is its value sane at this point?
  displacement *= speed;

  //does angle _really_ need to be a double here?
  //please don't use function-style casts. it frightens the children.
  displacement *= cos(double(angle));

  return (int)displacement;
}

int VelocityVector::yMove() {
  //floats are a lot faster than doubles and I don't reckon we really need super-huge precision here
  float displacement = sin(angle);
  displacement *= speed;
  //hey, are we sure that timy hasn't advanced at all since the time when xMove() was called?
  displacement *= timy.get_ticks();

  //If you're concerned about precision:
  //when doing serial scalar operations (multiply and divide)
  //try to do division last to preserve precision for free:
  //(division reduces precision; multiplication amplifies inaccuracy,
  //so put the loss at the end to avoid amplifying it)
  //[note - this is not the problem in this case, just general advice]
  displacement /= 1000;

  ///////
  timy.start(); //HEY, WHERE'D THIS GUY COME FROM?!?
  ///////

  return (int)displacement;
}

We've got a couple problems, firstly with that 'timy' fella. (He's always trouble.) From where I'm sitting it looks like any time 'timy' fails to get the necessary number of ticks you'll accomplish no movement whatsoever (since you seem to be using integer coordinates). I don't know what 'timy' is up to on his free time though, so I could be wrong. Maybe if instead of telling 'timy' to 'start' (I'm assuming that means 'restart') every frame you should:
  • control 'timy' from outside the move functions
  • let 'timy' run continuously without restarting
  • at the start of a frame save your existing 'curTime' as 'prevTime', then capture 'timy' into 'curTime'
  • pass 'curTime - 'prevTime' into the move functions to tell them how much time has passed
But the main concern is that when you use integer coordinates but want higher-than-integer precision then store the coordinates in the higher precision type and then cast them to lower precision only when you need to. In other words, store x and y as floats and then just cast them as ints when you pass them to a function requiring ints. This way you don't end up with a situation like this where you don't actually move most of the time since 'timy' can't work up enough ticks to move a full pixel-width (since the move functions return int you completely lose that partial movement!).

Example:
float x;
float y;

//do all math and adjustment with x and y as floats

//only cast to int at the last possible moment:
SDL_Rect offset = {(int)x, (int)y, 0, 0};
SDL_BlitSurface(source, NULL, destination, &offset);

#18Khatharr

Posted 07 January 2013 - 01:45 AM

I suspect that something is going on in the same place where you suspect that something is going on. I will mention in passing that the organization here is a bit choppy. You may want to sit down with a pen and paper and try to rethink how your objects are organized, but I don't think that's what's causing lag here, so let's fix the bug first.

Let's see here...
int VelocityVector::xMove() {
  //wow, that's a lot of precision for something like this... Is it _really_ necessary to use a double here?
  double displacement;

  //what's going on here?
  displacement = (0.0 + timy.get_ticks());
  //and here?
  displacement /= (0.0 + 1000);

  //assuming 'speed' is some scalar, is its value sane at this point?
  displacement *= speed;

  //does angle _really_ need to be a double here?
  //please don't use function-style casts. it frightens the children.
  displacement *= cos(double(angle));

  return (int)displacement;
}

int VelocityVector::yMove() {
  //floats are a lot faster than doubles and I don't reckon we really need super-huge precision here
  float displacement = sin(angle);
  displacement *= speed;
  //hey, are we sure that timy hasn't advanced at all since the time when xMove() was called?
  displacement *= timy.get_ticks();

  //If you're concerned about precision:
  //when doing serial scalar operations (multiply and divide)
  //try to do division last to preserve precision for free:
  //(division reduces precision; multiplication amplifies inaccuracy,
  //so put the loss at the end to avoid amplifying it)
  //[note - this is not the problem in this case, just general advice]
  displacement /= 1000;

  ///////
  timy.start(); //HEY, WHERE'D THIS GUY COME FROM?!?
  ///////

  return (int)displacement;
}

We've got a couple problems, firstly with that 'timy' fella. (He's always trouble.) From where I'm sitting it looks like any time 'timy' fails to get the necessary number of ticks you'll accomplish no movement whatsoever (since you seem to be using integer coordinates). I don't know what 'timy' is up to on his free time though, so I could be wrong. Maybe if instead of telling 'timy' to 'start' (I'm assuming that means 'restart') every frame you should:
  • control 'timy' from outside the move functions
  • let 'timy' run continuously without restarting
  • at the start of a frame save your existing 'curTime' as 'prevTime', then capture 'timy' into 'curTime'
  • pass 'curTime - 'prevTime' into the move functions to tell them how much time has passed
But the main concern is that when you use integer coordinates but want higher-than-integer precision then store the coordinates in the higher precision type and then cast them to lower precision only when you need to. In other words, store x and y as floats and then just cast them as ints when you pass them to a function requiring ints. This way you don't end up with a situation like this where you don't actually move most of the time since 'timy' can't work up enough ticks to move a full pixel-width (since the move functions return int you completely lose that partial movement!).

Example:
float x;
float y;

//do all math and adjustment with x and y as floats

//only cast to int at the last possible moment:
SDL_Rect offset = {(int)x, (int)y, 0, 0};
SDL_BlitSurface(source, NULL, destination, &offset);

#17Khatharr

Posted 07 January 2013 - 01:44 AM

I suspect that something is going on in the same place where you suspect that something is going on. I will mention in passing that the organization here is a bit choppy. You may want to sit down with a pen and paper and try to rethink how your objects are organized, but I don't think that's what's causing lag here, so let's fix the bug first.

Let's see here...
int VelocityVector::xMove() {
  //wow, that's a lot of precision for something like this... Is it _really_ necessary to use a double here?
  double displacement;

  //what's going on here?
  displacement = (0.0 + timy.get_ticks());
  //and here?
  displacement /= (0.0 + 1000);

  //assuming 'speed' is some scalar, is its value sane at this point?
  displacement *= speed;

  //does angle _really_ need to be a double here?
  //please don't use function-style casts. it frightens the children.
  displacement *= cos(double(angle));

  return (int)displacement;
}

int VelocityVector::yMove() {
  //floats are a lot faster than doubles and I don't reckon we really need super-huge precision here
  float displacement = sin(angle);
  displacement *= speed;
  displacement *= timy.get_ticks();

  //If you're concerned about precision:
  //when doing serial scalar operations (multiply and divide)
  //try to do division last to preserve precision for free:
  //(division reduces precision; multiplication amplifies inaccuracy,
  //so put the loss at the end to avoid amplifying it)
  //[note - this is not the problem in this case, just general advice]
  displacement /= 1000;

  ///////
  timy.start(); //HEY, WHERE'D THIS GUY COME FROM?!?
  ///////

  return (int)displacement;
}

We've got a couple problems, firstly with that 'timy' fella. (He's always trouble.) From where I'm sitting it looks like any time 'timy' fails to get the necessary number of ticks you'll accomplish no movement whatsoever (since you seem to be using integer coordinates). I don't know what 'timy' is up to on his free time though, so I could be wrong. Maybe if instead of telling 'timy' to 'start' (I'm assuming that means 'restart') every frame you should:
  • control 'timy' from outside the move functions
  • let 'timy' run continuously without restarting
  • at the start of a frame save your existing 'curTime' as 'prevTime', then capture 'timy' into 'curTime'
  • pass 'curTime - 'prevTime' into the move functions to tell them how much time has passed
But the main concern is that when you use integer coordinates but want higher-than-integer precision then store the coordinates in the higher precision type and then cast them to lower precision only when you need to. In other words, store x and y as floats and then just cast them as ints when you pass them to a function requiring ints. This way you don't end up with a situation like this where you don't actually move most of the time since 'timy' can't work up enough ticks to move a full pixel-width (since the move functions return int you completely lose that partial movement!).

Example:
float x;
float y;

//do all math and adjustment with x and y as floats

//only cast to int at the last possible moment:
SDL_Rect offset = {(int)x, (int)y, 0, 0};
SDL_BlitSurface(source, NULL, destination, &offset);

PARTNERS