Byungil Jeong
This second tutorial shows you how to implement a simple FSM as a DLL using Visual C++ and how to use it in DBPro. Since a DLL can hold data between each calls from DBPro, we can store the state information of our objects in a DLL and retrieve it whenever we want. This means that we can locate the AI part of our game in a DLL and control our objects in DBPro by just retrieving the state information from the DLL. For this tutorial, I made a FSM to control a moving sphere in DBPro according to key inputs. It is a simple example which shows you can implement game AI entirely as a DLL.
a. Open Visual C++ 6.0 and select NEW, choose Win32 Dynamic-Link Library, call your project FSM and click OK.
b. Select 'Create a SIMPLE DLL Project'.
c. In FileView, double click FSM files, then Source Files, then FSM.cpp.
d. Add the following below #include stdafx.h:
// indicating following function will be exported to other executables
#define MYCOMMAND __declspec ( dllexport )
// moving states
#define GO_UP 1
#define GO_DOWN 2
#define GO_LEFT 3
#define GO_RIGHT 4
// rotation states
#define CW 11 // clock-wise
#define CCW 12 // couter clock-wise
// key inputs
#define KEY_RIGHT 21
#define KEY_LEFT 22
e. Add the following below DllMain().
// state variables
int m_stat, r_stat, next_r_stat;
int count;
// initialize state variables
MYCOMMAND void init_states(void)
{
m_stat = GO_UP;
r_stat = next_r_stat = CW;
count = 0;
}
// change moving direction
void change_state()
{
switch(m_stat) {
case GO_UP :
if (r_stat == CW)
m_stat = GO_RIGHT;
else
m_stat = GO_LEFT;
break;
case GO_DOWN :
if (r_stat == CW)
m_stat = GO_LEFT;
else
m_stat = GO_RIGHT;
break;
case GO_LEFT :
if (r_stat == CW)
m_stat = GO_UP;
else
m_stat = GO_DOWN;
break;
case GO_RIGHT :
if (r_stat == CW)
m_stat = GO_DOWN;
else
m_stat = GO_UP;
break;
}
}
// find next direction of rotation
MYCOMMAND void change_rotation(int key)
{
switch(m_stat) {
case GO_UP :
if (key == KEY_RIGHT)
next_r_stat = CW;
else if (key == KEY_LEFT)
next_r_stat = CCW;
break;
case GO_DOWN :
if (key == KEY_RIGHT)
next_r_stat = CCW;
else if (key == KEY_LEFT)
next_r_stat = CW;
break;
case GO_LEFT :
if (key == KEY_RIGHT) {
if (r_stat == CW) // reverse rotation direction
next_r_stat = CCW;
else
next_r_stat = CW;
}
else if (key == KEY_LEFT) // keep rotation direction
next_r_stat = r_stat;
break;
case GO_RIGHT :
if (key == KEY_LEFT) {
if (r_stat == CW) // reverse rotation direction
next_r_stat = CCW;
else
next_r_stat = CW;
}
else if (key == KEY_RIGHT) // keep rotation direction
next_r_stat = r_stat;
break;
}
}
// retrieve state
MYCOMMAND int get_state(void)
{
count++;
// every 300 access change the moving direction of sphere
if (count == 300) {
r_stat = next_r_stat; // change of rotation direction
change_state(); // change of moving direction
count = 0;
}
return m_stat;
}
f. Change of moving state is simple. But, in case of rotation, direction can be reversed several times when we press left or right key, because DBPro can take it unexpected number of times even though we think that we just press it once. So I introduced an additional state variable, next_m_stat, and change rotation direction just before change of moving direction.
g. Press F7 to compile your DLL.
A DLL string table informs DBPro which commands the DLL has and which function is associated with each command.
a. Click INSERT from the Menu, then RESOURCE.
b. Select STRING TABLE to highlight it and then click NEW to create a new string table
c. Double click the highlighted box under ID and then click in the caption box where we will type out our command:
INIT FSM%0%?init_states@@YAXXZ
d. Type out the second and third command under first command in the same way
CHANGE ROTATION%L%?change_rotation@@YAXH@Z%int
GET STATE[%L%?get_state@@YAHXZ
e. Save this resource file in your project directory assigning file name as FSM.rc.
f. Now select the PROJECT menu and click ADD TO PROJECT and then FILES. Select FSM.rc and click OK. To make sure, click F7 to compile your DLL again. It will now contain a string table describing your first command.
a. You can find your DLL file(FSM.dll) in debug directory or release directory under your project directory according to your compile mode.
b. Copy your DLL file to plug-in user folder of DBPro. The default path to this folder is C:\Program Files\Dark Basic Software\Dark Basic Professional\Compiler\plugins-user.
c. Launch DBPro and type out the following:
REMSTART
## move states
GO_UP : 1
GO_DOWN : 2
GO_LEFT : 3
GO_RIGHT : 4
## key value
KEY_RIGHT : 21
KEY_LEFT : 22
REMEND
make object sphere 1, 10
position object 1, -15,-15,100
INIT FSM
do
IF RIGHTKEY() = 1 THEN CHANGE ROTATION 21
IF LEFTKEY() = 1 THEN CHANGE ROTATION 22
SELECT GET STATE()
CASE 1 : MOVE OBJECT UP 1, 0.1 : ENDCASE
CASE 2 : MOVE OBJECT DOWN 1, 0.1 : ENDCASE
CASE 3 : MOVE OBJECT LEFT 1, 0.1 : ENDCASE
CASE 4 : MOVE OBJECT RIGHT 1, 0.1 : ENDCASE
ENDSELECT
loop
sync
d. You can see the role of this DBPro code just takes key inputs and moves a sphere according to the state stored in DLL.
e. Press F5 to run the program and see a moving sphere. At first, it moves in the order of Up, RIGHT, DOWN, LEFT(clock wise). You can change the direction of rotation by pressing LEFT or RIGHT arrow key. Each key has different meaning according to moving direction of the sphere. When the sphere goes up, left key change the rotation direction to CCW, right key to CW. When the sphere goes down, the change is revesed ( left key : CW, right key : CCW). When the sphere goes left or right, pressing the key which has reverse direction to the moving direction reverses the rotation direction.