1. Identify to a formation center object.
May be a hero, or it can be a hidden object. The gridcenter of the following species
2. Pre-calculated number The vector of each formation "slot" relative to the center object.
void Gamecontrolmanager::startgridmode ()
{
if (M_mainscene->herolist.empty ())
Return
M_isstartgridmode = true;
Point gridcenter = Findgridcenter ();
if (Membernumber = = 1)
Return
else if (Membernumber = = 2)
{
0
1
Originrelativevec[0] = VEC2 (0,grid_slot_radius);
ORIGINRELATIVEVEC[1] = VEC2 (0,-grid_slot_radius);
}
else if (Membernumber = = 3)
{
Point Firstpos = Gridcenter + Vec2 (0,grid_slot_radius);
Point secondpos = Firstpos.rotatebyangle (Gridcenter, Cc_degrees_to_radians (-120));
Point thirdpos = Secondpos.rotatebyangle (Gridcenter, Cc_degrees_to_radians (-120));
0
//
1 2
Originrelativevec[0] = Firstpos-gridcenter;
ORIGINRELATIVEVEC[1] = Secondpos-gridcenter;
ORIGINRELATIVEVEC[2] = Thirdpos-gridcenter;
}
else if (Membernumber = = 4)
{
Point Firstpos = Gridcenter + Vec2 (0,grid_slot_radius);
Point secondpos = Firstpos.rotatebyangle (Gridcenter, Cc_degrees_to_radians (-90));
Point thirdpos = Secondpos.rotatebyangle (Gridcenter, Cc_degrees_to_radians (-90));
Point fourthpos = Thirdpos.rotatebyangle (Gridcenter, Cc_degrees_to_radians (-90));
0 soldiers
1 2 Hunter Mage
3 Priest
Originrelativevec[0] = Firstpos-gridcenter;
ORIGINRELATIVEVEC[1] = Fourthpos-gridcenter;
ORIGINRELATIVEVEC[2] = Secondpos-gridcenter;
ORIGINRELATIVEVEC[3] = Thirdpos-gridcenter;
}
Claim Slot Location
int slotindex = 0;
int minspeed = 999;
for (auto hero:m_mainscene->herolist)//already sorted
{
if (!hero->getisally () &&!hero->getisdead ())
{
Hero->setslotindex (Slotindex);
Slotindex + +;
Auto Actorinfo = Gamedata::getactorinfofrommap (Hero->getunitid ());
if (Actorinfo->speed < minspeed)
Minspeed = actorinfo->speed;
}
}
3. Determine the initial orientation of the formation based on the direction of a hero's relative center object
Point firstmanpos = M_mainscene->herolist.front ()->getcenterpoint ();
Crossover_point (Firstmanpos, Gridcenter,)
VEC2 Herovec = Firstmanpos-gridcenter;
Herovec.normalize ();
M_gridangle = Getdirectionbychief (Herovec);
for (int index = 0; index < membernumber; index++)
{
VEC2 cur = originrelativevec[index];
Point curpoint = cur + gridcenter;
Curpoint = Curpoint.rotatebyangle (Gridcenter, M_gridangle);
cur = curpoint-gridcenter;
Slotrelativevec[index] = cur;
}
4. All Heroes in position
for (auto hero:m_mainscene->herolist)
{
if (!hero->getisally () &&!hero->getisdead ())
{
VEC2 Curvec = Slotrelativevec[hero->getslotindex ()];
Point des = Gridcenter + Curvec;
Hero->setdestinationpoint (DES);
}
}
....
}
5. When the formation moves, update the formation orientation angle according to the "center object" relative to the destination location Targetpos Gridangle
Then refresh the relative vectors of each slot according to Gridangle cur
void Gamecontrolmanager::setgriddirection (Point targetpos)
{
Update formation orientation
Auto Gridcenter = Getgridcenter ();
VEC2 Chiefvec = Targetpos-gridcenter;
Chiefvec.normalize ();
M_gridangle = Getdirectionbychief (Chiefvec);
for (int index = 0; index < membernumber; index++)
{
VEC2 cur = originrelativevec[index];
Point curpoint = cur + m_gridobject->getposition ();
Curpoint = Curpoint.rotatebyangle (M_gridobject->getposition (), m_gridangle); Rotate on the original basis
cur = curpoint-m_gridobject->getposition ();
Slotrelativevec[index] = cur;
}
M_gridobject->setrotation (Cc_radians_to_degrees (-m_gridangle));
}
6. Each frame lets the character move to its corresponding slot
void Gamecontrolmanager::updategriddirection ()
{
Point slot = Getslotposbyindex (Hero->getslotindex ());
if (Hero->getcenterpoint (). Distance (slot) > Getelasticrange ())
{
Hero->movetoward (slot);
}
}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
COCOS2DX-based RPG simple and practical algorithm 3-multi-character follow formation movement