Blog Post

Small Basic Blog
4 MIN READ

Small Basic Game Programming - Game Math

NonkiTakahashi's avatar
NonkiTakahashi
Iron Contributor
Feb 13, 2019
First published on MSDN on Jul 29, 2015

Authored by Nonki Takahashi


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/s 2 ]), 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


Published Feb 13, 2019
Version 1.0
No CommentsBe the first to comment