Welcome, Guest. Please login or register.

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

Description:

0 Members and 1 Guest are viewing this topic.

Offline motorollinTopic starter

  • Hero Member
  • *****
  • Join Date: Nov 2005
  • Posts: 8669
    • Show all replies
Moving a sprite in a specified angle
« on: August 27, 2007, 08:03:16 PM »
In C++/SDL, how can I tell a sprite to move in a specific angle, in degrees? Currently I only know how to move it a certain number of pixels on the x or y axis, which doesn't really help when I want to move it at an angle of, say, 30 degrees.

Note this is moving in a straight line at that angle, not rotating the sprite.

--
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 motorollinTopic starter

  • Hero Member
  • *****
  • Join Date: Nov 2005
  • Posts: 8669
    • Show all replies
Re: Moving a sprite in a specified angle
« Reply #1 on: August 27, 2007, 09:14:00 PM »
Thanks Karlos! Here's what I've knocked together in the move() function:

if ( x <= 20 ) if ( xVel < 0 ) xVel = -xVel;
if ( y <= 20 ) if ( yVel < 0 ) yVel = -yVel;
       
if ( x >= 620 ) if ( xVel > 0 ) xVel = -xVel;
if ( y >= 440 ) if ( yVel > 0 ) yVel = -yVel;

x+=xVel*cos(angle);
y+=yVel*sin(angle);



This does work, and makes the sprite move in the angle specified by int angle, and bounce off the edges of the screen if it reaches the edge of the playfield. However, if I have lots of the same sprite (a vector of the same class) lots of the sprites seem to go off the edge of the screen instead of bouncing back in to the playfield :-?
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 motorollinTopic starter

  • Hero Member
  • *****
  • Join Date: Nov 2005
  • Posts: 8669
    • Show all replies
Re: Moving a sprite in a specified angle
« Reply #2 on: August 27, 2007, 09:50:13 PM »
No threads. It just runs through the vector of sprites and moves/checks/recalculates/shows them one at a time. I'm wondering if my variables are declared as public when they should be private, or vice versa? I'm not sure I fully understand the difference, but if a variable were public might that mean the velocity for all of the sprites was being adjusted the same instead of them each having their own velocity?

--
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 motorollinTopic starter

  • Hero Member
  • *****
  • Join Date: Nov 2005
  • Posts: 8669
    • Show all replies
Re: Moving a sprite in a specified angle
« Reply #3 on: August 27, 2007, 10:06:40 PM »
Looks like I had some of the < and > signs the wrong way round. Also I expanded the nested if statements out, and it seems to be working now.

    if ( x <= 20 )
    {
         if ( xVel > 0 )
         {
              xVel = -xVel;
         }
    }
    if ( y <= 20 )
    {
         if ( yVel < 0 )
         {
              yVel = -yVel;
         }
    }
    if ( x >= 620 )
    {
         if ( xVel < 0 )
         {
              xVel = -xVel;
         }
    }
    if ( y >= 440 )
    {
         if ( yVel > 0 )
         {
              yVel = -yVel;
         }
    }

    x+=xVel*cos(angle);
    y+=yVel*sin(angle);



Not sure how this is different to your last example Karlos, but at least it works now :-D

Cheers!

--
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 motorollinTopic starter

  • Hero Member
  • *****
  • Join Date: Nov 2005
  • Posts: 8669
    • Show all replies
Re: Moving a sprite in a specified angle
« Reply #4 on: August 27, 2007, 10:10:51 PM »
Hmmm, I borked it again :lol: I found out what is causing it, but I don't know why.

When the enemy is created its initial angle is set. If I set this to, e.g., 40 degrees, then the enemies all stay within the playfield. If I set it to rand() % 350 + 10 (should be an angle betwen 10 and 350 degrees) then they start flying off the screen :-?

--
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 motorollinTopic starter

  • Hero Member
  • *****
  • Join Date: Nov 2005
  • Posts: 8669
    • Show all replies
Re: Moving a sprite in a specified angle
« Reply #5 on: August 27, 2007, 10:22:08 PM »
OIC. xVel and yVel are initialised with enemyspeed, which is in turn initialised at the top of my code, just to make it easy to tweak sprite speeds and have the changes cascade through the code. xVel and yVel end up (currently) with a value of 3.

--
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 motorollinTopic starter

  • Hero Member
  • *****
  • Join Date: Nov 2005
  • Posts: 8669
    • Show all replies
Re: Moving a sprite in a specified angle
« Reply #6 on: August 27, 2007, 10:42:06 PM »
The reason for having two separate velocity variables (xVel and yVel) is for the edge rebound code. If the sprite hits the top or bottom then yVel is made negative, and if it hits the left or right then xVel is made negative.

If I only use one variable for the velocity then I can't do this, since changing the velocity variable would affect the direction on both the X and Y axes.

--
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 motorollinTopic starter

  • Hero Member
  • *****
  • Join Date: Nov 2005
  • Posts: 8669
    • Show all replies
Re: Moving a sprite in a specified angle
« Reply #7 on: August 27, 2007, 11:01:58 PM »
The problem there is that sometimes the sprite crosses a couple of pixels over the edge of the playfield boundary. This is not a problem aesthetically, but it does mean that it keeps having its angle reversed over and over again so gets stuck. At least if I check whether the velocity is going to take the sprite further out of the playfield before changing it then I can stop this from happening.

--
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 motorollinTopic starter

  • Hero Member
  • *****
  • Join Date: Nov 2005
  • Posts: 8669
    • Show all replies
Re: Moving a sprite in a specified angle
« Reply #8 on: 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 motorollinTopic starter

  • Hero Member
  • *****
  • Join Date: Nov 2005
  • Posts: 8669
    • Show all replies
Re: Moving a sprite in a specified angle
« Reply #9 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 motorollinTopic starter

  • Hero Member
  • *****
  • Join Date: Nov 2005
  • Posts: 8669
    • Show all replies
Re: Moving a sprite in a specified angle
« Reply #10 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 motorollinTopic starter

  • Hero Member
  • *****
  • Join Date: Nov 2005
  • Posts: 8669
    • Show all replies
Re: Moving a sprite in a specified angle
« Reply #11 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 motorollinTopic starter

  • Hero Member
  • *****
  • Join Date: Nov 2005
  • Posts: 8669
    • Show all replies
Re: Moving a sprite in a specified angle
« Reply #12 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