Page 1 of 2

Help, velocity and direction

Posted: Wed May 19, 2010 5:45 pm
by Avishaiozeri
Hi guys, i need some help. I'm starting to build some games for practice, and i wrote a simple battle ship game and some more simple stuff. And now i'm working on a two players pong game, and i have a problem. I want the ball to go to some random directions, so what i did is create him an x and y velocity variables, and set them to random numbers, and then, using an UpdateBall() function, to add the velocity to his x and y. now. it worked, the ball went in a random direction, but i cant control his speed! because what it really did is set is x and y to update in different speeds, and it created a random direction... can some one tell me how can i set the ball on a random direction and still control his speed? thanks

Re: Help, velocity and direction

Posted: Wed May 19, 2010 6:11 pm
by X Abstract X
I remember I had this exact same problem the first time I made pong haha. I think what you might want to do is, not set it randomly. Instead something like this:

Code: Select all

speed.x = 2;
speed.y = 2;

while (gameIsRunning) {
    if (collisionWithVerticalWall)
        speed.x *= -1;

    if (collisionWithHorizontalWall)
        speed.y *= -1;
}

If you truely do want a random direction:

Code: Select all

float ballSpeed = 5.0f;
float directionAngle = generateSomeRandomAngle();

float xSpeed = ballSpeed * cos(directionAngle)
float ySpeed = ballSpeed * sin(directionAngle)

Re: Help, velocity and direction

Posted: Wed May 19, 2010 6:16 pm
by Avishaiozeri
X Abstract X wrote:I remember I had this exact same problem the first time I made pong haha. I think what you might want to do is, not set it randomly. Instead something like this:

Code: Select all

speed.x = 2;
speed.y = 2;

while (gameIsRunning) {
    if (collisionWithVerticalWall)
        speed.x *= -1;

    if (collisionWithHorizontalWall)
        speed.y *= -1;
}
wouldn't it go just up or down or left to right? what will make it go in a different direction each time it hits one of the players or walls?

Re: Help, velocity and direction

Posted: Wed May 19, 2010 6:38 pm
by X Abstract X
There's nothing random about reflecting off the walls, you just multiply the relevant component by -1. The only randomness you could add is the initial velocity of the ball, when it first spawns in the center of your game board. When it hits a wall it's always going to reflect to form an angle of incidence equal to the angle of reflection assuming the wall is straight.

Re: Help, velocity and direction

Posted: Wed May 19, 2010 6:41 pm
by XianForce
The second thing he posted will solve that problem. Basically your making a random direction, via a random angle, and using cos and sin to get the respective x and y velocities.

But cos and sin can sometimes be a bit costly, but it will allow plenty of different directions. You can also do something like this:

Code: Select all

const int MAX_VEL = 8;

int xVel = ((rand() % MAX_VEL) + 1) * (rand() % 2) - 1);
int yVel = ((rand() % MAX_VEL) + 1) * (rand() % 2) - 1);
With this, a velocity between 1 and 8 will be generated, with the possibility of it becoming negative.

But I think you should probably use the cos/sin method =D!

Re: Help, velocity and direction

Posted: Wed May 19, 2010 6:45 pm
by X Abstract X
Here is how I would do it all.

Code: Select all

float ballSpeed = 5.0f;
float directionAngle = generateRandomAngle();

float xSpeed = ballSpeed * cos(directionAngle); //Don't forget to convert to radians if you're working in degrees
float ySpeed = ballSpeed * sin(directionAngle);

float ballX = 0.0f, ballY = 0.0f;

while (gameRunning) {
    if (collisionWithVerticalWall)
        xSpeed *= -1.0f;

    if (collisionWithHorizontalWall)
        ySpeed *= -1.0f;

    ballX += xSpeed;
    ballY += ySpeed;
}

Re: Help, velocity and direction

Posted: Wed May 19, 2010 7:00 pm
by Avishaiozeri
Thanks, i'll try that. and what do you mean 'costly' will it slow the game?

Re: Help, velocity and direction

Posted: Wed May 19, 2010 7:47 pm
by X Abstract X
Costly does mean slow but, it's nothing you have to worry about, at all. The trig functions are just really slow relative to other operations like addition, subtraction, etc.

Not that this is an accurate test at all, but I wrote a simple program just to get an idea of the speed of things.

Code: Select all

float x = 0.0f;

for (float i = 0.0f; i < 10000000.0f; i++)
    x = cos(i);
This only took around 1 second to execute.

Re: Help, velocity and direction

Posted: Wed May 19, 2010 7:48 pm
by X Abstract X
Opps, doubled.

Re: Help, velocity and direction

Posted: Thu May 20, 2010 7:08 am
by RyanPridgeon
I wrote these functions which will do what you wanted and explained the steps because I'm bored. Don't just copy and paste though, read through, make sure you understand, then try it yourself. It only requires a basic knowledge of simple trigonometry and pythag. Also I didn't try compiling it so there may be mistakes.

Code: Select all

float getSpeed() {
  return sqrt(xVel*xVel + yVel*yVel); // use pythag theorem to work out the speed
}

float getAngle() { // returns teh angle in radians not degrees
  return atan2(yVel, xVel); // use inverse tan to calculate the angle
}

void setSpeed(float speed) {

  float currentSpeed = sqrt(xVel*xVel + yVel*yVel); // pythagorous' theorem

  if (currentSpeed > 0.0f){ // if it's not moving, then just do nothing as we dont know which direction we want to go
    xVel *= speed / currentSpeed; // this will set xVel to the correct speed.
    yVel *= speed / currentSpeed; // this will set yVel to the correct speed.
  }
}

void setDirection(float angle) { // angle in radians, not degrees

  float currentSpeed = sqrt(xVel*xVel + yVel*yVel); // pythagorous' theorem

  xVel = currentSpeed * cos(angle); // use trig with radians, with 0 angle being along the positive X, and Pi / 2 being along the positive Y
  yVel = currentSpeed * sin(angle);

}

void setVelocityPolar(float angle, float speed) { // angle in radians
  xVel = speed * cos(angle); // use trig with radians, with 0 angle being along the positive X, and Pi / 2 being along the positive Y
  yVel = speed * sin(angle);
}
If I was coding your game, I would create a vector class and use vectors to store velocity, position etc. But I guess you don't want to do that, so the above will work fine.

Re: Help, velocity and direction

Posted: Thu May 20, 2010 7:36 am
by pritam
X Abstract X wrote:Costly does mean slow but, it's nothing you have to worry about, at all. The trig functions are just really slow relative to other operations like addition, subtraction, etc.

Not that this is an accurate test at all, but I wrote a simple program just to get an idea of the speed of things.

Code: Select all

float x = 0.0f;

for (float i = 0.0f; i < 10000000.0f; i++)
    x = cos(i);
This only took around 1 second to execute.
Dude you could totally have measured that accurately in milliseconds.

Re: Help, velocity and direction

Posted: Thu May 20, 2010 7:48 am
by Avishaiozeri
RyanPridgeon wrote:I wrote these functions which will do what you wanted and explained the steps because I'm bored. Don't just copy and paste though, read through, make sure you understand, then try it yourself. It only requires a basic knowledge of simple trigonometry and pythag. Also I didn't try compiling it so there may be mistakes.

Code: Select all

float getSpeed() {
  return sqrt(xVel*xVel + yVel*yVel); // use pythag theorem to work out the speed
}

float getAngle() { // returns teh angle in radians not degrees
  return atan2(yVel, xVel); // use inverse tan to calculate the angle
}

void setSpeed(float speed) {

  float currentSpeed = sqrt(xVel*xVel + yVel*yVel); // pythagorous' theorem

  if (currentSpeed > 0.0f){ // if it's not moving, then just do nothing as we dont know which direction we want to go
    xVel *= speed / currentSpeed; // this will set xVel to the correct speed.
    yVel *= speed / currentSpeed; // this will set yVel to the correct speed.
  }
}

void setDirection(float angle) { // angle in radians, not degrees

  float currentSpeed = sqrt(xVel*xVel + yVel*yVel); // pythagorous' theorem

  xVel = currentSpeed * cos(angle); // use trig with radians, with 0 angle being along the positive X, and Pi / 2 being along the positive Y
  yVel = currentSpeed * sin(angle);

}

void setVelocityPolar(float angle, float speed) { // angle in radians
  xVel = speed * cos(angle); // use trig with radians, with 0 angle being along the positive X, and Pi / 2 being along the positive Y
  yVel = speed * sin(angle);
}
If I was coding your game, I would create a vector class and use vectors to store velocity, position etc. But I guess you don't want to do that, so the above will work fine.
Wow, man thanks! I owe you!
Edit: I must admit, i'm learning this things in school this year, but i didn't exactly understood what you did... i guess because we started learning all the cos and sin, and angles not too long ago...
Another edit: Maybe i'll ask my dad, he is a math teacher...

Re: Help, velocity and direction

Posted: Thu May 20, 2010 7:54 am
by Bakkon
Avishaiozeri wrote:Thanks, i'll try that. and what do you mean 'costly' will it slow the game?
If you look up the definitions of sine and cosine, you see they are summations of a bunch of factorials and high exponentials. Extremely slower than basic addition and subtract, but on modern computers, you would notice anything unless you're calling these thousands of times per frame.

As for the topic, if you have a simple vector class, you can have your direction be a vector and then multiply it by your scalar speed.

Code: Select all

Vector2f direction(rand() % 9 - 4, rand() % 9 - 4);
direction.Normalize();
float speed = 10.0f;
position += direction * speed;

Re: Help, velocity and direction

Posted: Thu May 20, 2010 8:08 am
by RyanPridgeon
Bakkon wrote:
Avishaiozeri wrote:Thanks, i'll try that. and what do you mean 'costly' will it slow the game?
If you look up the definitions of sine and cosine, you see they are summations of a bunch of factorials and high exponentials. Extremely slower than basic addition and subtract, but on modern computers, you would notice anything unless you're calling these thousands of times per frame.

As for the topic, if you have a simple vector class, you can have your direction be a vector and then multiply it by your scalar speed.

Code: Select all

Vector2f direction(rand() % 9 - 4, rand() % 9 - 4);
direction.Normalize();
float speed = 10.0f;
position += direction * speed;
Yes, and if you really need to be using trigonometric functions alot then you would want to consider making a lookup table, which is essentially just a table of pre-calculate values. That would be as fast as accessing any other array :)

But again, OP; you probably don't need to care about this.

Also, although you've only just started learning about trigonometry in school, it's actaully quite simple to learn what I've used in those functions. Look it up on google, you'll want to learn how to calculate side lengths / angles in a triangle using cos, sin and tan. Then you just need to imagine the velocity as a triangle :)

Re: Help, velocity and direction

Posted: Thu May 20, 2010 8:10 am
by Avishaiozeri
I'm working on a pong game, because i'm a total noob... I'm good with math, but i'm learning all the stuff you're talking about this year, so i'm still not totally comfortable with some concepts...
Edit: Thanks, i'll check it in google
Another edit: sorry if i sound stupid... it's just that English isn't my language, i know some concepts in Hebrew, maybe i'll translate them....