Lengthdir function

Hi,
Maybe some of you are familiar with the lengthdir_x and lengthdir_y functions from Game Maker.
They just return a coordinate based on an angle and a distance you give these functions.
I am trying to write something like this for an arduboy game but it doesent give me the right coordinates maybe someone knows why.

int lengthdirX(int len, int dir) {
  dir = dir % 360;
  
  if (dir < 90) {
    return (cos(dir) * len);
  }
  if (dir > 90 and dir < 180) {
    return -(cos(dir) * len);
  }
  if (dir > 180 and dir < 270) {
    return -(cos(dir) * len);
  }
  if (dir > 270) {
    return (cos(dir) * len);
  }
  if (dir == 0 or dir == 360) {
    return len;
  }
  if (dir == 90 or dir == 270) {
    return 0;
  }
  if (dir == 180) {
    return - len;
  }
}

int lengthdirY(int len, int dir) {
  dir = dir % 360;

  if (dir < 90) {
    return -(sin(dir) * len);
  }
  if (dir > 90 and dir < 180) {
    return -(sin(dir) * len);
  }
  if (dir > 180 and dir < 270) {
    return (sin(dir) * len);
  }
  if (dir > 270) {
    return (sin(dir) * len);
  }
  if (dir == 0 or dir == 360 or dir == 180) {
    return 0;
  }
  if (dir == 90) {
    return - len;
  }
  if (dir == 270) {
    return len;
  }
}

Thanks.

In C/C++ sin and cos expect angles in radians, not degrees.
You’d need to convert the angle like this:
float angrad = dir/180.0*3.1415;
Floats on an 8-bit processor are really slow, though, so use sparingly (or not at all, if possible).

2 Likes

Gamemaker is a bit of an oddball as far as programming games goes, by which I mean it does a lot of things that would be considered odd by other languages.

Using degrees instead of radians is one of those things.

Degrees obviously go from 0 to 360 (with 360 being the same as 0).
Radians on the other hand go from 0 to 2*Pi (with 2*Pi being the same as 0)

As @FManga says, finding a point based on an angle is actually what sin and cos are for. (See the unit circle.)

The yoyogames documentation doesn’t actually state whether the result can be negative, but if it can then your function should be:

// radians version
float lengthDirX(float length, float angle)
{
  return cos(angle) * length;
}

// radians version
float lengthDirY(float length, float angle)
{
  return sin(angle) * length;
}

float degreesToRadians(float degrees)
{
  return degrees * (3.14159265359f / 180.0f);
}

float radiansToDegrees(float radians)
{
  return radians * (180.0f / 3.14159265359f);
}

// degrees version
float lengthDirXDegrees(float length, float angle)
{
  return cos(degreesToRadians(angle)) * length;
}

// degrees version
float lengthDirYDegrees(float length, float angle)
{
  return sin(degreesToRadians(angle)) * length;
}

Again, as @FManga said, floats are expensive, so use this sparingly and make sure to convert to integer types when possible.

If you’re used to Gamemaker you’re also used to being able to chew RAM and processing power freely.
On the Arduboy you have to be more conservative.

1 Like

thanks for your help it works now.

2 Likes