Welcome, Guest. Please login or register.

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

Description:

0 Members and 1 Guest are viewing this topic.

Offline motorollinTopic starter

  • Hero Member
  • *****
  • Join Date: Nov 2005
  • Posts: 8669
    • Show only replies by motorollin
Re: Moving a sprite in a specified angle
« Reply #14 from previous page: August 27, 2007, 11:29:13 PM »
Ok this works:

    if ( x <= 20 )
    {
        x=21;
        angle=(180-angle);
    }
    if ( y <= 20 )
    {
        y=21;
        angle=(180-angle)-180;
    }
    if ( x >= 620 )
    {
        x=619;
        angle=(180-angle);
    }
    if ( y >= 440 )
    {
        y=439;
        angle=(180-angle)-180;
    }

    x+=pinwheelspeed*cos(angle);
    y+=pinwheelspeed*sin(angle);




But every so often the sprite hits the wall at an angle which means it can't escape for some reason. It's probably due to the fact that certain angle can't be represented precisely at such a low resolution. I think it might be better to have tables of x and y velocities to give a variety of "angles" rather than trying to calculate actual angles.

--
moto
Code: [Select]
10  IT\'S THE FINAL COUNTDOWN
20  FOR C = 1 TO 2
30     DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NAAAA
40     DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NA-NA-NAAAAA
50  NEXT C
60  NA-NA-NAAAA
70  NA-NA NA-NA-NA-NA-NAAAA NAAA-NAAAAAAAAAAA
80  GOTO 10
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16867
  • Country: gb
  • Thanked: 4 times
    • Show only replies by Karlos
Re: Moving a sprite in a specified angle
« Reply #15 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 motorollinTopic starter

  • Hero Member
  • *****
  • Join Date: Nov 2005
  • Posts: 8669
    • Show only replies by motorollin
Re: Moving a sprite in a specified angle
« Reply #16 on: August 27, 2007, 11:50:16 PM »
Quote
Karlos wrote:
Strange that you are using degrees as an angular measure for sin and cos. I thought it only worked in radians?

Ohhhhh, that could be my mistake - I was treating the result as degrees :roll: However, this seems to work better anyway:

Pinwheel::Pinwheel()
{
...
xVel=4;
yVel-2;
...
}

Pinwheel::move()
{
    if ( x <= 0 )
    {
        x=1;
        xVel = -xVel;
    }
    if ( y <= 0 )
    {
        y=1;
        yVel = -yVel;
    }
    if ( x >= LEVEL_WIDTH-PINWHEEL_WIDTH )
    {
        x=(LEVEL_WIDTH-PINWHEEL_WIDTH)-1;
        xVel = -xVel;
    }
    if ( y >= LEVEL_HEIGHT-PINWHEEL_HEIGHT )
    {
        y=(LEVEL_HEIGHT-PINWHEEL_HEIGHT)-1;
        yVel = -yVel;
    }
   
    x+=xVel;
    y+=yVel;
}



This works perfectly even with 1000 pinwheels on screen. Only problem is, when I tried changing the values of xVel and yVel to "rand() % 10 + 2" to make them a random number, the pinwheels all moved in the same direction every time. Did I get the rand() syntax wrong?

--
moto
Code: [Select]
10  IT\'S THE FINAL COUNTDOWN
20  FOR C = 1 TO 2
30     DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NAAAA
40     DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NA-NA-NAAAAA
50  NEXT C
60  NA-NA-NAAAA
70  NA-NA NA-NA-NA-NA-NAAAA NAAA-NAAAAAAAAAAA
80  GOTO 10
 

Offline whabang

  • Hero Member
  • *****
  • Join Date: Mar 2002
  • Posts: 7270
    • Show only replies by whabang
Re: Moving a sprite in a specified angle
« Reply #17 on: August 28, 2007, 12:03:45 AM »
My mind hurts...
Beating the dead horse since 2002.
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16867
  • Country: gb
  • Thanked: 4 times
    • Show only replies by Karlos
Re: Moving a sprite in a specified angle
« Reply #18 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: 16867
  • Country: gb
  • Thanked: 4 times
    • Show only replies by Karlos
Re: Moving a sprite in a specified angle
« Reply #19 on: August 28, 2007, 12:20:15 AM »
Quote

whabang wrote:
My mind hurts...


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

Offline motorollinTopic starter

  • Hero Member
  • *****
  • Join Date: Nov 2005
  • Posts: 8669
    • Show only replies by motorollin
Re: Moving a sprite in a specified angle
« Reply #20 on: August 28, 2007, 08:00:34 AM »
Hmmm, it doesn't work...

int xv=(3*(rand()/RAND_MAX))+1;
int yv=(3*(rand()/RAND_MAX))+1;
int r=1*(rand()/RAND_MAX);
if ( r == 1 ) xv = -xv;
r=1*(rand()/RAND_MAX);
if ( r == 1 ) yv = -yv;
xVel=xv;
yVel=yv;

Lines 1 and 2 should (I think) generate two random numbers between 1 and 4 inclusive. Lines 3-6 then give each velocity a 50/50 chance of becoming negative (IOW the sprite has a 50/50 chance of having its direction reversed in each axis). Lines 7 and 8 obviously then assign the result to the velocities.

When I run this over and over again, the sprite always moves in the same direction. I then added "if ( xv == 1 && yv == 1 ) quit=true;", and my game quits every single time. That suggests to me that the result of the rand() functions are always returning 0 :-?

--
moto
Code: [Select]
10  IT\'S THE FINAL COUNTDOWN
20  FOR C = 1 TO 2
30     DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NAAAA
40     DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NA-NA-NAAAAA
50  NEXT C
60  NA-NA-NAAAA
70  NA-NA NA-NA-NA-NA-NAAAA NAAA-NAAAAAAAAAAA
80  GOTO 10
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16867
  • Country: gb
  • Thanked: 4 times
    • Show only replies by Karlos
Re: Moving a sprite in a specified angle
« Reply #21 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 motorollinTopic starter

  • Hero Member
  • *****
  • Join Date: Nov 2005
  • Posts: 8669
    • Show only replies by motorollin
Re: Moving a sprite in a specified angle
« Reply #22 on: August 28, 2007, 05:34:12 PM »
Ok I changed my code to this:

        int xv=((3*rand())/RAND_MAX)+1;
        int yv=((3*rand())/RAND_MAX)+1;
        int r1=((1*rand())/RAND_MAX)+1;
        if ( r1 == 1 ) xv = -xv;
        int r2=((1*rand())/RAND_MAX)+1;
        if ( r2 == 1 ) yv = -yv;
        pinwheels.xVel=xv;
        pinwheels.yVel=yv;

The enemy still moves in the same direction each time the game is launched (though a different one to the one it went in before I changed the rand() lines)
Code: [Select]
10  IT\'S THE FINAL COUNTDOWN
20  FOR C = 1 TO 2
30     DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NAAAA
40     DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NA-NA-NAAAAA
50  NEXT C
60  NA-NA-NAAAA
70  NA-NA NA-NA-NA-NA-NAAAA NAAA-NAAAAAAAAAAA
80  GOTO 10
 

Offline Karlos

  • Sockologist
  • Global Moderator
  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 16867
  • Country: gb
  • Thanked: 4 times
    • Show only replies by Karlos
Re: Moving a sprite in a specified angle
« Reply #23 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
 

Offline motorollinTopic starter

  • Hero Member
  • *****
  • Join Date: Nov 2005
  • Posts: 8669
    • Show only replies by motorollin
Re: Moving a sprite in a specified angle
« Reply #24 on: August 28, 2007, 08:37:40 PM »
Well actually I do have "srand( time(NULL) );" at the top of my main function, before the rand() commands :-?

--
moto
Code: [Select]
10  IT\'S THE FINAL COUNTDOWN
20  FOR C = 1 TO 2
30     DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NAAAA
40     DA-NA-NAAAA-NAAAA DA-NA-NA-NA-NA-NA-NAAAAA
50  NEXT C
60  NA-NA-NAAAA
70  NA-NA NA-NA-NA-NA-NAAAA NAAA-NAAAAAAAAAAA
80  GOTO 10