Welcome, Guest. Please login or register.

Author Topic: Moving a sprite in a specified angle  (Read 6510 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: Moving a sprite in a specified angle
« on: August 27, 2007, 08:42:51 PM »
Two possible approaches:

1) Use component velocities (velocities in X and Y axes). You can work this out from taking the sine and cosine of the angle and using them to factor your sprite's overall speed into the vX and vY components (which will allow you to position the sprite at any time along the trajectory).

2) Use a bresenham style line drawing algorithm to calculate your sprite position over successive iterations. This is only really useful if your sprite moves a fixed distance every frame.

Since you know how to move the sprite in X and Y, you could use either of the above. I'd go for (1) myself.
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: Moving a sprite in a specified angle
« Reply #1 on: August 27, 2007, 09:33:07 PM »
Strange. You're not using threads or anything like that are you?

Incidentally, I had something like this in mind for the components:

vX = sprite->speed*cos(sprite->angle);
vY = sprite->speed*sin(sprite->angle);

ie, you only have speed and angle and calculate vX amd vY as required.

I'd probably go for a basic lookup table or something for the sin/cos too if my angle is an integer with a small enough range. Or cache the cos/sin angle values and recalculate only when angle changes. Or both :lol:
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: Moving a sprite in a specified angle
« Reply #2 on: August 27, 2007, 10:13:23 PM »
Right. I was looking at the if statements and was pretty sure something weird must be happening, but as it worked in the single sprite case and failed in the many sprite case, simple boundary detection didn't seem the obvious cause ;-)
 
With respect to the calculation stuff, it's different in that you have have already separated the velocities into xVel and yVel which you then multiply by the corresponding component factor (cos(angle) / sin(angle) in the respective direction.

Or in English, you already have separate xVel / yVel which you then multiply by the cos/sin, which is quite different from having single speed which is then used to derive xVel / yVel.

In other words, I'm saying:

xVel = speed*cos(angle)

where as you have

xVel*cos(angle)

...what was xVel initialised with?
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: Moving a sprite in a specified angle
« Reply #3 on: August 27, 2007, 10:32:12 PM »
Right.

I'd suggest it's more numerically correct to stick with either totally separate 'vectorized' style xVel / yVel (ie no angle) or have speed and angle and derive xVel/yVel from the speed and angle.

In the latter case, the component velocities xVel and yVel, at any time, will always be:

xVel = speed*cos(angle);
yVel = speed*sin(angle);

which you derive just as you need them. For example, you can say, at any time:

sprite->posX += sprite->speed*cos(sprite->angle);
sprite->posY += sprite->speed*sin(sprite->angle);

to reposition the sprite. As an optimisation, if angle doesn't vary much, I'd consider storing the result of cos(angle) and sin(angle), but not xVel/yVel, eg:

sprite->scaleVelX = cos(sprite->angle);
sprite->scaleVelY = sin(sprite->angle);

...

sprite->posX += sprite->speed*sprite->scaleVelX;
sprite->posY += sprite->speed*sprite->scaleVelY;

I'm obviously not taking edge rebound into consideration here, but you get the general idea.


Having just one speed/angle pair per sprite makes things a bit easier to understand. It also allows you to alter the speed and angle (to simulate acceleration etc) with relative ease. The correct coordinates will always be found by the expressions above for any given value of speed/angle.

Also, unless your sprites always all move with the same speed, you'd want to make the speed/angle properties part of the sprite structure.
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: Moving a sprite in a specified angle
« Reply #4 on: August 27, 2007, 10:58:52 PM »
True, but remember, you could alter the angle instead.
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: Moving a sprite in a specified angle
« Reply #5 on: August 27, 2007, 11:24:46 PM »
Hey, all is fair in love, warfare and game physics ;-)

I remember doing trajectory stuff for objects bouncing over a polygon mesh. Not much fun at all :lol:
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: Moving a sprite in a specified angle
« Reply #6 on: August 27, 2007, 11:41:04 PM »
As sin / cos use doubles and return doubles, that's unlikely. It's more likely that the conversion to whatever type x and y are discards fractional data for results that would otherwise be less than one, giving a zero x or y velocity.

Strange that you are using degrees as an angular measure for sin and cos. I thought it only worked in radians?

Anyway, if you are going for strict x / y velocities and only ever inverting their signs on collision with a wall, you might as well do away with angles except when firing them off initially.

That is to say, each sprite is initialised with

xVel = speed*cos(angle);
yVel = speed*sin(angle);

and then basically the values dont change for the sprite except for sign flipping on hitting a wall.

Avoid narrow angles by only allowing say a 5 degree granularity for the starting angle.
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: Moving a sprite in a specified angle
« Reply #7 on: August 28, 2007, 12:17:24 AM »
C(++) stdlib rand() returns a pseudorandom number between 0 and RAND_MAX, which is implementation defined (from as low as 32767 or as high as (2^32)-1, depending on the implementation).

To convert the output to the range 0 ... N use ((N*rand())/RAND_MAX)
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: Moving a sprite in a specified angle
« Reply #8 on: August 28, 2007, 12:20:15 AM »
Quote

whabang wrote:
My mind hurts...


Wrong forum, really :lol:
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: Moving a sprite in a specified angle
« Reply #9 on: August 28, 2007, 01:28:35 PM »
As I said, you need

(N*rand())/RAND_MAX

What you are doing is this:

N*(rand()/RAND_MAX)

Since you are dealing with integer arithmetic here, you will always get zero for that except in the rare (about 1 in RAND_MAX ;-) ) chance that rand() returns RAND_MAX.

Order of evaluation is very important here. You want to multiply rand() by your scaling factor *before* dividing it, not the other way around.
int p; // A
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16879
  • Country: gb
  • Thanked: 5 times
    • Show all replies
Re: Moving a sprite in a specified angle
« Reply #10 on: August 28, 2007, 07:23:57 PM »
Well, you didn't expect rand() to be actually random did you? ;-)

Unsurprisingly, rand() returns the next number in a series of pseudorandom numbers that are in fact entirely predictable if you know the algorithm in use and the seed that it started with.

Try initialising the random number generator at the start with something reasonably likely to be different each time your program runs. The current system time is a favourite random seed of old.
int p; // A