This information is all available elsewhere, but I thought it might be helpful to put as much of it together in one place as possible.

I am hoping other people will contribute to this article with their own suggestions of formulae to include (or corrections).



Contents

Floats & Integers
Odd & Even
Left/Right Substrings
Random Numbers/Positions
Lowest/Highest Values
Distances & Angles
Custom Movements
Circles
Built-In Movements
Rectangular Grids
RGB/System Colors
Units of Time



Floats & Integers

Much of the time MMF will automatically convert floats (values with a decimal point) to integers (whole numbers). To force MMF to use floats, you can enter a value with a .0 on the end.

eg.
4 / 3 * 2 = 2
4 / 3.0 * 2 = 2.66667


When retrieving values from objects, it is not possible to do this (you obviously can't say Alterable Value A.o). Instead, you can add 0.0 to the values.

eg. Value.A / (0.0 + Value.B)

Also, X- and Y-positions are always integers. When using custom movements, you should always store an object's X- and Y- positions in alterable values rather than setting them directly. This will make the movement much smoother, as alterable values can store floats and not just integers. The same applies to angles.

Occasionally, you may want integers instead of floats. For this, you can use MMFs built-in conversion function Int().



Differentiate Between Odd & Even

if N mod 2 = 0 , N is Even
if N mod 2 = 1 , N is Odd



Retrieve Left/Right Portion of a String

Left$(String, #characters)
Right$(String, #characters)

eg. Typewriter Text
Text.displayed = Left$(Text.full, Value)
Value = Value + 1



Generate Random Number in Range A-B

Value = Random(B - A) + A



Generate Random Position

Anywhere within the frame;
New.x = Random(Frame.width)
New.y = Random(Frame.height)

Within a given radius of position X,Y;
Angle = Random(360)
Distance = Random(Radius)
New.x = Position.x + (Cos(Angle) * Distance)
New.y = Position.y - (Sin(Angle) * Distance)

Within a zone;
New.x = Left.x + (Random(Right.x - Left.x))
New.y = Top.y + (Random(Bottom.y - Top.y))



Find Lowest/Highest of A & B

Lowest = Min(A, B)
Highest = Max(A, B)


eg. Car Speed
Car.speed = Min(Max(Car.speed + Car.acceleration, Car.reverse_max), Car.forward_max)



Distance Between Two Points

Straight-line (Euclidean) Distance using Pythagoras' theorum;

Distance = sqr(((A.x - B.x) pow 2) + ((A.y - B.y) pow 2))

Image

Straight-line Distance (deviates from the true Euclidean distance by less than 3%, but faster because it does not use the Sqr function);

Distance = ((Max(Abs((A.x - B.x)), Abs((A.y - B.y)))) * 0.941246) + ((Min(Abs((A.x - B.x) ), Abs((A.y - B.y)))) * 0.41)


Manhattan Distance (4-directions);

Distance = Abs(A.x - B.x) + Abs(A.y - B.y)

Image

Chebyshev Distance (8-directions, inclucing diagonals);

Distance = Distance = Max(Abs(A.x - B.x), Abs(A.y - B.y))

Image



Angle Between Two Points

As of MMF2: Build 248, the ATan2 function may be used to calculate the angle between points.

Angle = ATan2(A.y - B.y, B.x - A.x)


Only use this next formula if you are using MMF1.5 or older.

Angle = Abs(360*Min(Max(A.y - B.y)+1, 0), 1)-(ASin((B.x - A.x)/Sqr(A.x - B.x) pow 2 + (A.y - B.y) pow 2))+270))

Or, for a version that you can copy and paste straight into MMF (just change Point A and Point B);

Angle = Abs(360*Min(Max(Y( Point A )-Y( Point B )+1, 0), 1)-(ASin((X( Point B )-X( Point A ))/Sqr((X( Point A )-X( Point B )) pow 2+((Y( Point A ))-Y( Point B )) pow 2))+270))



Difference Between Two Angles

Returns the difference between two angles, in the range -180 to +180. When rotating an object towards a direction, the sign of this value tells you whether to rotate clockwise or anticlockwise.

Abs((( Angle1 - Angle2 +540) mod 360)-180)



Custom Movements

New.x = Old.x + (Cos(Angle) * Speed)
New.y = Old.y - (Sin(Angle) * Speed)

Image

eg. Car Movement
Car.x = Car.x + (Cos(Car.angle) * Car.speed)
Car.y = Car.y - (Sin(Car.angle) * Car.speed)

eg. Asteroids Movement
Velocity.x = Velocity.x + (Cos(Ship.angle) * Ship.acceleration)
Velocity.y = Velocity.y - (Sin(Ship.angle) * Ship.acceleration)
Ship.x = Ship.x + Velocity.x
Ship.y = Ship.y + Velocity.y



Area/Circumference of a Circle

The value produced by the Pi function in MMF is 3.141592654. This is more than accurate enough for any game.

Area = (Radius * Radius)* Pi

Circumference = 2 * Pi * Radius

eg. Moon orbiting a Planet
Angle = Angle + (360 / (2 * Pi * Distance / Speed))
Moon.x = Planet.x + (Cos(Angle) * Distance)
Moon.y = Planet.y - (Sin(Angle) * Distance)



Built-In Movements

Speed;
Pixels per Second = (Speed * 6.25) * (Framerate / 50)
Pixels per Frame = Speed / 8

Direction;
Angle = Direction * 11.25



Snap to Rectangular Grid Coordinates

New.x = Old.x / Cell.width * Cell.width
New.y = Old.y / Cell.height * Cell.height



Conversion Between Rectangular Grid & Screen Coordinates

Screen.x = Grid.x * Cell.width
Screen.y = Grid.y * Cell.height

Grid.x = Screen.x / Cell.width
Grid.y = Screen.y / Cell.height



Conversion Between RGB and System Color Index

System Color Index = Red + (Green * 256) + (Blue * 65536)

Red = abs(((System.index mod 65536) mod 256))
Green = abs((System.index mod 65536) / 256)
Blue = abs(System.index / 65536)



Time

Days = int(Seconds) / 34560
Hours = int(((Seconds) mod 86400) / 1440) mod 24
Minutes = int((Seconds) mod 1440) / 60
Seconds = int(((Seconds) mod 86400) mod 3600) mod 60

The int() is there incase you want to use fractions of seconds (ie. if Seconds is a float).

To create a single string in the format HH:MM.SS (Day D), you can use;

Right$(00+Str$(((Int(value( Seconds )) mod 86400)/1440) mod 24),2)+:+Right$(00+Str$((Int(value( Seconds )) mod 1440)/60), 2)+.+Right$(00+Str$(((Int(value( Seconds )) mod 86400) mod 3600) mod 60), 2)+ (Day +Str$(Int((value( Seconds ))/34560)+1)+)



Suggestions?