# Small Basic Game Programming – Game Math

Once I wrote a series of blog posts about game programming in Small Basic.  Today, I'd like to add one more post about game math.

In this article, I'll talk about following Math operations.

• Random Number
• Remainder
• Trigonometric Functions
• Math for Kinetics (Dynamics)
• Math for Collision

# Random Number

Random number is sometimes used to such as random action of enemy or AI (artificial intelligence).  A simple sample is in a blog post Small Basic Game Programming - Let's start with RPS game.  And you can learn more about random number in another post Small Basic - Random Numbers.

# Remainder

Remainder is a useful function for such as following case:

• to check a number is odd or even
• to convert large angle (>= 360 decree) to small (< 360)
• to do another operation once every N times
• to get column from a 2-D board that implemented as 1-D array

Following code is a sample of the last one in the list above.  This code is from my 2048 game (CLZ771-0).

`Sub ``Board_CellToIndex`
`  ``' param col, row - cell position`
`  ``' return i - index of board array`
`  ``i ``= ``(``row ``- ``1``) ``* ``4 ``+ ``col`
`EndSub`
`Sub ``Board_IndexToCell`
`  ``' param i - index of board array`
`  ``' return col, row - cell position`
`  ``col ``= ``Math``.``Remainder``(``i ``- ``1``, ``4``) ``+ ``1`
`  ``row ``= ``Math``.``Floor``(``(``i ``- ``1``) ``/ ``4``) ``+ ``1`
`EndSub`

# Trigonometric Functions

Trigonometric functions will be used in following situations:

• to rotate Shapes not from their centers (using sin and cos)
• to convert a polar coordinate to a rectangular coordinate (using sin and cos)
• to convert a rectangular coordinate to a polar coordinate (using arctan)

Following subroutine converts a rectangular (Cartesian) coordinate (x, y) to a polar coordinate (r, a).  This subroutine uses tan-1 (arctan) function.  For example, this subroutine is used in my game Dragon vs Turtle (HMP803-5) to get an angle for moving the Turtle from a mouse position.

`Sub ``Math_CartesianToPolar`
`  ``' Math | convert Cartesian coordinate to polar coordinate`
`  ``' param x, y - Cartesian coordinate`
`  ``' return r, a - polar coordinate (0<=a<360)`
`  ``r ``= ``Math``.``SquareRoot``(``x ``* ``x ``+ ``y ``* ``y``)`
`  ``If ``x ``= ``0 ``And ``y ``> ``0 ``Then`
`    ``a ``= ``90 ``' [degree]`
`  ``ElseIf ``x ``= ``0 ``And ``y ``< ``0 ``Then`
`    ``a ``= ``-``90`
`  ``Else`
`    ``a ``= ``Math``.``ArcTan``(``y ``/ ``x``) ``* ``180 ``/ ``Math``.``Pi`
`  ``EndIf`
`  ``If ``x ``< ``0 ``Then`
`    ``a ``= ``a ``+ ``180`
`  ``ElseIf ``x ``>``= ``0 ``And ``y ``< ``0 ``Then`
`    ``a ``= ``a ``+ ``360`
`  ``EndIf`
`EndSub`

# Math for Kinetics (Dynamics)

Motion of a point is calculated from it's acceleration (a [m/s2]), velocity (v [m/s]), displacement (d [m]) and time (t [s]).  Delta velocity is calculated from following equation. Delta displacement is calculated from following equation. Following graph shows Δd as a dark gray trapezoid.  And the slope of the graph shows acceleration.  This t-v graph is drawn by a program JLF545-1. My game Lunar Module (DTF312-2) uses this kind of calculation.

# Math for Collision

Today I'd like to introduce two easy way to calculate collision.  The first one is a circle and walls of the graphics window.  Following code is from a program LDH017.  And this code is checking the circle position with walls (x<=0, x>=the graphic window width, y<=0 and y>=the graphics window height).

`    ``' collision detect with walls`
`    ``If ``(``_x ``- ``_s``[``id``]``[``"w"``] ``/ ``2``) ``<``= ``0 ``Then`
`      ``_x ``= ``_x ``- ``2 ``* ``(``_x ``- ``_s``[``id``]``[``"w"``] ``/ ``2``)`
`      ``_s``[``_id``]``[``"vx"``] ``= ``-``_s``[``_id``]``[``"vx"``] ``* ``_s``[``_id``]``[``"r"``]`
`    ``ElseIf  ``gw ``<``= ``(``_x ``+ ``_s``[``id``]``[``"w"``] ``/ ``2``) ``Then`
`      ``_x ``= ``_x ``- ``2 ``* ``(``_x ``+ ``_s``[``id``]``[``"w"``] ``/ ``2 ``- ``gw``)`
`      ``_s``[``_id``]``[``"vx"``] ``= ``-``_s``[``_id``]``[``"vx"``] ``* ``_s``[``_id``]``[``"r"``]`
`    ``EndIf`
`    ``If ``(``_y ``- ``_s``[``id``]``[``"h"``] ``/ ``2``) ``<``= ``0 ``Then`
`      ``_y ``= ``_y ``- ``2 ``* ``(``_y ``- ``_s``[``id``]``[``"h"``] ``/ ``2``)`
`      ``_s``[``_id``]``[``"vy"``] ``= ``-``_s``[``_id``]``[``"vy"``] ``* ``_s``[``_id``]``[``"r"``]`
`    ``ElseIf  ``gh ``<``= ``(``_y ``+ ``_s``[``id``]``[``"h"``] ``/ ``2``) ``Then`
`      ``_y ``= ``_y ``- ``2 ``* ``(``_y ``+ ``_s``[``id``]``[``"h"``] ``/ ``2 ``- ``gh``)`
`      ``_s``[``_id``]``[``"vy"``] ``= ``-``_s``[``_id``]``[``"vy"``] ``* ``_s``[``_id``]``[``"r"``]`
`    ``EndIf`

The second one is between circles.  To detect collision between two circles, calculate the distance of two centers.  This method can be used when the shape is not circle.  Following games use this method.

Following code is from DONKEY KONG.  The d means the distance between Mario and a barrel.

`    ``nb ``= ``barrel``[``"num"``]`
`    ``For ``ib ``= ``1 ``To ``nb`
`      ``xb ``= ``barrel``[``ib``]``[``"x"``] ``+ ``16`
`      ``yb ``= ``barrel``[``ib``]``[``"y"``] ``+ ``16`
`      ``d ``= ``Math``.``SquareRoot``(``Math``.``Power``(``(``xb ``- ``xm``)``, ``2``) ``+ ``Math``.``Power``(``(``yb ``- ``ym``)``, ``2``)``)`
`      ``If ``d ``< ``20 ``Then`
`        ``mario``[``"hit"``] ``= ``"True"`
`        ``mario``[``"vx"``] ``= ``0`
`        ``ym ``= ``ym ``- ``24`
`        ``mario``[``"vr"``] ``= ``720`
`      ``EndIf`
`    ``EndFor`

# See Also

Comments (6)
1. Yan Grenier - MTFC says:

Great article. Thanks Nonki.

2. Ed Price - MSFT says:

This is a fantastic summary of the different types of Game Math!

3. Nonki Takahashi says:

Thanks, Yan and Ed.

4. Sean Liming says:

Nice summary. Like the tie in examples.

5. Nonki Takahashi says:

Thanks, Sean.

6. Nonki Takahashi says:

Following condition is needed for Small Basic 1.2 before Else in Math_CartesianToPolar subroutine.

ElseIf x = 0 Then ' this condition is needed for SB 1.2

a = 0

Comments are closed.

Skip to main content